Skip to content

SCIM Cross domain Identity Management

System for Cross-domain Identity Management (SCIM) is an open standard that enables the automatic provisioning, management, and deprovisioning of users and groups across different systems. SCIM is particularly useful in environments where applications need to manage large volumes of user identities, such as in cloud-based services or SaaS applications. By using SCIM, organizations can automate user account management, improving consistency, security, and reducing manual work.

SCIM uses RESTful APIs and JSON to represent user identities and allows applications to manage resources such as users, groups, and their attributes.

Specifications and Technical Overview

Key Concepts of SCIM

  • User: The primary resource in SCIM, representing an individual with attributes such as userName, email, phoneNumber, etc.
  • Group: A collection of users, often representing roles, departments, or access groups within a system.
  • Provisioning: The process of creating, updating, or deleting user accounts on the target system using SCIM APIs.
  • Identity Provider (IdP): The system responsible for managing users and providing their identity information, such as Okta, Azure AD, or any SCIM-compliant IdP.
  • Service Provider: The system or application that consumes the SCIM data and provisions users, such as a SaaS platform or cloud service.

SCIM Workflow

  1. Provisioning Request: The identity provider sends a request to the service provider to create, update, or delete user accounts or groups.
  2. User Synchronization: The service provider processes the request and updates its internal system to reflect the changes (e.g., adding new users, updating attributes, or removing users).
  3. Group Management: SCIM also supports managing groups of users, enabling the assignment of users to roles or teams.

SCIM API Endpoints

  • GET /Users: Fetches a list of users.
  • POST /Users: Creates a new user.
  • PUT /Users/{id}: Updates an existing user.
  • PATCH /Users/{id}: Modifies a subset of a user’s attributes.
  • DELETE /Users/{id}: Deletes a user.
  • GET /Groups: Fetches a list of groups.
  • POST /Groups: Creates a new group.
  • PUT /Groups/{id}: Updates an existing group.
  • DELETE /Groups/{id}: Deletes a group.

Python Ecosystem for SCIM

Python provides several libraries and frameworks that allow you to implement SCIM-compliant services. While SCIM-specific libraries are less common compared to OAuth or OIDC libraries, SCIM can be implemented using generic libraries like Flask, FastAPI, or Django combined with tools like requests for HTTP requests. You can also build custom SCIM clients and servers using Python’s robust ecosystem.

Example SCIM Client in Python

Here’s an example of how to interact with a SCIM API using Python and the requests library.

Prerequisites

  1. Install the requests library:
    bash pip install requests

  2. Use an SCIM-compliant identity provider or service provider (e.g., Okta, Azure AD, or a custom SCIM server).

Example: SCIM Client in Python

import requests
import json

SCIM_BASE_URL = "https://your-scim-provider.com/scim/v2"
SCIM_API_TOKEN = "your-api-token"

HEADERS = {
    "Authorization": f"Bearer {SCIM_API_TOKEN}",
    "Content-Type": "application/scim+json"
}

# Fetch a list of users
def get_users():
    url = f"{SCIM_BASE_URL}/Users"
    response = requests.get(url, headers=HEADERS)
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"Error fetching users: {response.status_code}, {response.text}")

# Create a new user
def create_user(user_data):
    url = f"{SCIM_BASE_URL}/Users"
    response = requests.post(url, headers=HEADERS, data=json.dumps(user_data))
    if response.status_code == 201:
        return response.json()
    else:
        raise Exception(f"Error creating user: {response.status_code}, {response.text}")

# Update an existing user
def update_user(user_id, user_data):
    url = f"{SCIM_BASE_URL}/Users/{user_id}"
    response = requests.put(url, headers=HEADERS, data=json.dumps(user_data))
    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"Error updating user: {response.status_code}, {response.text}")

# Delete a user
def delete_user(user_id):
    url = f"{SCIM_BASE_URL}/Users/{user_id}"
    response = requests.delete(url, headers=HEADERS)
    if response.status_code == 204:
        print("User deleted successfully")
    else:
        raise Exception(f"Error deleting user: {response.status_code}, {response.text}")

# Example usage
if __name__ == "__main__":
    # Fetch all users
    users = get_users()
    print(users)

    # Create a new user
    new_user = {
        "userName": "jdoe",
        "name": {
            "givenName": "John",
            "familyName": "Doe"
        },
        "emails": [
            {"value": "jdoe@example.com", "primary": True}
        ]
    }
    created_user = create_user(new_user)
    print(created_user)

    # Update a user
    updated_data = {
        "name": {
            "givenName": "Johnathan"
        }
    }
    updated_user = update_user(created_user['id'], updated_data)
    print(updated_user)

    # Delete the user
    delete_user(created_user['id'])

Flask Example: Building a SCIM Server

In this example, we create a simple SCIM server using Flask to handle basic SCIM operations like creating and retrieving users.

Prerequisites

  1. Install Flask:
    bash pip install Flask

Flask SCIM Server Example

from flask import Flask, request, jsonify

app = Flask(__name__)

# In-memory data store (not suitable for production)
users = {}

# SCIM endpoint to create a new user
@app.route('/scim/v2/Users', methods=['POST'])
def create_user():
    user_data = request.json
    user_id = len(users) + 1
    user_data['id'] = user_id
    users[user_id] = user_data
    return jsonify(user_data), 201

# SCIM endpoint to fetch all users
@app.route('/scim/v2/Users', methods=['GET'])
def list_users():
    return jsonify(list(users.values())), 200

# SCIM endpoint to retrieve a user by ID
@app.route('/scim/v2/Users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = users.get(user_id)
    if user:
        return jsonify(user), 200
    return jsonify({'error': 'User not found'}), 404

# SCIM endpoint to update a user by ID
@app.route('/scim/v2/Users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
    user = users.get(user_id)
    if user:
        users[user_id].update(request.json)
        return jsonify(users[user_id]), 200
    return jsonify({'error': 'User not found'}), 404

# SCIM endpoint to delete a user by ID
@app.route('/scim/v2/Users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    if user_id in users:
        del users[user_id]
        return '', 204
    return jsonify({'error': 'User not found'}), 404

if __name__ == '__main__':
    app.run(debug=True)

Use Cases for SCIM in Python

  1. User Provisioning in SaaS: SCIM is widely used to automate user provisioning and management across SaaS platforms. For example, when a user is created in an organization’s identity provider, SCIM can automatically provision that user across all associated applications (e.g., Google Workspace, Salesforce, etc.).

  2. User Deprovisioning: SCIM also handles deprovisioning (i.e., removing access or deleting users when they leave an organization), which is essential for maintaining security and access control.

  3. Role and Group Management: SCIM can manage roles and groups of users, assigning different permissions or access levels based on group membership.

Best Practices and Considerations

  • Secure API Access: SCIM APIs should be protected with strong authentication mechanisms like OAuth 2.0 to prevent unauthorized access.
  • Data Validation: Ensure proper validation of user data, such as email formats and required attributes, before creating or updating users.
  • Error Handling: SCIM defines a clear set of error response codes (e.g., 404 for not found, 400 for bad request). Ensure your SCIM server or client handles errors according to the SCIM specification.
  • Pagination and Filtering: SCIM supports pagination and filtering for retrieving large lists of users or groups. Implementing these features improves scalability.

References

Page last modified: 2024-09-25 08:35:47