Internet-Draft | SCIM RoleAssignment | September 2025 |
Poreddy | Expires 6 March 2026 | [Page] |
SCIM 2.0 defines "roles" and "entitlements" attributes on the User resource, but it lacks a standardized way to bind roles to specific scopes such as projects, tenants, or groups. This gap forces organizations to rely on group sprawl or non-standard encodings, preventing true interoperability. This document introduces a new SCIM resource type, RoleAssignment, which models scoped role bindings as first-class records, enabling portable provisioning, lifecycle governance, and compliance visibility.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 5 March 2026.¶
Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The SCIM protocol [RFC7643] [RFC7644] defines the User and Group resources and allows global roles to be attached to Users via the "roles" attribute. However, the specification does not provide a standardized way to associate roles with specific scopes such as projects, tenants, or device groups.¶
This limitation prevents SCIM from modeling the most common real-world requirement: assigning different roles to the same identity in different contexts.¶
For example, consider a user named Alice:¶
User: Alice +-- Global Role: Power User +-- Project A: Maintainer +-- Project B: Developer +-- Project C: ReadOnly¶
Today, there is no interoperable SCIM method to represent Alice's per-project role bindings. Current workarounds include creating Groups for every {scope x role} combination, which leads to group sprawl and poor interoperability, or embedding scope names into free-form role strings, which are not machine-readable or portable.¶
These limitations are visible in real-world SCIM implementations: GitLab [GITLAB-SCIM] , Tanium [TANIUM-RBAC] , and scenarios in Microsoft Entra ID [AZURE-SCIM] .¶
This document introduces a new SCIM 2.0 resource, RoleAssignment, which makes scoped role bindings a first-class concept. Each RoleAssignment explicitly links a subject (for example, User), a scope (for example, Project), and a role (for example, Developer). Optional metadata such as validity periods, source system, and approver information enable lifecycle management and governance.¶
By standardizing RoleAssignments:¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The RoleAssignment resource complements existing SCIM resources. Whereas the User.roles attribute provides only coarse global roles, RoleAssignment expresses who (subject) has what role in which scope. This allows interoperable provisioning of scoped role bindings.¶
{ "name": "RoleAssignment", "endpoint": "/RoleAssignments", "schema": "urn:ietf:params:scim:schemas:core:2.0:RoleAssignment", "schemaExtensions": [] }¶
The RoleAssignment resource defines the following top-level attributes.¶
Attribute | Type | Req | Multi | Mutability | Description |
---|---|---|---|---|---|
id | string | yes | no | readOnly | Provider-assigned unique identifier. |
externalId | string | no | no | readWrite | Client-supplied correlation id. |
subject | complex | yes | no | readWrite | The subject receiving the role. |
scope | complex | yes | no | readWrite | The scope where the role applies. |
role | complex | yes | no | readWrite | The role granted within the scope. |
priority | integer | no | no | readWrite | Conflict resolution (higher wins). Default 0. |
grant | complex | no | no | readWrite | Assignment metadata (source, reason, approver). |
validity | complex | no | no | readWrite | Validity window in UTC. |
status | string | no | no | readOnly | Computed lifecycle status. |
Priority usage guidance: When multiple active assignments exist for the same subject and scope, the assignment with the highest priority takes precedence. If priorities are equal, implementation-defined resolution rules apply.¶
Attribute | Type | Req | Multi | Mutability | Description |
---|---|---|---|---|---|
value | string | yes | no | readWrite | Identifier of the subject. |
$ref | reference | no | no | readWrite | URI to the subject resource, when available. |
type | string | no | no | readWrite | Subject type. Standard: "User", "Group". "ServiceAccount" MAY be used. Vendor-specific types SHOULD use prefixes. |
Attribute | Type | Req | Multi | Mutability | Description |
---|---|---|---|---|---|
type | string | yes | no | readWrite | Scope type. Common: "project", "tenant", "organization", "application", "environment". |
value | string | yes | no | readWrite | Provider-meaningful identifier of the scope. |
$ref | reference | no | no | readWrite | URI to the scope resource, if available. Optional when scope is opaque. |
Attribute | Type | Req | Multi | Mutability | Description |
---|---|---|---|---|---|
name | string | yes | no | readWrite | Display name of the role. |
value | string | no | no | readWrite | Stable identifier for the role. |
$ref | reference | no | no | readWrite | URI to a role catalog entry, if available. Providers with catalogs SHOULD include $ref for discovery. |
Role Discovery Guidance: Since role.$ref is optional, servers SHOULD support filtering on role and scope to enable discovery, for example:¶
GET /RoleAssignments?attributes=role,scope&filter=scope.type eq "project"¶
Providers that expose a role catalog MAY align discovery with the SCIM Roles and Entitlements approach [SCIM-ROLES-ENTITLEMENTS] .¶
Attribute | Type | Req | Multi | Mutability | Description |
---|---|---|---|---|---|
source | string | no | no | readWrite | Originating system or process. |
reason | string | no | no | readWrite | Human-readable justification. |
approver | string | no | no | readWrite | Approver identifier or reference. |
Attribute | Type | Req | Multi | Mutability | Description |
---|---|---|---|---|---|
validFrom | dateTime | no | no | readWrite | Start of validity window (UTC). |
validTo | dateTime | no | no | readWrite | End of validity window (UTC). |
The "status" attribute is readOnly and computed using the following rules:¶
If the referenced subject is inactive: status = "suspended".¶
If current time < validity.validFrom: status = "pending".¶
If current time > validity.validTo: status = "expired".¶
Otherwise: status = "active".¶
Special cases:¶
If validity.validFrom is null, assignment is immediately eligible.¶
If validity.validTo is null, assignment does not expire.¶
If explicitly revoked via DELETE or PATCH: status = "revoked".¶
Required status values:¶
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:RoleAssignment"], "id": "assignment-12345", "externalId": "ext-assign-001", "subject": { "value": "alice@company.com", "$ref": "https://example.com/scim/v2/Users/alice", "type": "User" }, "scope": { "type": "project", "value": "web-app-proj", "$ref": null }, "role": { "name": "Developer", "value": "developer", "$ref": null }, "priority": 100, "grant": { "source": "HR-System", "reason": "New team member onboarding", "approver": "manager@company.com" }, "validity": { "validFrom": "2025-09-01T00:00:00Z", "validTo": "2026-09-01T00:00:00Z" }, "status": "active" }¶
Create (POST): Servers MUST validate subject, scope, and role.¶
Replace (PUT): Missing required attributes cause 400 Bad Request.¶
Patch (PATCH): MUST be supported; invalid states SHOULD be rejected.¶
Delete (DELETE): Removes assignment and SHOULD revoke permissions.¶
Filter (GET): MUST support filters on subject, scope, role.¶
Pagination/Sorting: MUST support startIndex and count; SHOULD support sorting.¶
Bulk: MAY be supported. Clients SHOULD use externalId for idempotency.¶
- User's assignments: GET /RoleAssignments?filter=subject.value eq "alice@company.com" - Scope permissions: GET /RoleAssignments?filter=scope.value eq "project-x" - Role discovery within a scope type: GET /RoleAssignments?attributes=role&filter=scope.type eq "project" - Expiring access before a date/time: GET /RoleAssignments?filter=validity.validTo le "2025-12-31T23:59:59Z"¶
400 Invalid Value for malformed attributes or invalid validity windows.¶
404 Not Found for unknown subject, scope, or role references.¶
409 Conflict for duplicate active assignments.¶
412 Precondition Failed for ETag mismatches on conditional updates.¶
Error responses SHOULD include "detail" and "scimType" per [RFC7644] .¶
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "400", "scimType": "invalidValue", "detail": "validity.validFrom must be before validity.validTo" }¶
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "409", "scimType": "uniqueness", "detail": "Active assignment exists for subject 'alice@company.com' with role 'admin' in scope 'project-x'" }¶
Providers MAY continue to expose global roles via User.roles and coarse-grained membership via Groups. Providers SHOULD offer mapping guidance between legacy models and RoleAssignments. Dual-writing (maintaining both representations) is RECOMMENDED during migration.¶
RoleAssignments may expose organizational structures and access patterns. Sensitive metadata SHOULD follow least-privilege disclosure.¶
This specification requests registration of the following SCIM schema:¶
URN: urn:ietf:params:scim:schemas:core:2.0:RoleAssignment Specification: this document Contact: IETF SCIM Working Group Change Controller: IESG Experimental namespace MAY also be used: URN: urn:ietf:params:scim:schemas:extension:role:1.0:RoleAssignment¶
URNs are assigned and interpreted in accordance with [RFC8141] .¶
Initial version. Defines RoleAssignment schema, attributes, and operations. Adds priority, complete example, error examples, and query patterns. Includes error handling, backward compatibility, and IANA registration. Updates BCP14 boilerplate; replaces non-ASCII; converts ASCII tables to RFCXML tables; updates Roles/Entitlements reference to -02; cites RFC8141.¶
Prithvi Poreddy<br/> Email: <prithvikrishnab4u@gmail.com>¶