RFC 7643

System for Cross-domain Identity Management: Core Schema

๐Ÿ“… published September 2015, from ietf

System for Cross-domain Identity Management: Core Schema ๐ŸŽ€

Okay bestie, this one is RFC 7643 ๐Ÿ’– It's a Standards Track document from the IETF, published in September 2015 with ISSN 2070-1721. The editor is P. Hunt from Oracle, and the other authors are K. Grizzle (SailPoint), E. Wahlstroem (Nexus Technology), and C. Mortimore (Salesforce). Nothing in its header says it obsoletes or updates another RFC, so it's a fresh start ๐ŸŒธ

Abstract

Okay so the SCIM specs (System for Cross-domain Identity Management) exist to make identity management in cloud apps and services way easier โœจ The suite is built on experience with existing schemas and deployments, and it puts a lot of focus on keeping development and integration simple, while still using the authentication, authorization, and privacy models people already have. The whole point is to cut the cost and complexity of user management by giving everyone a common user schema and extension model, plus binding documents that show how to swap that schema over HTTP ๐Ÿฆ‹

This document is the platform-neutral schema and extension model for representing users, groups, and other resource types in JSON format. It's written for exchange and use with cloud service providers, so yes, it's giving interoperability ๐Ÿ’…

Status of This Memo

This is an Internet Standards Track document ๐ŸŒˆ

It's a product of the Internet Engineering Task Force (IETF), which means it reflects the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check out Section 2 of RFC 5741 ๐Ÿ“š

For the current status, any errata, and how to send feedback, go to http://www.rfc-editor.org/info/rfc7643 ๐Ÿ”—

Copyright (c) 2015 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, which you can find at http://trustee.ietf.org/license-info, as they were in effect on the date this document was published. Please read them carefully, because they spell out your rights and restrictions for this document ๐Ÿซถ Code Components pulled out of this document must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as described in the Simplified BSD License โญ

Table of Contents

1. Introduction and Overview .......................................3
   1.1. Requirements Notation and Conventions ......................4
   1.2. Definitions ................................................5
2. SCIM Schema .....................................................6
   2.1. Attributes .................................................7
   2.2. Attribute Characteristics ..................................8
   2.3. Attribute Data Types .......................................8
        2.3.1. String ..............................................9
        2.3.2. Boolean .............................................9
        2.3.3. Decimal ............................................10
        2.3.4. Integer ............................................10
        2.3.5. DateTime ...........................................10
        2.3.6. Binary .............................................10
        2.3.7. Reference ..........................................10
        2.3.8. Complex ............................................11
   2.4. Multi-Valued Attributes ...................................11
   2.5. Unassigned and Null Values ................................13
3. SCIM Resources .................................................13
   3.1. Common Attributes .........................................16
   3.2. Defining New Resource Types ...............................18
   3.3. Attribute Extensions to Resources .........................18
4. SCIM Core Resources and Extensions .............................19
   4.1. "User" Resource Schema ....................................19
        4.1.1. Singular Attributes ................................19
        4.1.2. Multi-Valued Attributes ............................23
   4.2. "Group" Resource Schema ...................................25
   4.3. Enterprise User Schema Extension ..........................26
5. Service Provider Configuration Schema ..........................27
6. ResourceType Schema ............................................29
7. Schema Definition ..............................................30
8. JSON Representation ............................................34
   8.1. Minimal User Representation ...............................34
   8.2. Full User Representation ..................................35
   8.3. Enterprise User Extension Representation ..................39
   8.4. Group Representation ......................................43
   8.5. Service Provider Configuration Representation .............44
   8.6. Resource Type Representation ..............................46
   8.7. Schema Representation .....................................47
        8.7.1. Resource Schema Representation .....................47
        8.7.2. Service Provider Schema Representation .............74
9. Security Considerations ........................................92
   9.1. Protocol ..................................................92
   9.2. Passwords and Other Sensitive Security Data ...............92
   9.3. Privacy ...................................................92
10. IANA Considerations ...........................................94
    10.1. Registration of SCIM URN Sub-namespace and SCIM
          Registry .................................................94
    10.2. URN Sub-namespace for SCIM ...............................94
          10.2.1. Specification Template ............................95
    10.3. Registering SCIM Schemas .................................97
          10.3.1. Registration Procedure ............................97
          10.3.2. Schema Registration Template ......................98
    10.4. Initial SCIM Schema Registry .............................99
11. References ...................................................100
    11.1. Normative References ....................................100
    11.2. Informative References ..................................101
Acknowledgements .................................................103
Authors' Addresses ...............................................104

1. Introduction and Overview โœจ

Okay so, there are already standards for describing and exchanging user information, but a lot of them are hard to implement and/or use ๐Ÿ˜ญ For example, their wire protocols don't easily get through firewalls, and they aren't easily layered onto existing web protocols. So lots of cloud providers just make up their own non-standard protocols for managing users, and that makes things way more expensive and complicated for organizations that use products from several cloud providers, because they have to do redundant integration work ๐Ÿ’€ Cloud service providers that want to work with multiple application marketplaces or cloud identity providers would also need pairwise integration, which is a lot.

SCIM is here to fix that ๐Ÿ’– It's an easy-to-implement specification suite with a common user schema and extension model, plus a SCIM protocol document that defines how to exchange this schema over an HTTP-based protocol [RFC7644]. The SCIM specs take design input and feedback from a bunch of identity-related protocols and schemas, including existing services exposed by cloud providers, PortableContacts [PortableContacts], vCards [RFC6350], and Lightweight Directory Access Protocol (LDAP) directory services [RFC4512]. Not me gathering all the best ideas ๐Ÿงš

The SCIM protocol is an application-level protocol for provisioning and managing identity data that's described through SCIM schemas. It supports creating, modifying, retrieving, and discovering core identity resources like Users and Groups, using a subset of the HTTP methods: GET for retrieving resources, POST for creating, searching, and bulk modification, PUT for replacing attributes within resources, PATCH for partially updating attributes, and DELETE for removing resources ๐Ÿฆ‹

The SCIM protocol and core schema specs are meant to cover point-to-point scenarios, but implementers and deployers should also think about multi-hop and multi-party scenarios ๐Ÿ‘‘ For example, a service provider might act as a general profile service for in-domain applications, like a directory. Or a service provider might pass information on to a third-party service provider by acting as either a SCIM client or a SCIM service provider. Implementers and deployers should really think hard about their service level agreements and privacy agreements before distributing or propagating personal information (see Section 9.3). Privacy is a whole vibe ๐Ÿ™ˆ

This document provides a JSON-based schema and extension model for representing users and groups, along with service provider configuration. It's intended for exchange and use with cloud service providers and other cross-domain scenarios ๐ŸŒธ

1.1. Requirements Notation and Conventions ๐Ÿ’…

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. These are the key words that carry the requirement weight, so pay attention to them ๐Ÿ”ฅ

The key words "REQUIRED" and "OPTIONAL" show up all over this document to say whether an attribute or schema element is required or optional. They can stand alone (like "REQUIRED.") or sit inside a sentence. If nothing is specified, an attribute counts as optional ๐Ÿ“

The word "DEFAULT" in Section 7 means a "keyword" value for an attribute characteristic is the default behavior ๐ŸŒˆ

Values in this document are in quotes to show they're meant to be taken literally. When you use these values in protocol messages, the quotes MUST NOT be part of the value โš ๏ธ Honestly this is the kind of detail that gets people, so don't skip it ๐Ÿ˜ญ

Figures in this document may have extra spaces and line wrapping so they're easier to read and fit on the page. Some URIs in the examples are also shortened for space and readability ๐Ÿงš

1.2. Definitions ๐Ÿ’…

Okay so, time for the glossary, bestie. These are the words the whole spec throws around, so let's get them down. ๐ŸŽ€

Service Provider ๐ŸŒธ An HTTP web application that provides identity information via the SCIM protocol.

Client ๐Ÿฆ‹ A website or application that uses the SCIM protocol to manage identity data maintained by the service provider. The client starts SCIM HTTP requests aimed at a target service provider.

Provisioning Domain ๐Ÿฐ A provisioning domain is an administrative domain outside the domain of a service provider, for legal or technical reasons. For example, a SCIM client in an enterprise (provisioning client) talks to a SCIM service provider that's owned or controlled by a different legal entity. Two companies, two lanes, no cap. ๐Ÿ™ˆ

Resource Type ๐Ÿงš A type of resource that a service provider manages. The resource type defines the resource name, endpoint URL, schemas, and other metadata that tell you where a resource lives and how it's put together, e.g., "User" or "Group". โœจ

Resource ๐Ÿ’œ An artifact that a service provider manages, and that holds one or more attributes, e.g., "User" or "Group". ๐Ÿ“

Endpoint ๐Ÿ›ค๏ธ An endpoint for a service provider is a defined base path, relative to the service provider's Base URI (see Section 1.3 of [RFC7644]), where SCIM operations can happen against SCIM resources. For example, if the service provider's Base URI is https://example.com/, then "User" resources can be reached at https://example.com/Users or https://example.com/v2/Users. (See Section 3.13 of [RFC7644] for the deets on protocol versioning, e.g., 'v2'.) Service provider schemas MAY be returned from the /Schemas endpoint. ๐ŸŒˆ

Schema ๐Ÿ“œ A collection of attribute definitions that describe the contents of an entire or partial resource, e.g., urn:ietf:params:scim:schemas:core:2.0:User. The attribute definitions spell out the attribute's name, plus metadata like type (e.g., string, binary), cardinality (singular, multi, complex), mutability, and returnability. Lots of details, but they're giving organized. ๐Ÿ—‚๏ธ

Singular Attribute 1๏ธโƒฃ A resource attribute that holds 0..1 values, e.g., "displayName". Solo queen energy. ๐Ÿ‘‘

Multi-valued Attribute ๐ŸŽถ A resource attribute that holds 0..n values, e.g., "emails". The group chat version. ๐Ÿ’ฌ

Simple Attribute ๐Ÿฌ A singular or multi-valued attribute whose value is a primitive, e.g., "String". A simple attribute MUST NOT contain sub-attributes. No nesting allowed, periodt. ๐Ÿ™…โ€โ™€๏ธ

Complex Attribute ๐Ÿงฉ A singular or multi-valued attribute whose value is made up of one or more simple attributes. For example, "addresses" has the sub-attributes "streetAddress", "locality", "postalCode", and "country". This one's a whole outfit. ๐Ÿ‘—

Sub-Attribute ๐Ÿชž A simple attribute that lives inside a complex attribute. Think of it as the accessory on the outfit. ๐Ÿ’–


2. SCIM Schema โœจ

Okay, this is where it gets juicy. A SCIM server offers a set of resources, and what's allowed inside them is defined by a set of schema URIs and a resource type. SCIM's schema is NOT document-centric like [XML-Schema] is. Instead, SCIM's schema support is attribute based, where each attribute can have a different type, mutability, cardinality, or returnability. ๐Ÿฆ‹

Checking documents and messages is always done by the intended receiver, as the SCIM specifications say. The receiver validates in the context of a SCIM protocol request (see [RFC7644]). For example, if a SCIM service provider gets a request to replace an existing resource with a replacement JSON object, it looks at each asserted attribute based on its characteristics in the relevant schema (e.g., mutability), and then decides which attributes get replaced and which get ignored. Smart, right? ๐Ÿง 

This spec gives you a minimal core schema for representing users and groups (resources), covering common attributes found in lots of existing deployments and schemas. On top of that core schema, this document also lays out a standard way for service providers to extend schemas, so they can define new resources and attributes, both standardized ones and service-provider-specific ones. Extensibility is everything. ๐ŸŒธ

Resources get sorted into common resource types like "User" or "Group". Collections of resources of the same type usually live together in the same "container" ("folder") endpoint. Organized bestie, very healthy. ๐Ÿ“

2.1. Attributes ๐ŸŽ€

A resource is a collection of attributes identified by one or more schemas. At minimum, an attribute is made of the attribute name and at least one simple or complex value, and either kind of value can be multi-valued. For each attribute, a SCIM schema defines the data type, plurality, mutability, and other distinguishing features. ๐Ÿ’…

Attribute names are case insensitive and are often "camel-cased" (e.g., "camelCase"). SCIM resources are represented in JSON [RFC7159] format, and they MUST specify schema via the schemas attribute per Section 3. Non-negotiable. ๐Ÿšซ

Attribute names MUST conform to the following ABNF rules:

            ATTRNAME   = ALPHA *(nameChar)
            nameChar   = "$" / "-" / "_" / DIGIT / ALPHA

Figure 1: ABNF for Attribute Names ๐Ÿ“

The rules above (and other rules in this specification) use the "Core Rules" from ABNF. See Appendix B of [RFC5234]. Unless this document says otherwise, all ABNF strings are case insensitive and the character set for these strings is US-ASCII. So all attribute names defined by the rule above are case insensitive. Consistent, iconic. ๐Ÿ”ค

When you're defining attribute names, heads up: the hyphen (-) is not permitted in JavaScript attribute names (or in attribute names for some other languages). There are no known issues within the HTTP protocol and JSON notation, but attribute names with hyphens may need to be escaped when you declare the matching JavaScript attributes. Not a bug, just a vibe check. โš ๏ธ

2.2. Attribute Characteristics ๐Ÿ“‹

Every attribute has a set of characteristics that describe its type and how the service provider handles it. The full definitions are in Section 7. The characteristics include:

  • required
  • canonicalValues
  • caseExact
  • mutability
  • returned
  • uniqueness
  • referenceTypes

If Section 7 doesn't say otherwise, SCIM attributes have these characteristics:

  • required is false (i.e., not REQUIRED) ๐Ÿ™…
  • canonicalValues: none assigned (for example, the "type" sub-attribute as described in Section 2.4) ๐Ÿซฅ
  • caseExact is false (i.e., case-insensitive) ๐Ÿ”ก
  • mutability is readWrite (i.e., modifiable) โœ๏ธ
  • returned is default (the attribute value is returned by default) ๐Ÿ“ฌ
  • uniqueness is none (has no uniqueness enforced) ๐ŸŒ€
  • type is string (Section 2.3.1) ๐Ÿญ

2.3. Attribute Data Types ๐Ÿงƒ

Attribute data types come from JSON [RFC7159]. The JSON format only defines a limited set of data types, so where it makes sense, alternate JSON representations derived from XML Schema [XML-Schema] are defined below. SCIM extensions SHOULD NOT introduce new data types. Keep it simple, bestie. ๐Ÿค

Table 1 maps the SCIM data types to their matching SCIM schema type and underlying JSON data type:

+-----------+-------------+-----------------------------------------+
| SCIM Data | SCIM Schema | JSON Type                               |
| Type      | "type"      |                                         |
+-----------+-------------+-----------------------------------------+
| String    | "string"    | String per Section 7 of [RFC7159]       |
|           |             |                                         |
| Boolean   | "boolean"   | Value per Section 3 of [RFC7159]        |
|           |             |                                         |
| Decimal   | "decimal"   | Number per Section 6 of [RFC7159]       |
|           |             |                                         |
| Integer   | "integer"   | Number per Section 6 of [RFC7159]       |
|           |             |                                         |
| DateTime  | "dateTime"  | String per Section 7 of [RFC7159]       |
|           |             |                                         |
| Binary    | "binary"    | Binary value base64 encoded per Section |
|           |             | 4 of [RFC4648], or with URL and         |
|           |             | filename safe alphabet URL per Section  |
|           |             | 5 of [RFC4648] that is passed as a JSON |
|           |             | string per Section 7 of [RFC7159]       |
|           |             |                                         |
| Reference | "reference" | String per Section 7 of [RFC7159]       |
|           |             |                                         |
| Complex   | "complex"   | Object per Section 4 of [RFC7159]       |
+-----------+-------------+-----------------------------------------+

Table 1: SCIM Data Type to JSON Representation ๐Ÿ—บ๏ธ

2.3.1. String ๐Ÿงต

A sequence of zero or more Unicode characters, encoded using UTF-8 as per [RFC2277] and [RFC3629]. The JSON format is defined in Section 7 of [RFC7159]. An attribute with SCIM schema type "string" MAY specify a required data format. Also, when canonicalValues is specified, service providers MAY restrict accepted values to the specified values. Options, but make them clear. ๐ŸŽจ

2.3.2. Boolean โœ…

The literal "true" or "false". The JSON format is defined in Section 3 of [RFC7159]. A boolean has no case sensitivity or uniqueness. It's giving binary, and that's it. ๐ŸŒ—

2.3.3. Decimal ๐Ÿ”ข

A real number with at least one digit to the left and right of the period. The JSON format is defined in Section 6 of [RFC7159]. A decimal has no case sensitivity. ๐Ÿ’ซ

2.3.4. Integer ๐ŸŽฏ

A whole number with no fractional digits or decimal. The JSON format is defined in Section 6 of [RFC7159], with the extra rule that the value MUST NOT contain fractional or exponent parts. An integer has no case sensitivity. Whole numbers only, no drama. ๐Ÿ™Œ

2.3.5. DateTime ๐Ÿ•ฐ๏ธ

A DateTime value (e.g., 2008-01-23T04:56:22Z). The attribute value MUST be encoded as a valid xsd:dateTime as specified in Section 3.3.7 of [XML-Schema], and it MUST include both a date and a time. A date time format has no case sensitivity or uniqueness. Timestamps with receipts. โฐ

Values represented in JSON format MUST conform to the XML constraints above, and they are represented as a JSON string per Section 7 of [RFC7159]. Strict, but iconic. ๐Ÿ’…

2.3.6. Binary ๐Ÿงฑ

Arbitrary binary data. The attribute value MUST be base64 encoded as specified in Section 4 of [RFC4648]. Where a URL-safe encoding is needed, the attribute definition MAY specify that base64 URL encoding be used, as per Section 5 of [RFC4648]. Unless the attribute definition says otherwise, trailing padding characters MAY be omitted ("="). Padding is optional, bestie. ๐ŸŒ™

In JSON representation, the encoded values are represented as a JSON string per Section 7 of [RFC7159]. A binary is case exact and has no uniqueness. Raw data, dressed up nicely. ๐ŸŽ

2.3.7. Reference โœจ

okay so a reference is basically a URI that points at a resource ๐Ÿ”— and a resource MAY be a SCIM resource, an external link to a resource (like a photo ๐Ÿ“ธ), or an identifier such as a URN. the value MUST be the absolute or relative URI of the target resource. relative URIs should be resolved as specified in Section 5.2 of [RFC3986], BUT the base URI for relative URI resolution MUST include all URI components and path segments up to, but not including, the Endpoint URI (the SCIM service provider root endpoint) ๐ŸŒธ

for example, if a request goes to "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646", the base URI would be "https://example.com/v2/" and the relative URI for that resource would be "Users/2819c223-7f76-453a-919d-413861904646". the way the base gets split up is so clean ๐Ÿ˜ญ๐Ÿ’…

in JSON, the URI value is just a JSON string (per Section 7 of [RFC7159]) and a reference is case exact, so don't you dare change the casing ๐Ÿ™…โ€โ™€๏ธ. a reference also has a "referenceTypes" attribute that tells you what types of resources may be linked, as per Section 7 of this document ๐Ÿฆ‹

now the important bit: a reference URI MUST be to an HTTP-addressable resource ๐Ÿ”ฅ. an HTTP client doing a GET on a reference URI MUST receive the target resource or an appropriate HTTP response code. and a SCIM service provider MAY choose to enforce referential integrity for reference types referring to SCIM resources ๐Ÿงš

by convention, a reference is usually shown as a "$ref" sub-attribute inside complex or multi-valued attributes, but this is OPTIONAL ๐Ÿ’œ

2.3.8. Complex โœจ

a complex attribute is a singular or multi-valued attribute whose value is made of one or more simple attributes stuck together ๐Ÿงฉ. the JSON format is defined in Section 4 of [RFC7159]. the order of the component attributes is not significant, so servers and clients MUST NOT require or expect attributes to be in any specific order when an object is generated or analyzed ๐Ÿ™ˆ. a complex attribute has no uniqueness or case sensitivity, and a complex attribute MUST NOT contain sub-attributes that have sub-attributes (aka that are complex) ๐Ÿ’€

2.4. Multi-Valued Attributes ๐ŸŽ€

multi-valued attributes hold a list of elements using the JSON array format from Section 5 of [RFC7159] ๐ŸŒˆ. each element can be either of these:

  • primitive values, or
  • objects with a set of sub-attributes and values, using the JSON object format from Section 4 of [RFC7159]. when they're objects, they SHALL be considered to be complex attributes ๐Ÿซถ. as with complex attributes, the order of sub-attributes is not significant. the predefined sub-attributes listed in this section can be used with multi-valued attribute objects, but these sub-attributes MUST be used with the meanings defined here โœจ

if nothing else is defined, the default set of sub-attributes for a multi-valued attribute is below, bestie ๐Ÿ‘‘

type A label showing the attribute's function, e.g., "work" or "home" ๐Ÿก

primary A Boolean value showing the 'primary' or preferred attribute value for this attribute, e.g., the preferred mailing address or the primary email address ๐Ÿ“ฌ. the primary attribute value "true" MUST appear no more than once (only ONE main character per attribute, periodt ๐Ÿ’…). if it's not specified, the value of "primary" SHALL be assumed to be "false".

display A human-readable name, mainly for display purposes, and it has a mutability of "immutable" ๐Ÿ”’.

value The attribute's significant value, e.g., an email address or phone number ๐Ÿ“ž.

$ref The reference URI of a target resource, if the attribute is a reference. URIs get canonicalized per Section 6.2 of [RFC3986] ๐Ÿ”. while the representation of a resource may vary across SCIM protocol API versions (see Section 3.13 of [RFC7644]), URIs for SCIM resources with an API version SHALL be considered comparable to URIs without a version or with a different version. for example, "https://example.com/Users/12345" is equivalent to "https://example.com/v2/Users/12345" ๐Ÿฆ‹

when service providers return multi-valued attributes, they SHOULD canonicalize the value returned (e.g., by returning a value for the sub-attribute "type", such as "home" or "work") when that makes sense (e.g., for email addresses and URLs) ๐Ÿ’–.

service providers MAY return element objects with the same "value" sub-attribute more than once with a different "type" sub-attribute (e.g., the same email address may be used for work AND home ๐Ÿ ๐Ÿ’ผ), but they SHOULD NOT return the same (type, value) combination more than once per attribute, because that makes processing a mess for the client ๐Ÿ˜ญ.

when defining schema for multi-valued attributes, it's considered good practice to provide a type attribute that MAY be used for canonicalization of values ๐Ÿงน. in the schema definition for an attribute, the service provider MAY define the recommended canonical values (see Section 7) ๐ŸŒธ.

2.5. Unassigned and Null Values ๐Ÿซง

unassigned attributes, the null value, or an empty array (for a multi-valued attribute) SHALL be considered equivalent in "state" ๐Ÿค. assigning an attribute the value "null" or an empty array (for multi-valued attributes) makes the attribute "unassigned" ๐Ÿ™ƒ. when a resource is expressed in JSON format, unassigned attributes (even though they're defined in the schema) MAY be omitted for compactness ๐Ÿ“.

3. SCIM Resources ๐ŸŒŸ

each SCIM resource is a JSON object with the following components ๐Ÿง:

Resource Type each resource (or JSON object) in SCIM has a resource type ("meta.resourceType"; see Section 3.1) that defines the resource's core attribute schema and any attribute extension schema, plus the endpoint where objects of the same type can be found ๐Ÿ—บ๏ธ. more information about a resource MAY be found in its resource type definition (see Section 6) ๐Ÿ“–.

"Schemas" Attribute the "schemas" attribute is a REQUIRED attribute and it's an array of Strings containing URIs that show the namespaces of the SCIM schemas defining the attributes present in the current JSON structure ๐Ÿงพ. parsers may use this to figure out which attributes are in the JSON body of an HTTP request or response ๐Ÿ‘€. each String value must be a unique URI. ALL representations of SCIM schemas MUST include a non-empty array with the value(s) of the URIs supported by that representation ๐Ÿ’ฏ. the "schemas" attribute for a resource MUST only contain values defined as "schema" and "schemaExtensions" for the resource's defined "resourceType" ๐ŸŽฏ. duplicate values MUST NOT be included. value order is not specified and MUST NOT impact behavior, so don't stress about it ๐Ÿซถ.

Common Attributes a resource's common attributes are the ones that are part of EVERY SCIM resource, no matter what the "schemas" attribute says in the JSON body ๐ŸŒ. these aren't defined in any particular schema, but they SHALL be assumed to be present in every resource, regardless of the value of the "schemas" attribute. see Section 3.1 ๐Ÿฆ‹.

Core Attributes a resource's core attributes are the ones sitting at the top level of the JSON object alongside the common attributes (like the resource "id") ๐Ÿช„. the list of valid attributes is specified by the resource type's "schema" attribute (see Section 6). this same value is also present in the resource's "schemas" attribute ๐Ÿ”.

Extended Attributes extended schema attributes are specified by the resource type's "schemaExtensions" attribute (see Section 6) ๐Ÿงฉ. unlike core attributes, extended attributes live in their own sub-attribute namespace, identified by the schema extension URI. this avoids name conflicts from separate schema extensions ๐Ÿ™Œ.

the example "User" below has the common attributes "id" and "externalId", plus the complex attribute "meta", which contains the sub-attribute "resourceType". the resource also has core attributes "userName" and "name", and extended enterprise User attributes "employeeNumber" and "costCenter", which sit in their own JSON substructure identified by their schema URI ๐Ÿข. some values have been omitted (...), shortened, or spaced out for clarity, so don't panic if it looks a bit messy ๐Ÿ™ˆ.

{
  "schemas":
    ["urn:ietf:params:scim:schemas:core:2.0:User",
      "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],

  "id": "2819c223-7f76-453a-413861904646",
  "externalId": "701984",

  "userName": "bjensen@example.com",
  "name": {
    "formatted": "Ms. Barbara J Jensen, III",
    "familyName": "Jensen",
    "givenName": "Barbara",
    "middleName": "Jane",
    "honorificPrefix": "Ms.",
    "honorificSuffix": "III"
  },
 ...

  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "employeeNumber": "701984",
    "costCenter": "4130",
    ...
  },

  "meta": {
    "resourceType": "User",
    "created": "2010-01-23T04:56:22Z",
    "lastModified": "2011-05-13T04:42:34Z",
    "version": "W\/\"3694e05e9dff591\"",
    "location":
      "https://example.com/v2/Users/2819c223-7f76-453a-413861904646"
  }
}

Figure 2: Example JSON Resource Structure ๐Ÿ“ธ๐Ÿ’•

3.1. Common Attributes โœจ

okay so every SCIM resource (Users, Groups, all of them ๐Ÿ’…) gets the same set of common attributes. The only exceptions are the "ServiceProviderConfig" and "ResourceType" server discovery endpoints and their resources, and those are the odd ones out ๐Ÿ™ˆ. Everywhere else these attributes MUST be defined, including on any extended resource types. When a service provider accepts a resource (like after a SCIM create), it MUST assign values to id and meta (plus its sub-attributes). Common attributes are treated as part of every base resource schema, so they don't get their own schemas URI. Lowkey iconic, no extra URI needed ๐Ÿฆ‹

For backward compatibility, some older schema definitions MAY list common attributes as part of the schema. The attribute characteristics (see Section 2.2) listed here SHALL take precedence over any older definitions in existing schemas. So the rules in this section win, periodt ๐Ÿ‘‘

id This is the unique identifier for a SCIM resource, as defined by the service provider. Every representation of the resource MUST include a non-empty id value. The identifier MUST be unique across the service provider's entire set of resources. It MUST be stable and non-reassignable, meaning it does not change when the same resource comes back in later requests. The service provider always issues the id value, and it MUST NOT be specified by the client. The string bulkId is a reserved keyword, so it MUST NOT appear in any unique identifier value. The attribute characteristics are caseExact as true, a mutability of readOnly, and a returned characteristic of always. Privacy considerations are in Section 9, so go check those ๐Ÿ”

externalId A String that identifies the resource as defined by the provisioning client. This one is a total game changer ๐Ÿงš It lets the client find a resource using a filter with an identifier from its own provisioning domain. That means the client doesn't need to keep a local mapping between its identifier and the one the service provider uses. Each resource MAY include a non-empty externalId value. The provisioning client always issues the externalId value, and it MUST NOT be specified by the service provider. The service provider MUST always interpret externalId as scoped to the provisioning domain. The server doesn't enforce uniqueness, and it is assumed that the client controls uniqueness when it sets the value. Privacy considerations are in Section 9 again, bestie ๐Ÿซถ This attribute has caseExact as true and a mutability of readWrite. This attribute is OPTIONAL.

meta This is a complex attribute holding resource metadata. The service provider assigns all of the meta sub-attributes (they have a mutability of readOnly), and every one of them has a returned characteristic of default. This attribute SHALL be ignored when clients provide it, so don't even try ๐Ÿ™… meta contains the following sub-attributes:

  • resourceType: The name of the resource's resource type. This attribute has a mutability of readOnly and caseExact as true.
  • created: The DateTime that the resource was added to the service provider. This attribute MUST be a DateTime.
  • lastModified: The most recent DateTime that the details of this resource were updated at the service provider. If the resource has never been modified since it was first created, the value MUST be the same as the value of created.
  • location: The URI of the resource being returned. This value MUST be the same as the Content-Location HTTP response header (see Section 3.1.4.2 of [RFC7231]).
  • version: The version of the resource being returned. This value must be the same as the entity-tag (ETag) HTTP response header (see Sections 2.1 and 2.3 of [RFC7232]). This attribute has caseExact as true. Service provider support for this attribute is optional and depends on the service provider's support for versioning (see Section 3.14 of [RFC7644]). If a service provider provides version (entity-tag) for a representation, and the way that entity-tag is generated does not satisfy all of the characteristics of a strong validator (see Section 2.1 of [RFC7232]), then the origin server MUST mark the version (entity-tag) as weak by prefixing its opaque value with W/ (case sensitive). Weak tags are giving "not quite perfect" energy, but they're still valid ๐ŸŒธ

3.2. Defining New Resource Types ๐Ÿ“

SCIM can be extended to define brand new classes of resources, and it's done by defining a resource type. Each resource type defines its name, its endpoint, its base schema (the attributes), and any schema extensions registered for use with that resource type. To offer new types of resources, a service provider defines the new resource type as specified in Section 6, and it also defines a schema representation (see Section 8.7). Main character energy for whatever you invent next โœจ

3.3. Attribute Extensions to Resources ๐ŸŒˆ

SCIM lets resource types have extensions on top of their core schema. This is kind of like how "objectClasses" work in LDAP [RFC4512], except LDAP has inheritance and SCIM doesn't ๐Ÿ™ƒ Here, all extensions are additive, similar to the LDAP auxiliary object class. Each value in the schemas attribute names an additive schema that MAY exist in a SCIM resource representation. The schemas attribute MUST contain at least one value, and that value SHALL be the base schema for the resource. The schemas attribute MAY contain extra values for any extended schemas that are in use. Schema extensions SHOULD avoid redefining any attributes defined in this specification, and they SHOULD follow the conventions defined in this specification, so keep it consistent bestie ๐Ÿ’œ Except for the base object schema, the schema extension URI SHALL be used as a JSON container. This separates attributes belonging to the extension namespace from the base schema attributes. See Figure 5 for an example of the JSON representation of an enterprise User, which is also an example of a User with an extended schema ๐ŸŽ€

To figure out which URI in the schemas attribute is the base schema and which is an extension, for any given resource, the resource's resourceType attribute value MAY be used to retrieve the resource's ResourceType schema (see Section 6). See the ResourceType representation in Figure 8 for an example ๐Ÿ”

4. SCIM Core Resources and Extensions ๐Ÿ’–

This section defines the default resource schemas present in a SCIM server. SCIM isn't limited to these resources, though, and it can be extended to support other resource types (see Section 3.2). Literally so flexible ๐Ÿฆ‹

4.1. "User" Resource Schema ๐Ÿง‘โ€๐Ÿ’ป

SCIM provides a resource type for "User" resources. The core schema for "User" is identified with the following schema URI: urn:ietf:params:scim:schemas:core:2.0:User. The following attributes are defined in addition to the core schema attributes:

4.1.1. Singular Attributes โœจ

Okay bestie, here come the singular attributes, the ones that show up exactly once per user ๐Ÿ’–

userName ๐Ÿฆ‹ is the service provider's unique identifier for the user, the one the user actually types in to log in ๐Ÿ”‘. It's the readable one, way better than "id" or "externalId", which are basically opaque ๐Ÿ™ˆ. Each User MUST include a non-empty userName value. This identifier MUST be unique across the service provider's entire set of Users. This attribute is REQUIRED and is case insensitive ๐Ÿ’….

name ๐ŸŒธ is all the pieces of the user's name. Service providers MAY return just the full name as one string in the formatted sub-attribute, or they MAY return just the individual component sub-attributes, or they MAY return both. If both come back, they SHOULD be describing the same name, with the formatted name showing how the components get put together ๐ŸŽ€.

  • formatted ๐Ÿ’– is the full name, including all middle names, titles, and suffixes as appropriate, formatted for display (e.g., "Ms. Barbara Jane Jensen, III").
  • familyName ๐ŸŒˆ is the family name of the User, or last name in most Western languages (e.g., "Jensen" given the full name "Ms. Barbara Jane Jensen, III").
  • givenName โญ is the given name of the User, or first name in most Western languages (e.g., "Barbara" given the full name "Ms. Barbara Jane Jensen, III").
  • middleName ๐Ÿงš is the middle name(s) of the User (e.g., "Jane" given the full name "Ms. Barbara Jane Jensen, III").
  • honorificPrefix ๐Ÿ‘‘ is the honorific prefix(es) of the User, or title in most Western languages (e.g., "Ms." given the full name "Ms. Barbara Jane Jensen, III").
  • honorificSuffix ๐Ÿ’œ is the honorific suffix(es) of the User, or suffix in most Western languages (e.g., "III" given the full name "Ms. Barbara Jane Jensen, III").

displayName ๐Ÿ“ is the name of the user, suitable for showing to end-users. Each user returned MAY include a non-empty displayName value. It SHOULD be the full name of the User being described, if known (e.g., "Babs Jensen" or "Ms. Barbara J Jensen, III"), but it MAY be a username or handle if that's all that's available (e.g., "bjensen"). The value provided SHOULD be the primary textual label that the service provider normally displays for this User when presenting it to end-users โœจ.

nickName ๐Ÿ™ˆ is the casual way to address the user in real life, e.g., "Bob" or "Bobby" instead of "Robert". This attribute SHOULD NOT be used to represent a User's username (e.g., bjensen or mpepperidge). Not the same thing, bestie ๐Ÿ’€.

profileUrl ๐Ÿ”— is a URI that is a uniform resource locator (as defined in Section 1.1.3 of [RFC3986]) and that points to a location representing the user's online profile (e.g., a web page). URIs are canonicalized per Section 6.2 of [RFC3986] ๐Ÿฆ‹.

title ๐Ÿ‘‘ is the user's title, such as "Vice President". Iconic ๐Ÿ’….

userType ๐ŸŒธ identifies the relationship between the organization and the user. Typical values might be "Contractor", "Employee", "Intern", "Temp", "External", and "Unknown", but any value may be used ๐Ÿซถ.

preferredLanguage ๐ŸŒˆ says which written or spoken languages the user prefers, and it's generally used for picking a localized user interface ๐Ÿ‡ซ๐Ÿ‡ท. The value is a set of natural languages in preferred order. Its format is the same as the HTTP Accept-Language header field (not including Accept-Language:) and is specified in Section 5.3.5 of [RFC7231]. The whole point is letting cloud apps match language tags [RFC4647] to the user's preferences, even when the user agent is shared, or when there's no user in the loop at all (like a delegated OAuth 2.0 [RFC6749] style interaction), where normal HTTP Accept-Language negotiation can't happen ๐Ÿ˜ญ.

locale ๐ŸŽ€ is the User's default location for localizing stuff like currency, date time format, or number representations. A valid value is a language tag as defined in [RFC5646]. Computer languages are explicitly excluded, so no sneaking in programming languages ๐Ÿ™….

A language tag is one or more case-insensitive sub-tags, each separated by a hyphen character ("-", %x2D). For backward compatibility, servers MAY accept tags separated by an underscore character ("_", %x5F). Usually a language tag has a primary language sub-tag for a broad family of related languages (e.g., "en" = English), optionally followed by sub-tags that refine or narrow that range (e.g., "en-CA" = the variety of English communicated in Canada) ๐Ÿ‡จ๐Ÿ‡ฆ. Whitespace is not allowed inside a language tag. Example tags include:

fr, en-US, es-419, az-Arab, x-pig-latin, man-Nkoo-GN

See [RFC5646] for more info ๐Ÿ“š.

timezone ๐ŸŒ is the User's time zone, in IANA Time Zone database format [RFC6557], also known as the "Olson" time zone database format [Olson-TZ] (e.g., America/Los_Angeles) โฐ.

active ๐Ÿฆ‹ is a Boolean value for the user's administrative status. Its definitive meaning is decided by the service provider. As a typical example, true means the user can log in, while false means the account has been suspended ๐Ÿ”’.

password ๐Ÿ” is for setting, replacing, or comparing (i.e., filtering for equality) a password. This one is serious, bestie ๐Ÿ˜ค. The cleartext value or the hashed value of a password SHALL NOT be returnable by a service provider. If a service provider holds the value locally, the value SHOULD be hashed. When a password is set or changed by the client, the cleartext password SHOULD be processed by the service provider as follows:

  • Prepare the cleartext value for international language comparison. See Section 7.8 of [RFC7644].
  • Validate the value against server password policy. Note: The definition and enforcement of password policy are beyond the scope of this document.
  • Ensure that the value is encrypted (e.g., hashed). See Section 9.2 for acceptable hashing and encryption handling when storing or persisting for provisioning workflow reasons.

A service provider that immediately passes the cleartext value on to another system or programming interface MUST pass the value directly over a secured connection (e.g., Transport Layer Security (TLS)). If the value needs to be temporarily persisted for a period of time (e.g., because of a workflow) before provisioning, then the value MUST be protected by some method, such as encryption ๐Ÿ›ก๏ธ.

Testing for an equality match MAY be supported if there is an existing stored hashed value. When testing for equality, the service provider:

  • Prepares the filter value for international language comparison. See Section 7.8 of [RFC7644].
  • Generates the salted hash of the filter value and tests for a match with the locally held value.

The mutability of the password attribute is "writeOnly", indicating that the value MUST NOT be returned by a service provider in any form (the attribute characteristic "returned" is "never"). Passwords are for logging in, not for sharing, periodt ๐Ÿซถ๐Ÿ’œ

4.1.2. Multi-Valued Attributes โœจ

okay bestie, here are the multi-valued attributes defined for the User ๐Ÿ’…

emails

Email addresses for the User. The value SHOULD be specified according to [RFC5321]. Service providers SHOULD canonicalize the value according to [RFC5321], e.g., "bjensen@example.com" instead of "bjensen@EXAMPLE.COM". The display sub-attribute MAY be used to return the canonicalized representation of the email value. The type sub-attribute is used to provide a classification meaningful to the (human) user. The user interface should encourage the use of basic values of work, home, and other and MAY allow additional type values to be used at the discretion of SCIM clients.

phoneNumbers

Phone numbers for the user. The value SHOULD be specified according to the format defined in [RFC3966], e.g., 'tel:+1-201-555-0123'. Service providers SHOULD canonicalize the value according to [RFC3966] format, when appropriate. The display sub-attribute MAY be used to return the canonicalized representation of the phone number value. The sub-attribute type often has typical values of work, home, mobile, fax, pager, and other and MAY allow more types to be defined by the SCIM clients.

ims

Instant messaging address for the user. No official canonicalization rules exist for all instant messaging addresses, but service providers SHOULD, when appropriate, remove all whitespace and convert the address to lowercase. The type sub-attribute SHOULD take one of the following values: aim, gtalk, icq, xmpp, msn, skype, qq, yahoo, or other (representing currently popular IM services at the time of this writing). Service providers MAY add further values if new IM services are introduced and MAY specify more detailed canonicalization rules for each possible value.

photos

A URI that is a uniform resource locator (as defined in Section 1.1.3 of [RFC3986]) that points to a resource location representing the user's image. The resource MUST be a file (e.g., a GIF, JPEG, or PNG image file) rather than a web page containing an image. Service providers MAY return the same image in different sizes, although it is recognized that no standard for describing images of various sizes currently exists. Note that this attribute SHOULD NOT be used to send down arbitrary photos taken by this user; instead, profile photos of the user that are suitable for display when describing the user should be sent. Instead of the standard canonical values for type, this attribute defines the following canonical values to represent popular photo sizes: photo and thumbnail.

addresses

A physical mailing address for this user. Canonical type values of work, home, and other. This attribute is a complex type with the following sub-attributes. All sub-attributes are OPTIONAL.

  • formatted: The full mailing address, formatted for display or use with a mailing label. This attribute MAY contain newlines.
  • streetAddress: The full street address component, which may include house number, street name, P.O. box, and multi-line extended street address information. This attribute MAY contain newlines.
  • locality: The city or locality component.
  • region: The state or region component.
  • postalCode: The zip code or postal code component.
  • country: The country name component. When specified, the value MUST be in ISO 3166-1 "alpha-2" code format [ISO3166]; e.g., the United States and Sweden are "US" and "SE", respectively.

groups

A list of groups to which the user belongs, either through direct membership, through nested groups, or dynamically calculated. The values are meant to enable expression of common group-based or role-based access control models, although no explicit authorization model is defined. It is intended that the semantics of group membership and any behavior or authorization granted as a result of membership are defined by the service provider. The canonical types direct and indirect are defined to describe how the group membership was derived. Direct group membership indicates that the user is directly associated with the group and SHOULD indicate that clients may modify membership through the "Group" resource. Indirect membership indicates that user membership is transitive or dynamic and implies that clients cannot modify indirect group membership through the "Group" resource but MAY modify direct group membership through the "Group" resource, which may influence indirect memberships. If the SCIM service provider exposes a "Group" resource, the "value" sub-attribute MUST be the "id", and the "$ref" sub-attribute must be the URI of the corresponding "Group" resources to which the user belongs. Since this attribute has a mutability of "readOnly", group membership changes MUST be applied via the "Group" Resource (Section 4.2). This attribute has a mutability of "readOnly".

entitlements

A list of entitlements for the user that represent a thing the user has. An entitlement may be an additional right to a thing, object, or service. No vocabulary or syntax is specified; service providers and clients are expected to encode sufficient information in the value so as to accurately and without ambiguity determine what the user has access to. This value has no canonical types, although a type may be useful as a means to scope entitlements.

roles

A list of roles for the user that collectively represent who the user is, e.g., "Student", "Faculty". No vocabulary or syntax is specified, although it is expected that a role value is a String or label representing a collection of entitlements. This value has no canonical types.

x509Certificates

A list of certificates associated with the resource (e.g., a User). Each value contains exactly one DER-encoded X.509 certificate (see Section 4 of [RFC5280]), which MUST be base64 encoded per Section 4 of [RFC4648]. A single value MUST NOT contain multiple certificates and so does not contain the encoding "SEQUENCE OF Certificate" in any guise.


4.2. "Group" Resource Schema ๐Ÿซถ

SCIM provides a schema for representing groups, identified using the following schema URI: "urn:ietf:params:scim:schemas:core:2.0:Group".

"Group" resources are meant to enable expression of common group-based or role-based access control models, although no explicit authorization model is defined. It is intended that the semantics of group membership, and any behavior or authorization granted as a result of membership, are defined by the service provider; these are considered out of scope for this specification.

The following singular attribute is defined in addition to the common attributes defined in the SCIM core schema:

  • displayName: A human-readable name for the Group. REQUIRED.

The following multi-valued attribute is defined in addition to the common attributes defined in the SCIM core schema:

  • members: A list of members of the Group. While values MAY be added or removed, sub-attributes of members are "immutable". The "value" sub-attribute contains the value of an "id" attribute of a SCIM resource, and the "$ref" sub-attribute must be the URI of a SCIM resource such as a "User", or a "Group". The intention of the "Group" type is to allow the service provider to support nested groups. Service providers MAY require clients to provide a non-empty value by setting the "required" attribute characteristic of a sub-attribute of the "members" attribute in the "Group" resource schema.

4.3. Enterprise User Schema Extension ๐ŸŒˆ

The following SCIM extension defines attributes commonly used in representing users that belong to, or act on behalf of, a business or enterprise. The enterprise User extension is identified using the following schema URI: "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User".

The following singular attributes are defined:

  • employeeNumber: A string identifier, typically numeric or alphanumeric, assigned to a person, typically based on order of hire or association with an organization.
  • costCenter: Identifies the name of a cost center.
  • organization: Identifies the name of an organization.
  • division: Identifies the name of a division.
  • department: Identifies the name of a department.
  • manager: The user's manager. A complex type that optionally allows service providers to represent organizational hierarchy by referencing the "id" attribute of another User.
    • value: The "id" of the SCIM resource representing the user's manager. RECOMMENDED.
    • $ref: The URI of the SCIM resource representing the User's manager. RECOMMENDED.
    • displayName: The displayName of the user's manager. This attribute is OPTIONAL, and mutability is "readOnly".

5. Service Provider Configuration Schema โœจ

okay so SCIM has a schema for the service provider's configuration, and it's identified by urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig ๐ŸŽ€

The service provider configuration resource is how a service provider lets clients discover SCIM features in a standardized way, plus it shares extra implementation details ๐Ÿ’… All attributes have a mutability of readOnly. Unlike other core resources, the id attribute is not required here ๐Ÿ™ˆ

These singular attributes are defined on top of the common attributes from the core schema:

  • documentationUri: an HTTP-addressable URL pointing to the service provider's human-consumable help documentation. OPTIONAL.
  • patch: a complex type that specifies PATCH configuration options. REQUIRED. See Section 3.5.2 of [RFC7644].
    • supported: a Boolean value specifying whether or not the operation is supported. REQUIRED.
  • bulk: a complex type that specifies bulk configuration options. See Section 3.7 of [RFC7644]. REQUIRED.
    • supported: a Boolean value specifying whether or not the operation is supported. REQUIRED.
    • maxOperations: an integer value specifying the maximum number of operations. REQUIRED.
    • maxPayloadSize: an integer value specifying the maximum payload size in bytes. REQUIRED.
  • filter: a complex type that specifies FILTER options. REQUIRED. See Section 3.4.2.2 of [RFC7644].
    • supported: a Boolean value specifying whether or not the operation is supported. REQUIRED.
    • maxResults: an integer value specifying the maximum number of resources returned in a response. REQUIRED.
  • changePassword: a complex type that specifies configuration options related to changing a password. REQUIRED.
    • supported: a Boolean value specifying whether or not the operation is supported. REQUIRED.
  • sort: a complex type that specifies Sort configuration options. REQUIRED.
    • supported: a Boolean value specifying whether or not sorting is supported. REQUIRED.
  • etag: a complex type that specifies ETag configuration options. REQUIRED.
    • supported: a Boolean value specifying whether or not the operation is supported. REQUIRED.

This multi-valued attribute is also defined on top of the common attributes from the core schema:

  • authenticationSchemes: a multi-valued complex type that specifies supported authentication scheme properties. To enable seamless discovery of configurations, the service provider SHOULD, with the appropriate security considerations, make the authenticationSchemes attribute publicly accessible without prior authentication. REQUIRED. The following sub-attributes are defined:
    • type: the authentication scheme. This specification defines the values "oauth", "oauth2", "oauthbearertoken", "httpbasic", and "httpdigest". REQUIRED.
    • name: the common authentication scheme name, e.g., HTTP Basic. REQUIRED.
    • description: a description of the authentication scheme. REQUIRED.
    • specUri: an HTTP-addressable URL pointing to the authentication scheme's specification. OPTIONAL.
    • documentationUri: an HTTP-addressable URL pointing to the authentication scheme's usage documentation. OPTIONAL.

6. ResourceType Schema

the ResourceType schema is where the metadata about a resource type lives ๐Ÿฆ‹ Resource type resources are READ-ONLY and identified using urn:ietf:params:scim:schemas:core:2.0:ResourceType. Unlike other core resources, all attributes are REQUIRED unless otherwise specified ๐Ÿ˜ญ The id attribute is not required for the resource type resource either.

These singular attributes are defined:

  • id: the resource type's server unique id. This is often the same value as the name attribute. OPTIONAL.
  • name: the resource type name. When applicable, service providers MUST specify the name, e.g., "User" or "Group". This name is referenced by the meta.resourceType attribute in all resources. REQUIRED.
  • description: the resource type's human-readable description. When applicable, service providers MUST specify the description. OPTIONAL.
  • endpoint: the resource type's HTTP-addressable endpoint relative to the Base URL of the service provider, e.g., "Users". REQUIRED.
  • schema: the resource type's primary/base schema URI, e.g., "urn:ietf:params:scim:schemas:core:2.0:User". This MUST be equal to the id attribute of the associated Schema resource. REQUIRED.
  • schemaExtensions: a list of URIs of the resource type's schema extensions. OPTIONAL.
    • schema: the URI of an extended schema, e.g., "urn:edu:2.0:Staff". This MUST be equal to the id attribute of a Schema resource. REQUIRED.
    • required: a Boolean value that specifies whether or not the schema extension is required for the resource type. If true, a resource of this type MUST include this schema extension and also include any attributes declared as required in this schema extension. If false, a resource of this type MAY omit this schema extension. REQUIRED.

7. Schema Definition โœจ

okay bestie, this section is all about how a SCIM service provider describes the schemas it uses ๐ŸŽ€ For every "schemas" URI value, the schema spells out the defined attribute(s) and their characteristics (mutability, returnability, etc.) ๐Ÿ’… Every schema URI used in a resource object gets a matching "Schema" resource. "Schema" resources are not modifiable, and their attributes have a mutability of "readOnly" ๐Ÿ”’ Except for "id" (which is always returned), every attribute has a "returned" characteristic of "default". Unless otherwise specified, all schema attributes are case insensitive ๐Ÿซถ These resources have a "schemas" attribute with this schema URI:

urn:ietf:params:scim:schemas:core:2.0:Schema

Unlike the other core resources, the "Schema" resource MAY contain a complex object within a sub-attribute, and all attributes are REQUIRED unless otherwise specified ๐Ÿงš

The following singular attributes are defined:

id ๐Ÿ†” The unique URI of the schema. When applicable, service providers MUST specify the URI, e.g., "urn:ietf:params:scim:schemas:core:2.0:User". Unlike most other schemas, which use some sort of Globally Unique Identifier (GUID) for the "id", the schema "id" is a URI so that it can be registered and is portable between different service providers and clients. REQUIRED.

name ๐Ÿท๏ธ The schema's human-readable name. When applicable, service providers MUST specify the name, e.g., "User" or "Group". OPTIONAL.

description ๐Ÿ“ The schema's human-readable description. When applicable, service providers MUST specify the description. OPTIONAL.

The following multi-valued attribute is defined:

attributes ๐ŸŒˆ A complex type that defines service provider attributes and their qualities via the following set of sub-attributes:

  • name: The attribute's name.
  • type: The attribute's data type. Valid values are "string", "boolean", "decimal", "integer", "dateTime", "reference", and "complex". When an attribute is of type "complex", there SHOULD be a corresponding schema attribute "subAttributes" defined, listing the sub-attributes of the attribute.
  • subAttributes: When an attribute is of type "complex", "subAttributes" defines a set of sub-attributes. "subAttributes" has the same schema sub-attributes as "attributes".
  • multiValued: A Boolean value indicating the attribute's plurality.
  • description: The attribute's human-readable description. When applicable, service providers MUST specify the description.
  • required: A Boolean value that specifies whether or not the attribute is required.
  • canonicalValues: A collection of suggested canonical values that MAY be used (e.g., "work" and "home"). In some cases, service providers MAY choose to ignore unsupported values. OPTIONAL.
  • caseExact: A Boolean value that specifies whether or not a string attribute is case sensitive. The server SHALL use case sensitivity when evaluating filters. For attributes that are case exact, the server SHALL preserve case for any value submitted. If the attribute is case insensitive, the server MAY alter case for a submitted value. Case sensitivity also impacts how attribute values MAY be compared against filter values (see Section 3.4.2.2 of [RFC7644]).
  • mutability: A single keyword indicating the circumstances under which the value of the attribute can be (re)defined:
    • readOnly: The attribute SHALL NOT be modified.
    • readWrite: The attribute MAY be updated and read at any time. This is the default value.
    • immutable: The attribute MAY be defined at resource creation (e.g., POST) or at record replacement via a request (e.g., a PUT). The attribute SHALL NOT be updated.
    • writeOnly: The attribute MAY be updated at any time. Attribute values SHALL NOT be returned (e.g., because the value is a stored hash). Note: An attribute with a mutability of "writeOnly" usually also has a returned setting of "never".
  • returned: A single keyword that indicates when an attribute and associated values are returned in response to a GET request or in response to a PUT, POST, or PATCH request. Valid keywords are as follows:
    • always: The attribute is always returned, regardless of the contents of the "attributes" parameter. For example, "id" is always returned to identify a SCIM resource.
    • never: The attribute is never returned. This may occur because the original attribute value (e.g., a hashed value) is not retained by the service provider. A service provider MAY allow attributes to be used in a search filter.
    • default: The attribute is returned by default in all SCIM operation responses where attribute values are returned. If the GET request "attributes" parameter is specified, attribute values are only returned if the attribute is named in the "attributes" parameter. DEFAULT.
    • request: The attribute is returned in response to any PUT, POST, or PATCH operations if the attribute was specified by the client (for example, the attribute was modified). The attribute is returned in a SCIM query operation only if specified in the "attributes" parameter.
  • uniqueness: A single keyword value that specifies how the service provider enforces uniqueness of attribute values. A server MAY reject an invalid value based on uniqueness by returning HTTP response code 400 (Bad Request). A client MAY enforce uniqueness on the client side to a greater degree than the service provider enforces. For example, a client could make a value unique while the server has uniqueness of "none". Valid keywords are as follows:
    • none: The values are not intended to be unique in any way. DEFAULT.
    • server: The value SHOULD be unique within the context of the current SCIM endpoint (or tenancy) and MAY be globally unique (e.g., a "username", email address, or other server-generated key or counter). No two resources on the same server SHOULD possess the same value.
    • global: The value SHOULD be globally unique (e.g., an email address, a GUID, or other value). No two resources on any server SHOULD possess the same value.
  • referenceTypes: A multi-valued array of JSON strings that indicate the SCIM resource types that may be referenced. Valid values are as follows:
    • A SCIM resource type (e.g., "User" or "Group"),
    • "external" - indicating that the resource is an external resource (e.g., a photo), or
    • "uri" - indicating that the reference is to a service endpoint or an identifier (e.g., a schema URN).

This attribute is only applicable for attributes that are of type "reference" (Section 2.3.7).


8. JSON Representation ๐Ÿ“

8.1. Minimal User Representation

The following is a non-normative example of the minimal required SCIM representation in JSON format ๐Ÿ’–

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "id": "2819c223-7f76-453a-919d-413861904646",
  "userName": "bjensen@example.com",
  "meta": {
    "resourceType": "User",
    "created": "2010-01-23T04:56:22Z",
    "lastModified": "2011-05-13T04:42:34Z",
    "version": "W\/\"3694e05e9dff590\"",
    "location":
     "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646"
  }
}

Figure 3: Example Minimal User JSON Representation โœจ

8.2. Full User Representation

The following is a non-normative example of the fully populated SCIM representation in JSON format ๐ŸŒธ

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "id": "2819c223-7f76-453a-919d-413861904646",
  "externalId": "701984",
  "userName": "bjensen@example.com",
  "name": {
    "formatted": "Ms. Barbara J Jensen, III",
    "familyName": "Jensen",
    "givenName": "Barbara",
    "middleName": "Jane",
    "honorificPrefix": "Ms.",
    "honorificSuffix": "III"
  },
  "displayName": "Babs Jensen",
  "nickName": "Babs",
  "profileUrl": "https://login.example.com/bjensen",
  "emails": [
    {
      "value": "bjensen@example.com",
      "type": "work",
      "primary": true
    },
    {
      "value": "babs@jensen.org",
      "type": "home"
    }
  ],
  "addresses": [
    {
      "type": "work",
      "streetAddress": "100 Universal City Plaza",
      "locality": "Hollywood",
      "region": "CA",
      "postalCode": "91608",
      "country": "USA",
      "formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
      "primary": true
    },
    {
      "type": "home",
      "streetAddress": "456 Hollywood Blvd",
      "locality": "Hollywood",
      "region": "CA",
      "postalCode": "91608",
      "country": "USA",
      "formatted": "456 Hollywood Blvd\nHollywood, CA 91608 USA"
    }
  ],
  "phoneNumbers": [
    {
      "value": "555-555-5555",
      "type": "work"
    },
    {
      "value": "555-555-4444",
      "type": "mobile"
    }
  ],
  "ims": [
    {
      "value": "someaimhandle",
      "type": "aim"
    }
  ],
  "photos": [
    {
      "value":
        "https://photos.example.com/profilephoto/72930000000Ccne/F",
      "type": "photo"
    },
    {
      "value":
        "https://photos.example.com/profilephoto/72930000000Ccne/T",
      "type": "thumbnail"
    }
  ],
  "userType": "Employee",
  "title": "Tour Guide",
  "preferredLanguage": "en-US",
  "locale": "en-US",
  "timezone": "America/Los_Angeles",
  "active":true,
  "password": "t1meMa$heen",
  "groups": [
    {
      "value": "e9e30dba-f08f-4109-8486-d5c6a331660a",
      "$ref":

"https://example.com/v2/Groups/71ddacd2-a8e7-49b8-a5db-ae50d0a5bfd7",
      "display": "US Employees"
    }
  ],
  "x509Certificates": [
    {
      "value":
       "MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMx
        EzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYD
        VQQDDAtleGFtcGxlLmNvbTAeFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFa
        MH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtl
        eGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBKZW5zZW4gSUlJMSIw
        IAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
        AQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc
        1FLgzdLI8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5i
        PSi8xO8SL7I7SDhcBVJhqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZ
        zidPl8HZ7DhXkZIRtJwBweq4bvm3hM1Os7UQH05ZS6cVDgweKNwdLLrT51ikSQG3
        DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z9QiwlYEdRbLJ4zJQBmDr
        SGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sweTAJBgNV
        HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp
        Y2F0ZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAU
        dGeKitcaF7gnzsNwDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJt
        Ng5Tcq+/ByEDrBgnusx0jloUhByPMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1R
        C4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTVvxB/A67g42/vzgAtoRUeDov1
        +GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo="
    }
  ],
  "meta": {
    "resourceType": "User",
    "created": "2010-01-23T04:56:22Z",
    "lastModified": "2011-05-13T04:42:34Z",
    "version": "W\/\"a330bc54f0671c9\"",
    "location":
"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646"
  }
}

Figure 4: Example Full User JSON Representation

8.3. Enterprise User Extension Representation โœจ

okay bestie, this one is the fully loaded User with the enterprise extension stacked on top ๐Ÿ’… it's a non-normative example, so think of it as a vibe check, not a rulebook ๐ŸŽ€

{
  "schemas":
    ["urn:ietf:params:scim:schemas:core:2.0:User",
      "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
  "id": "2819c223-7f76-453a-919d-413861904646",
  "externalId": "701984",
  "userName": "bjensen@example.com",
  "name": {
    "formatted": "Ms. Barbara J Jensen, III",
    "familyName": "Jensen",
    "givenName": "Barbara",
    "middleName": "Jane",
    "honorificPrefix": "Ms.",
    "honorificSuffix": "III"
  },
  "displayName": "Babs Jensen",
  "nickName": "Babs",
  "profileUrl": "https://login.example.com/bjensen",
  "emails": [
    {
      "value": "bjensen@example.com",
      "type": "work",
      "primary": true
    },
    {
      "value": "babs@jensen.org",
      "type": "home"
    }
  ],
  "addresses": [
    {
      "streetAddress": "100 Universal City Plaza",
      "locality": "Hollywood",
      "region": "CA",
      "postalCode": "91608",
      "country": "USA",
      "formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
      "type": "work",
      "primary": true
    },
    {
      "streetAddress": "456 Hollywood Blvd",
      "locality": "Hollywood",
      "region": "CA",
      "postalCode": "91608",
      "country": "USA",
      "formatted": "456 Hollywood Blvd\nHollywood, CA 91608 USA",
      "type": "home"
     }
  ],
  "phoneNumbers": [
    {
      "value": "555-555-5555",
      "type": "work"
    },
    {
      "value": "555-555-4444",
      "type": "mobile"
    }
  ],
  "ims": [
    {
      "value": "someaimhandle",
      "type": "aim"
    }
  ],
  "photos": [
    {
      "value":
        "https://photos.example.com/profilephoto/72930000000Ccne/F",
      "type": "photo"
    },
    {
      "value":
        "https://photos.example.com/profilephoto/72930000000Ccne/T",
      "type": "thumbnail"
    }
  ],
  "userType": "Employee",
  "title": "Tour Guide",
  "preferredLanguage": "en-US",
  "locale": "en-US",
  "timezone": "America/Los_Angeles",
  "active":true,
  "password": "t1meMa$heen",
  "groups": [
    {
      "value": "e9e30dba-f08f-4109-8486-d5c6a331660a",
      "$ref": "../Groups/e9e30dba-f08f-4109-8486-d5c6a331660a",
      "display": "Tour Guides"
    },
    {
      "value": "fc348aa8-3835-40eb-a20b-c726e15c55b5",
      "$ref": "../Groups/fc348aa8-3835-40eb-a20b-c726e15c55b5",
      "display": "Employees"
    },
    {
      "value": "71ddacd2-a8e7-49b8-a5db-ae50d0a5bfd7",
      "$ref": "../Groups/71ddacd2-a8e7-49b8-a5db-ae50d0a5bfd7",
      "display": "US Employees"
    }
  ],
  "x509Certificates": [
    {
      "value":
       "MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMx
        EzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYD
        VQQDDAtleGFtcGxlLmNvbTAeFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFa
        MH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtl
        eGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBKZW5zZW4gSUlJMSIw
        IAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
        AQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc
        1FLgzdLI8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5i
        PSi8xO8SL7I7SDhcBVJhqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZ
        zidPl8HZ7DhXkZIRtJwBweq4bvm3hM1Os7UQH05ZS6cVDgweKNwdLLrT51ikSQG3
        DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z9QiwlYEdRbLJ4zJQBmDr
        SGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sweTAJBgNV
        HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp
        Y2F0ZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAU
        dGeKitcaF7gnzsNwDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJt
        Ng5Tcq+/ByEDrBgnusx0jloUhByPMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1R
        C4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTVvxB/A67g42/vzgAtoRUeDov1
        +GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo="
    }
  ],
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "employeeNumber": "701984",
    "costCenter": "4130",
    "organization": "Universal Studios",
    "division": "Theme Park",
    "department": "Tour Operations",
    "manager": {
      "value": "26118915-6090-4610-87e4-49d8ca9f808d",
      "$ref": "../Users/26118915-6090-4610-87e4-49d8ca9f808d",
      "displayName": "John Smith"
    }
  },
  "meta": {
    "resourceType": "User",
    "created": "2010-01-23T04:56:22Z",
    "lastModified": "2011-05-13T04:42:34Z",
    "version": "W\/\"3694e05e9dff591\"",
    "location":
"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646"
  }
}

Figure 5: Example Enterprise User JSON Representation

8.4. Group Representation ๐Ÿงš

this is the non-normative group example, the Tour Guides squad ๐ŸŽ€

   {
     "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
     "id": "e9e30dba-f08f-4109-8486-d5c6a331660a",
     "displayName": "Tour Guides",
     "members": [
       {
         "value": "2819c223-7f76-453a-919d-413861904646",
         "$ref":
   "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
         "display": "Babs Jensen"
       },
       {
         "value": "902c246b-6245-4190-8e05-00816be7344a",
         "$ref":
   "https://example.com/v2/Users/902c246b-6245-4190-8e05-00816be7344a",
         "display": "Mandy Pepperidge"
       }
     ],
     "meta": {
       "resourceType": "Group",
       "created": "2010-01-23T04:56:22Z",
       "lastModified": "2011-05-13T04:42:34Z",
       "version": "W\/\"3694e05e9dff592\"",
       "location":
   "https://example.com/v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a"
     }
   }

Figure 6: Example Group JSON Representation

8.5. Service Provider Configuration Representation ๐Ÿฆ‹

non-normative example of the SCIM service provider configuration, so you can see what a server is "giving" ๐Ÿ’…

  {
    "schemas":
      ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"],
    "documentationUri": "http://example.com/help/scim.html",
    "patch": {
      "supported":true
    },
    "bulk": {
      "supported":true,
      "maxOperations":1000,
      "maxPayloadSize":1048576
    },
    "filter": {
      "supported":true,
      "maxResults": 200
    },
    "changePassword": {
      "supported":true
    },
    "sort": {
      "supported":true
    },
    "etag": {
      "supported":true
    },
    "authenticationSchemes": [
      {
        "name": "OAuth Bearer Token",
        "description":
          "Authentication scheme using the OAuth Bearer Token Standard",
        "specUri": "http://www.rfc-editor.org/info/rfc6750",
        "documentationUri": "http://example.com/help/oauth.html",
        "type": "oauthbearertoken",
        "primary": true
      },
      {
        "name": "HTTP Basic",
        "description":
          "Authentication scheme using the HTTP Basic Standard",
        "specUri": "http://www.rfc-editor.org/info/rfc2617",
        "documentationUri": "http://example.com/help/httpBasic.html",
        "type": "httpbasic"
       }
    ],
    "meta": {
      "location": "https://example.com/v2/ServiceProviderConfig",
      "resourceType": "ServiceProviderConfig",
      "created": "2010-01-23T04:56:22Z",
      "lastModified": "2011-05-13T04:42:34Z",
      "version": "W\/\"3694e05e9dff594\""
    }
  }

Figure 7: Example Service Provider Configuration JSON Representation

8.6. Resource Type Representation ๐ŸŒธ

here are the SCIM resource types in JSON, non-normative, so again just a vibe โœจ

   [{
     "schemas": ["urn:ietf:params:scim:schemas:core:2.0:ResourceType"],
     "id": "User",
     "name": "User",
     "endpoint": "/Users",
     "description": "User Account",
     "schema": "urn:ietf:params:scim:schemas:core:2.0:User",
     "schemaExtensions": [
       {
         "schema":
           "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
         "required": true
       }
     ],
     "meta": {
       "location": "https://example.com/v2/ResourceTypes/User",
       "resourceType": "ResourceType"
     }
    },
    {
     "schemas": ["urn:ietf:params:scim:schemas:core:2.0:ResourceType"],
     "id": "Group",
     "name": "Group",
     "endpoint": "/Groups",
     "description": "Group",
     "schema": "urn:ietf:params:scim:schemas:core:2.0:Group",
     "meta": {
       "location": "https://example.com/v2/ResourceTypes/Group",
       "resourceType": "ResourceType"
     }
   }]

Figure 8: Example Resource Type JSON Representation

8.7. Schema Representation ๐Ÿง 

okay so these sections show schemas for both SCIM resources and service provider schemas ๐Ÿ’– heads up, the JSON got reformatted so it's easier to read and fits the spec layout, so don't panic if the spacing looks a little different ๐Ÿซถ

8.7.1. Resource Schema Representation ๐Ÿ’œ

this one is an example of the SCIM schema in JSON for SCIM resources. Individual values and the schema MAY change where that's permitted โœจ it covers "User", "Group", and "EnterpriseUser", and other schema representations are possible ๐ŸŒˆ

[
  {
    "id" : "urn:ietf:params:scim:schemas:core:2.0:User",
    "name" : "User",
    "description" : "User Account",
    "attributes" : [
      {
        "name" : "userName",
        "type" : "string",
        "multiValued" : false,
        "description" : "Unique identifier for the User, typically
used by the user to directly authenticate to the service provider.
Each User MUST include a non-empty userName value.  This identifier
MUST be unique across the service provider's entire set of Users.
REQUIRED.",
        "required" : true,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "server"
      },
      {
        "name" : "name",
        "type" : "complex",
        "multiValued" : false,
        "description" : "The components of the user's real name.
Providers MAY return just the full name as a single string in the
formatted sub-attribute, or they MAY return just the individual

okay the name attribute is still serving, and then we get into the rest of the User schema ๐ŸŽ€๐Ÿ’–

component attributes using the other sub-attributes, or they MAY
return both.  If both variants are returned, they SHOULD be
describing the same name, with the formatted name indicating how the
component attributes should be combined.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "formatted",
            "type" : "string",
            "multiValued" : false,
            "description" : "The full name, including all middle
names, titles, and suffixes as appropriate, formatted for display
(e.g., 'Ms. Barbara J Jensen, III').",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "familyName",
            "type" : "string",
            "multiValued" : false,
            "description" : "The family name of the User, or
last name in most Western languages (e.g., 'Jensen' given the full
name 'Ms. Barbara J Jensen, III').",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "givenName",
            "type" : "string",
            "multiValued" : false,
            "description" : "The given name of the User, or
first name in most Western languages (e.g., 'Barbara' given the
full name 'Ms. Barbara J Jensen, III').",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "middleName",
            "type" : "string",
            "multiValued" : false,
            "description" : "The middle name(s) of the User
(e.g., 'Jane' given the full name 'Ms. Barbara J Jensen, III').",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "honorificPrefix",
            "type" : "string",
            "multiValued" : false,
            "description" : "The honorific prefix(es) of the User, or
title in most Western languages (e.g., 'Ms.' given the full name
'Ms. Barbara J Jensen, III').",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "honorificSuffix",
            "type" : "string",
            "multiValued" : false,
            "description" : "The honorific suffix(es) of the User, or
suffix in most Western languages (e.g., 'III' given the full name
'Ms. Barbara J Jensen, III').",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          }
        ],
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "displayName",
        "type" : "string",
        "multiValued" : false,
        "description" : "The name of the User, suitable for display
to end-users.  The name SHOULD be the full name of the User being
described, if known.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "nickName",
        "type" : "string",
        "multiValued" : false,
        "description" : "The casual way to address the user in real
life, e.g., 'Bob' or 'Bobby' instead of 'Robert'.  This attribute
SHOULD NOT be used to represent a User's username (e.g., 'bjensen' or
'mpepperidge').",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "profileUrl",
        "type" : "reference",
        "referenceTypes" : ["external"],
        "multiValued" : false,
        "description" : "A fully qualified URL pointing to a page
representing the User's online profile.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "title",
        "type" : "string",
        "multiValued" : false,
        "description" : "The user's title, such as
\"Vice President.\"",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "userType",
        "type" : "string",
        "multiValued" : false,
        "description" : "Used to identify the relationship between
the organization and the user.  Typical values used might be
'Contractor', 'Employee', 'Intern', 'Temp', 'External', and
'Unknown', but any value may be used.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "preferredLanguage",
        "type" : "string",
        "multiValued" : false,
        "description" : "Indicates the User's preferred written or
spoken language.  Generally used for selecting a localized user
interface; e.g., 'en_US' specifies the language English and country
US.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "locale",
        "type" : "string",
        "multiValued" : false,
        "description" : "Used to indicate the User's default location
for purposes of localizing items such as currency, date time format, or
numerical representations.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "timezone",
        "type" : "string",
        "multiValued" : false,
        "description" : "The User's time zone in the 'Olson' time zone
database format, e.g., 'America/Los_Angeles'.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "active",
        "type" : "boolean",
        "multiValued" : false,
        "description" : "A Boolean value indicating the User's
administrative status.",
        "required" : false,
        "mutability" : "readWrite",
        "returned" : "default"
      },
      {
        "name" : "password",
        "type" : "string",
        "multiValued" : false,
        "description" : "The User's cleartext password.  This
attribute is intended to be used as a means to specify an initial
password when creating a new User or to reset an existing User's
password.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "writeOnly",
        "returned" : "never",
        "uniqueness" : "none"
      },
      {
        "name" : "emails",
        "type" : "complex",
        "multiValued" : true,
        "description" : "Email addresses for the user.  The value
SHOULD be canonicalized by the service provider, e.g.,
'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'.
Canonical type values of 'work', 'home', and 'other'.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "value",
            "type" : "string",
            "multiValued" : false,
            "description" : "Email addresses for the user.  The value
SHOULD be canonicalized by the service provider, e.g.,
'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'.
Canonical type values of 'work', 'home', and 'other'.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "display",
            "type" : "string",
            "multiValued" : false,
            "description" : "A human-readable name, primarily used
for display purposes.  READ-ONLY.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "A label indicating the attribute's
function, e.g., 'work' or 'home'.",
            "required" : false,
            "caseExact" : false,
            "canonicalValues" : [
              "work",
              "home",
              "other"
            ],
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "primary",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value indicating the 'primary'
or preferred attribute value for this attribute, e.g., the preferred
mailing address or primary email address.  The primary attribute
value 'true' MUST appear no more than once.",
            "required" : false,
            "mutability" : "readWrite",
            "returned" : "default"
          }
        ],
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "phoneNumbers",
        "type" : "complex",
        "multiValued" : true,
        "description" : "Phone numbers for the User.  The value
SHOULD be canonicalized by the service provider according to the
format specified in RFC 3966, e.g., 'tel:+1-201-555-0123'.
Canonical type values of 'work', 'home', 'mobile', 'fax', 'pager',
and 'other'.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "value",
            "type" : "string",
            "multiValued" : false,
            "description" : "Phone number of the User.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "display",
            "type" : "string",
            "multiValued" : false,
            "description" : "A human-readable name, primarily used
for display purposes.  READ-ONLY.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "A label indicating the attribute's
function, e.g., 'work', 'home', 'mobile'.",
            "required" : false,
            "caseExact" : false,
            "canonicalValues" : [
              "work",
              "home",
              "mobile",
              "fax",
              "pager",
              "other"
            ],
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "primary",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value indicating the 'primary'
or preferred attribute value for this attribute, e.g., the preferred
phone number or primary phone number.  The primary attribute value

okay so we're still deep in the User schema and it's giving lots of attributes ๐Ÿงš ngl the ims, photos, addresses, groups and entitlements bits are where it gets extra spicy ๐Ÿ’…

'true' MUST appear no more than once.",
            "required" : false,
            "mutability" : "readWrite",
            "returned" : "default"
          }
        ],
        "mutability" : "readWrite",
        "returned" : "default"
      },
      {
        "name" : "ims",
        "type" : "complex",
        "multiValued" : true,
        "description" : "Instant messaging addresses for the User.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "value",
            "type" : "string",
            "multiValued" : false,
            "description" : "Instant messaging address for the User.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "display",
            "type" : "string",
            "multiValued" : false,
            "description" : "A human-readable name, primarily used
for display purposes.  READ-ONLY.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "A label indicating the attribute's
function, e.g., 'aim', 'gtalk', 'xmpp'.",
            "required" : false,
            "caseExact" : false,
            "canonicalValues" : [
              "aim",
              "gtalk",
              "icq",
              "xmpp",
              "msn",
              "skype",
              "qq",
              "yahoo"
            ],
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "primary",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value indicating the 'primary'
or preferred attribute value for this attribute, e.g., the preferred
messenger or primary messenger.  The primary attribute value 'true'
MUST appear no more than once.",
            "required" : false,
            "mutability" : "readWrite",
            "returned" : "default"
          }
        ],
        "mutability" : "readWrite",
        "returned" : "default"
      },
      {
        "name" : "photos",
        "type" : "complex",
        "multiValued" : true,
        "description" : "URLs of photos of the User.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "value",
            "type" : "reference",
            "referenceTypes" : ["external"],
            "multiValued" : false,
            "description" : "URL of a photo of the User.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "display",
            "type" : "string",
            "multiValued" : false,
            "description" : "A human-readable name, primarily used
for display purposes.  READ-ONLY.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "A label indicating the attribute's
function, i.e., 'photo' or 'thumbnail'.",
            "required" : false,
            "caseExact" : false,
            "canonicalValues" : [
              "photo",
              "thumbnail"
            ],
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "primary",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value indicating the 'primary'
or preferred attribute value for this attribute, e.g., the preferred
photo or thumbnail.  The primary attribute value 'true' MUST appear
no more than once.",
            "required" : false,
            "mutability" : "readWrite",
            "returned" : "default"
          }
        ],
        "mutability" : "readWrite",
        "returned" : "default"
      },
      {
        "name" : "addresses",
        "type" : "complex",
        "multiValued" : true,
        "description" : "A physical mailing address for this User.
Canonical type values of 'work', 'home', and 'other'.  This attribute
is a complex type with the following sub-attributes.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "formatted",
            "type" : "string",
            "multiValued" : false,
            "description" : "The full mailing address, formatted for
display or use with a mailing label.  This attribute MAY contain
newlines.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "streetAddress",
            "type" : "string",
            "multiValued" : false,
            "description" : "The full street address component,
which may include house number, street name, P.O. box, and multi-line
extended street address information.  This attribute MAY contain
newlines.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "locality",
            "type" : "string",
            "multiValued" : false,
            "description" : "The city or locality component.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "region",
            "type" : "string",
            "multiValued" : false,
            "description" : "The state or region component.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "postalCode",
            "type" : "string",
            "multiValued" : false,
            "description" : "The zip code or postal code component.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "country",
            "type" : "string",
            "multiValued" : false,
            "description" : "The country name component.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "A label indicating the attribute's
function, e.g., 'work' or 'home'.",
            "required" : false,
            "caseExact" : false,
            "canonicalValues" : [
              "work",
              "home",
              "other"
            ],
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          }
        ],
        "mutability" : "readWrite",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "groups",
        "type" : "complex",
        "multiValued" : true,
        "description" : "A list of groups to which the user belongs,
either through direct membership, through nested groups, or
dynamically calculated.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "value",
            "type" : "string",
            "multiValued" : false,
            "description" : "The identifier of the User's group.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "$ref",
            "type" : "reference",
            "referenceTypes" : [
              "User",
              "Group"
            ],
            "multiValued" : false,
            "description" : "The URI of the corresponding 'Group'
resource to which the user belongs.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "display",
            "type" : "string",
            "multiValued" : false,
            "description" : "A human-readable name, primarily used
for display purposes.  READ-ONLY.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "A label indicating the attribute's
function, e.g., 'direct' or 'indirect'.",
            "required" : false,
            "caseExact" : false,
            "canonicalValues" : [
              "direct",
              "indirect"
            ],
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          }
        ],
        "mutability" : "readOnly",
        "returned" : "default"
      },
      {
        "name" : "entitlements",
        "type" : "complex",
        "multiValued" : true,
        "description" : "A list of entitlements for the User that
represent a thing the User has.",
        "required" : false,
        "subAttributes" : [
          {
            "name" : "value",
            "type" : "string",
            "multiValued" : false,
            "description" : "The value of an entitlement.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "display",
            "type" : "string",
            "multiValued" : false,
            "description" : "A human-readable name, primarily used
for display purposes.  READ-ONLY.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "A label indicating the attribute's
function.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readWrite",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "primary",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value indicating the 'primary'
or preferred attribute value for this attribute.  The primary

attribute value 'true' MUST appear no more than once.", "required" : false, "mutability" : "readWrite", "returned" : "default" } ], "mutability" : "readWrite", "returned" : "default" }, { "name" : "roles", "type" : "complex", "multiValued" : true, "description" : "A list of roles for the User that collectively represent who the User is, e.g., 'Student', 'Faculty'.", "required" : false, "subAttributes" : [ { "name" : "value", "type" : "string", "multiValued" : false, "description" : "The value of a role.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "display", "type" : "string", "multiValued" : false, "description" : "A human-readable name, primarily used for display purposes. READ-ONLY.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "type", "type" : "string", "multiValued" : false, "description" : "A label indicating the attribute's function.", "required" : false, "caseExact" : false, "canonicalValues" : [], "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "primary", "type" : "boolean", "multiValued" : false, "description" : "A Boolean value indicating the 'primary' or preferred attribute value for this attribute. The primary attribute value 'true' MUST appear no more than once.", "required" : false, "mutability" : "readWrite", "returned" : "default" } ], "mutability" : "readWrite", "returned" : "default" }, { "name" : "x509Certificates", "type" : "complex", "multiValued" : true, "description" : "A list of certificates issued to the User.", "required" : false, "caseExact" : false, "subAttributes" : [ { "name" : "value", "type" : "binary", "multiValued" : false, "description" : "The value of an X.509 certificate.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "display", "type" : "string", "multiValued" : false, "description" : "A human-readable name, primarily used for display purposes. READ-ONLY.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "type", "type" : "string", "multiValued" : false, "description" : "A label indicating the attribute's function.", "required" : false, "caseExact" : false, "canonicalValues" : [], "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "primary", "type" : "boolean", "multiValued" : false, "description" : "A Boolean value indicating the 'primary' or preferred attribute value for this attribute. The primary attribute value 'true' MUST appear no more than once.", "required" : false, "mutability" : "readWrite", "returned" : "default" } ], "mutability" : "readWrite", "returned" : "default" } ], "meta" : { "resourceType" : "Schema", "location" : "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User" } }, { "id" : "urn:ietf:params:scim:schemas:core:2.0:Group", "name" : "Group", "description" : "Group", "attributes" : [ { "name" : "displayName", "type" : "string", "multiValued" : false, "description" : "A human-readable name for the Group. REQUIRED.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "members", "type" : "complex", "multiValued" : true, "description" : "A list of members of the Group.", "required" : false, "subAttributes" : [ { "name" : "value", "type" : "string", "multiValued" : false, "description" : "Identifier of the member of this Group.", "required" : false, "caseExact" : false, "mutability" : "immutable", "returned" : "default", "uniqueness" : "none" }, { "name" : "$ref", "type" : "reference", "referenceTypes" : [ "User", "Group" ], "multiValued" : false, "description" : "The URI corresponding to a SCIM resource that is a member of this Group.", "required" : false, "caseExact" : false, "mutability" : "immutable", "returned" : "default", "uniqueness" : "none" }, { "name" : "type", "type" : "string", "multiValued" : false, "description" : "A label indicating the type of resource, e.g., 'User' or 'Group'.", "required" : false, "caseExact" : false, "canonicalValues" : [ "User", "Group" ], "mutability" : "immutable", "returned" : "default", "uniqueness" : "none" } ], "mutability" : "readWrite", "returned" : "default" } ], "meta" : { "resourceType" : "Schema", "location" : "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group" } }, { "id" : "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", "name" : "EnterpriseUser", "description" : "Enterprise User", "attributes" : [ { "name" : "employeeNumber", "type" : "string", "multiValued" : false, "description" : "Numeric or alphanumeric identifier assigned to a person, typically based on order of hire or association with an organization.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "costCenter", "type" : "string", "multiValued" : false, "description" : "Identifies the name of a cost center.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "organization", "type" : "string", "multiValued" : false, "description" : "Identifies the name of an organization.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "division", "type" : "string", "multiValued" : false, "description" : "Identifies the name of a division.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "department", "type" : "string", "multiValued" : false, "description" : "Identifies the name of a department.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "manager", "type" : "complex", "multiValued" : false, "description" : "The User's manager. A complex type that optionally allows service providers to represent organizational hierarchy by referencing the 'id' attribute of another User.", "required" : false, "subAttributes" : [ { "name" : "value", "type" : "string", "multiValued" : false, "description" : "The id of the SCIM resource representing the User's manager. REQUIRED.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "$ref", "type" : "reference", "referenceTypes" : [ "User" ], "multiValued" : false, "description" : "The URI of the SCIM resource representing the User's manager. REQUIRED.", "required" : false, "caseExact" : false, "mutability" : "readWrite", "returned" : "default", "uniqueness" : "none" }, { "name" : "displayName", "type" : "string", "multiValued" : false, "description" : "The displayName of the User's manager. OPTIONAL and READ-ONLY.", "required" : false, "caseExact" : false, "mutability" : "readOnly", "returned" : "default", "uniqueness" : "none" } ], "mutability" : "readWrite", "returned" : "default" } ], "meta" : { "resourceType" : "Schema", "location" : "/v2/Schemas/urn:ietf:params:scim:schemas:extension:enterprise:2.0:User" } } ]

Figure 9: Example JSON Representation for Resource Schema ๐ŸŽ€

8.7.2. Service Provider Schema Representation โœจ

Okay so now we're getting into the service provider stuff, bestie ๐Ÿ’… The next bit is a representation of the SCIM schema for the fixed service provider schemas: ServiceProviderConfig, ResourceType, and Schema. These are the ones that stay the same no matter what ๐Ÿซถ no cap, it's giving structure ๐Ÿ’–

okay bestie, we're picking up right where the schema layout left off ๐Ÿ’…โœจ this part is all about the service provider config and resource type schemas, so buckle up ๐ŸŽ€

  {
    "id" :
      "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",
    "name" : "Service Provider Configuration",
    "description" : "Schema for representing the service provider's
      configuration",
    "attributes" : [
      {
        "name" : "documentationUri",
        "type" : "reference",
        "referenceTypes" : ["external"],
        "multiValued" : false,
        "description" : "An HTTP-addressable URL pointing to the
          service provider's human-consumable help documentation.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "patch",
        "type" : "complex",
        "multiValued" : false,
        "description" : "A complex type that specifies PATCH
          configuration options.",
        "required" : true,
        "returned" : "default",
        "mutability" : "readOnly",
        "subAttributes" : [
          {
            "name" : "supported",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value specifying whether or not
              the operation is supported.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default"
          }
        ]
      },
      {
        "name" : "bulk",
        "type" : "complex",
        "multiValued" : false,
        "description" : "A complex type that specifies bulk
          configuration options.",
        "required" : true,
        "returned" : "default",
        "mutability" : "readOnly",
        "subAttributes" : [
          {
            "name" : "supported",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value specifying whether or not
              the operation is supported.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default"
          },
          {
            "name" : "maxOperations",
            "type" : "integer",
            "multiValued" : false,
            "description" : "An integer value specifying the maximum
              number of operations.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "maxPayloadSize",
            "type" : "integer",
            "multiValued" : false,
            "description" : "An integer value specifying the maximum
              payload size in bytes.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          }
        ]
      },
      {
        "name" : "filter",
        "type" : "complex",
        "multiValued" : false,
        "description" : "A complex type that specifies
          FILTER options.",
        "required" : true,
        "returned" : "default",
        "mutability" : "readOnly",
        "subAttributes" : [
          {
            "name" : "supported",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value specifying whether or not
              the operation is supported.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default"
          },
          {
            "name" : "maxResults",
            "type" : "integer",
            "multiValued" : false,
            "description" : "An integer value specifying the maximum
              number of resources returned in a response.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          }
        ]
      },
      {
        "name" : "changePassword",
        "type" : "complex",
        "multiValued" : false,
        "description" : "A complex type that specifies configuration
          options related to changing a password.",
        "required" : true,
        "returned" : "default",
        "mutability" : "readOnly",
        "subAttributes" : [
          {
            "name" : "supported",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value specifying whether or not
              the operation is supported.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default"
          }
        ]
      },
      {
        "name" : "sort",
        "type" : "complex",
        "multiValued" : false,
        "description" : "A complex type that specifies sort result
          options.",
        "required" : true,
        "returned" : "default",
        "mutability" : "readOnly",
        "subAttributes" : [
          {
            "name" : "supported",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value specifying whether or not
              the operation is supported.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default"
          }
        ]
      },
      {
        "name" : "authenticationSchemes",
        "type" : "complex",
        "multiValued" : true,
        "description" : "A complex type that specifies supported
          authentication scheme properties.",
        "required" : true,
        "returned" : "default",
        "mutability" : "readOnly",
        "subAttributes" : [
          {
            "name" : "name",
            "type" : "string",
            "multiValued" : false,
            "description" : "The common authentication scheme name,
              e.g., HTTP Basic.",
            "required" : true,
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "description",
            "type" : "string",
            "multiValued" : false,
            "description" : "A description of the authentication
              scheme.",
            "required" : true,
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "specUri",
            "type" : "reference",
            "referenceTypes" : ["external"],
            "multiValued" : false,
            "description" : "An HTTP-addressable URL pointing to the
              authentication scheme's specification.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "documentationUri",
            "type" : "reference",
            "referenceTypes" : ["external"],
            "multiValued" : false,
            "description" : "An HTTP-addressable URL pointing to the
              authentication scheme's usage documentation.",
            "required" : false,
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          }
        ]
      }
    ]
  },
  {
    "id" : "urn:ietf:params:scim:schemas:core:2.0:ResourceType",
    "name" : "ResourceType",
    "description" : "Specifies the schema that describes a SCIM
      resource type",
    "attributes" : [
      {
        "name" : "id",
        "type" : "string",
        "multiValued" : false,
        "description" : "The resource type's server unique id.
          May be the same as the 'name' attribute.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "name",
        "type" : "string",
        "multiValued" : false,
        "description" : "The resource type name.  When applicable,
          service providers MUST specify the name, e.g., 'User'.",
        "required" : true,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "description",
        "type" : "string",
        "multiValued" : false,
        "description" : "The resource type's human-readable
          description.  When applicable, service providers MUST
          specify the description.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "endpoint",
        "type" : "reference",
        "referenceTypes" : ["uri"],
        "multiValued" : false,
        "description" : "The resource type's HTTP-addressable
          endpoint relative to the Base URL, e.g., '/Users'.",
        "required" : true,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "schema",
        "type" : "reference",
        "referenceTypes" : ["uri"],
        "multiValued" : false,
        "description" : "The resource type's primary/base schema
          URI.",
        "required" : true,
        "caseExact" : true,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "schemaExtensions",
        "type" : "complex",
        "multiValued" : false,
        "description" : "A list of URIs of the resource type's schema
          extensions.",
        "required" : true,
        "mutability" : "readOnly",
        "returned" : "default",
        "subAttributes" : [
          {
            "name" : "schema",
            "type" : "reference",
            "referenceTypes" : ["uri"],
            "multiValued" : false,
            "description" : "The URI of a schema extension.",
            "required" : true,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "required",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value that specifies whether
              or not the schema extension is required for the
              resource type.  If true, a resource of this type MUST
              include this schema extension and also include any
              attributes declared as required in this schema extension.
              If false, a resource of this type MAY omit this schema
              extension.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default"
          }
        ]
      }
    ]
  },
  {
    "id" : "urn:ietf:params:scim:schemas:core:2.0:Schema",
    "name" : "Schema",
    "description" : "Specifies the schema that describes a
      SCIM schema",
    "attributes" : [
      {
        "name" : "id",
        "type" : "string",
        "multiValued" : false,
        "description" : "The unique URI of the schema.
          When applicable, service providers MUST specify the URI.",
        "required" : true,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "name",
        "type" : "string",
        "multiValued" : false,
        "description" : "The schema's human-readable name.  When
          applicable, service providers MUST specify the name,
          e.g., 'User'.",
        "required" : true,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "description",
        "type" : "string",
        "multiValued" : false,
        "description" : "The schema's human-readable name.  When
          applicable, service providers MUST specify the name,
          e.g., 'User'.",
        "required" : false,
        "caseExact" : false,
        "mutability" : "readOnly",
        "returned" : "default",
        "uniqueness" : "none"
      },
      {
        "name" : "attributes",
        "type" : "complex",
        "multiValued" : true,
        "description" : "A complex attribute that includes the
          attributes of a schema.",
        "required" : true,
        "mutability" : "readOnly",
        "returned" : "default",
        "subAttributes" : [
          {
            "name" : "name",
            "type" : "string",
            "multiValued" : false,
            "description" : "The attribute's name.",
            "required" : true,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "type",
            "type" : "string",
            "multiValued" : false,
            "description" : "The attribute's data type.
              Valid values include 'string', 'complex', 'boolean',
              'decimal', 'integer', 'dateTime', 'reference'.",
            "required" : true,
            "canonicalValues" : [
              "string",
              "complex",
              "boolean",
              "decimal",
              "integer",
              "dateTime",
              "reference"
            ],
            "caseExact" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "multiValued",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value indicating an
              attribute's plurality.",
            "required" : true,
            "mutability" : "readOnly",
            "returned" : "default"
          },
          {
            "name" : "description",
            "type" : "string",
            "multiValued" : false,
            "description" : "A human-readable description of the
              attribute.",
            "required" : false,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "required",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A boolean value indicating whether or
              not the attribute is required.",
            "required" : false,
            "mutability" : "readOnly",
            "returned" : "default"
          },
          {
            "name" : "canonicalValues",
            "type" : "string",
            "multiValued" : true,
            "description" : "A collection of canonical values.  When
              applicable, service providers MUST specify the
              canonical types, e.g., 'work', 'home'.",
            "required" : false,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "caseExact",
            "type" : "boolean",
            "multiValued" : false,
            "description" : "A Boolean value indicating whether or
              not a string attribute is case sensitive.",
            "required" : false,
            "mutability" : "readOnly",
            "returned" : "default"
          },
          {
            "name" : "mutability",
            "type" : "string",
            "multiValued" : false,
            "description" : "Indicates whether or not an attribute
              is modifiable.",
            "required" : false,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none",
            "canonicalValues" : [
              "readOnly",
              "readWrite",
              "immutable",
              "writeOnly"
            ]
          },
          {
            "name" : "returned",
            "type" : "string",
            "multiValued" : false,
            "description" : "Indicates when an attribute is returned
              in a response (e.g., to a query).",
            "required" : false,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none",
            "canonicalValues" : [
              "always",
              "never",
              "default",
              "request"
            ]
          },
          {
            "name" : "uniqueness",
            "type" : "string",
            "multiValued" : false,
            "description" : "Indicates how unique a value must be.",
            "required" : false,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none",
            "canonicalValues" : [
              "none",
              "server",
              "global"
            ]
          },
          {
            "name" : "referenceTypes",
            "type" : "string",
            "multiValued" : true,
            "description" : "Used only with an attribute of type
              'reference'.  Specifies a SCIM resourceType that a
              reference attribute MAY refer to, e.g., 'User'.",
            "required" : false,
            "caseExact" : true,
            "mutability" : "readOnly",
            "returned" : "default",
            "uniqueness" : "none"
          },
          {
            "name" : "subAttributes",
            "type" : "complex",
            "multiValued" : true,
            "description" : "Used to define the sub-attributes of a
              complex attribute.",
            "required" : false,
            "mutability" : "readOnly",
            "returned" : "default",
            "subAttributes" : [
              {
                "name" : "name",
                "type" : "string",
                "multiValued" : false,
                "description" : "The attribute's name.",
                "required" : true,
                "caseExact" : true,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none"
              },
              {
                "name" : "type",
                "type" : "string",
                "multiValued" : false,
                "description" : "The attribute's data type.
                  Valid values include 'string', 'complex', 'boolean',
                  'decimal', 'integer', 'dateTime', 'reference'.",
                "required" : true,
                "caseExact" : false,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none",
                "canonicalValues" : [
                  "string",
                  "complex",
                  "boolean",
                  "decimal",
                  "integer",
                  "dateTime",
                  "reference"
                ]
              },
              {
                "name" : "multiValued",
                "type" : "boolean",
                "multiValued" : false,
                "description" : "A Boolean value indicating an
                  attribute's plurality.",
                "required" : true,
                "mutability" : "readOnly",
                "returned" : "default"
              },
              {
                "name" : "description",
                "type" : "string",
                "multiValued" : false,
                "description" : "A human-readable description of the
                  attribute.",
                "required" : false,
                "caseExact" : true,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none"
              },
              {
                "name" : "required",
                "type" : "boolean",
                "multiValued" : false,
                "description" : "A boolean value indicating whether or
                  not the attribute is required.",
                "required" : false,
                "mutability" : "readOnly",
                "returned" : "default"
              },
              {
                "name" : "canonicalValues",
                "type" : "string",
                "multiValued" : true,
                "description" : "A collection of canonical values.  When
                  applicable, service providers MUST specify the
                  canonical types, e.g., 'work', 'home'.",
                "required" : false,
                "caseExact" : true,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none"
              },
              {
                "name" : "caseExact",
                "type" : "boolean",
                "multiValued" : false,
                "description" : "A Boolean value indicating whether or
                  not a string attribute is case sensitive.",
                "required" : false,
                "mutability" : "readOnly",
                "returned" : "default"
              },
              {
                "name" : "mutability",
                "type" : "string",
                "multiValued" : false,
                "description" : "Indicates whether or not an
                  attribute is modifiable.",
                "required" : false,
                "caseExact" : true,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none",
                "canonicalValues" : [
                  "readOnly",
                  "readWrite",
                  "immutable",
                  "writeOnly"
                ]
              },
              {
                "name" : "returned",
                "type" : "string",
                "multiValued" : false,
                "description" : "Indicates when an attribute is
                  returned in a response (e.g., to a query).",
                "required" : false,
                "caseExact" : true,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none",
                "canonicalValues" : [
                  "always",
                  "never",
                  "default",
                  "request"
                ]
              },
              {
                "name" : "uniqueness",
                "type" : "string",
                "multiValued" : false,
                "description" : "Indicates how unique a value must be.",
                "required" : false,
                "caseExact" : true,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none",
                "canonicalValues" : [
                  "none",
                  "server",
                  "global"
                ]
              },
              {
                "name" : "referenceTypes",
                "type" : "string",
                "multiValued" : false,
                "description" : "Used only with an attribute of type
                  'reference'.  Specifies a SCIM resourceType that a
                  reference attribute MAY refer to, e.g., 'User'.",
                "required" : false,
                "caseExact" : true,
                "mutability" : "readOnly",
                "returned" : "default",
                "uniqueness" : "none"
              }
            ]
          }
        ]
      }
    ]
  }
]

Figure 10: Representation of Fixed Service Provider Endpoint Schemas ๐ŸŽ€

9. Security Considerations ๐Ÿ”

9.1. Protocol ๐ŸŽ€

okay bestie, SCIM data is meant to get exchanged using the SCIM protocol ๐Ÿ“ฆ so when you're handling it you REALLY need to follow the security stuff in Section 7 of [RFC7644]. it's giving "read the manual first" energy ๐Ÿ™ˆ

9.2. Passwords and Other Sensitive Security Data ๐Ÿ”

passwords and other security credential stuff is extremely sensitive, so it needs special care whenever it's sent or stored ๐Ÿฅบ SCIM uses cleartext passwords for assigning values and for equality testing, but password values MUST NOT be stored in cleartext form. no cap, this one's non-negotiable ๐Ÿ’…

admins should use industry best practices to protect stored credentials, and they SHOULD follow the advice in Section 5.1.4.1 of [RFC6819] ๐Ÿงš the requirements include (but aren't limited to) the following:

  • provide injection attack countermeasures (e.g., by validating all inputs and parameters) ๐Ÿ›ก๏ธ
  • credentials should not be stored in cleartext form ๐Ÿ™…โ€โ™€๏ธ
  • store credentials using an encrypted protection mechanism (e.g., hashing); and ๐Ÿ”’
  • where possible, avoid passwords as the sole form of authentication, and consider using credentials that are based on asymmetric cryptography ๐Ÿฆ‹

9.3. Privacy ๐ŸŒธ

the SCIM core schema defines attributes that are sensitive and may count as personally identifying information (PII) ๐Ÿ‘€ these privacy considerations should also be thought about for extensions, not just the schema in this spec. ngl, this part is so important ๐Ÿ˜ญ

for this spec, PII means any attribute that could be used as a unique key to identify a person (e.g., "User") ๐Ÿ†” and since other info can be combined to figure out who someone is, all SCIM attributes are treated as "sensitive" personal information. check the rules in your region too, because there may be special considerations for handling personal info (e.g., PII) ๐ŸŒ

info should be shared on an as-needed basis, okay? a SCIM client should only send what it thinks a service provider needs, and a SCIM service provider should only accept info it actually needs โœจ clients and service providers should also remember that personal info is being passed around across technical (e.g., protocol and applications), administrative (e.g., organizational, corporate), and jurisdictional boundaries ๐Ÿ—บ๏ธ info security and privacy both have to be considered, periodt ๐Ÿ’œ

security service level agreements for handling these attributes are beyond the scope of this document, but implementers and deploying organizations should carefully consider them ๐Ÿซถ

for more protocol-specific privacy stuff about SCIM info, check out the Privacy Considerations section of [RFC7644] ๐Ÿ“–

SCIM defines attributes like "id", "externalId", and SCIM resource URIs, and these cause new PII to be generated ๐ŸŒˆ this info is important for how the SCIM protocol identifies and locates resources. where possible, service providers are suggested to take these remediations:

  • where possible, assign and bind identifiers to specific tenants and/or clients. when multiple tenants can reference the same resource, they should do so via separate identifiers (id or externalId). this makes sure separate domains linked to the same info can't do identifier correlation ๐Ÿ•ต๏ธโ€โ™€๏ธ
  • in the case of "externalId", if multiple values are supported, use access control to restrict access to the client domain that assigned the "externalId" value ๐Ÿ”‘
  • make sure access to data is properly restricted to authorized parties with a "need to know" ๐Ÿคซ
  • when persisted, make sure the right protection mechanisms are in place to restrict access by unauthorized parties, including administrators or parties with access to backup data ๐Ÿ’พ

10. IANA Considerations โœจ

10.1. Registration of SCIM URN Sub-namespace and SCIM Registry ๐Ÿ—‚๏ธ

IANA added an entry to the "IETF URN Sub-namespace for Registered Protocol Parameter Identifiers" registry and made a sub-namespace for the Registered Parameter Identifier as per [RFC3553]: urn:ietf:params:scim ๐ŸŽ‰

to manage this sub-namespace, IANA created the "System for Cross-domain Identity Management (SCIM) Schema URIs" registry, which is used to manage entries within the urn:ietf:params:scim namespace. here's the registry description:

  • Registry name: SCIM
  • Specification: this document (RFC 7643)
  • Repository: See Section 10.2
  • Index value: See Section 10.2

10.2. URN Sub-namespace for SCIM ๐Ÿ’ซ

SCIM schemas and SCIM messages use URIs to identify the schema in use or other relevant context ๐Ÿฆ‹ this section creates and registers an IETF URN Sub-namespace for use in the SCIM specifications and future extensions. main character namespace energy ๐Ÿ‘‘

10.2.1. Specification Template ๐Ÿ“

Namespace ID: The Namespace ID "scim" has been assigned. ๐Ÿท๏ธ

Registration Information: Version: 1, Date: 2015-06-22 ๐Ÿ“…

Declared registrant of the namespace: Registering organization is The Internet Engineering Task Force. Designated contact is a designated expert who will monitor the SCIM public mailing list, "scim@ietf.org". ๐Ÿ“ฌ

Declaration of Syntactic Structure: The Namespace Specific String (NSS) of all URNs that use the "scim" Namespace ID shall have the following structure:

urn:ietf:params:scim:{type}:{name}{:other}

the keywords mean the following:

  • type: The entity type, which is either "schemas" or "api". ๐Ÿงฉ
  • name: A required US-ASCII string that conforms to the URN syntax requirements (see [RFC2141]) and defines a major namespace of a schema used within SCIM (e.g., "core", which is reserved for SCIM specifications). The value MAY also be an industry name or organization name. ๐Ÿญ
  • other: Any US-ASCII string that conforms to the URN syntax requirements (see [RFC2141]) and defines the sub-namespace (which MAY be further broken down in namespaces delimited by colons) as needed to uniquely identify a schema. ๐Ÿ”

Relevant Ancillary Documentation: None ๐Ÿ™ƒ

Identifier Uniqueness Considerations: The designated contact shall be responsible for reviewing and enforcing uniqueness. ๐Ÿง

Identifier Persistence Considerations: Once a name has been allocated, it MUST NOT be reallocated for a different purpose. The rules provided for assignments of values within a sub-namespace MUST be constructed so that the meanings of values cannot change. This registration mechanism is not appropriate for naming values whose meanings may change over time. ๐Ÿšซ this part is lowkey strict, and honestly iconic for it.

as the SCIM specs get updated and the SCIM protocol version gets adjusted, a new registration will be made when significant changes are made. for example, "urn:ietf:params:scim:schemas:core:1.0 (externally defined, not previously registered)" and "urn:ietf:params:scim:schemas:core:2.0" โณ

Process of Identifier Assignment: Identifiers with namespace type "schema" (e.g., "urn:ietf:params:scim:schemas") are assigned after the review of the assigned contact via the SCIM public mailing list, "scim@ietf.org", as documented in Section 10.3. Namespaces with type "api" (e.g., "urn:ietf:params:scim:api") and "param" (e.g., "urn:ietf:params:scim:param") are reserved for IETF-approved SCIM specifications. ๐ŸŽ€

Process of Identifier Resolution: The namespace is not currently listed with a Resolution Discovery System (RDS), but nothing about the namespace prohibits the future definition of appropriate resolution methods or listing with an RDS. ๐Ÿ”ฎ

Rules for Lexical Equivalence: No special considerations; the rules for lexical equivalence specified in [RFC2141] apply. โš–๏ธ

Conformance with URN Syntax: No special considerations. โœ…

Validation Mechanism: None specified. ๐Ÿคทโ€โ™€๏ธ

Scope: Global. ๐ŸŒ

10.3. Registering SCIM Schemas ๐Ÿงพ

this section defines the process for registering new SCIM schemas with IANA in the "System for Cross-domain Identity Management (SCIM) Schema URIs" registry (see Section 10.1). a schema URI is used as a value in the "schemas" attribute (Section 3) to tell apart extensions used in a SCIM resource ๐Ÿงš

10.3.1. Registration Procedure ๐Ÿ“š

the IETF made a mailing list, scim@ietf.org, which can be used for public discussion of SCIM schema proposals before registration. using the mailing list is strongly encouraged ๐Ÿ’Œ the IESG appointed a designated expert [RFC5226] who will monitor the scim@ietf.org mailing list and review registrations.

registration of new "core" schemas (e.g., in the namespace "urn:ietf:params:scim:schemas:core") and "API" schemas (e.g., in the namespace "urn:ietf:params:scim:api") MUST be reviewed by the designated expert and published in an RFC. An RFC is REQUIRED for the registration of new value data types that modify existing properties. An RFC is also REQUIRED for registration of SCIM schema URIs that modify SCIM schema previously documented in an existing RFC. URNs within "urn:ietf:params:scim" but outside the above namespaces MAY be registered with a simple review (e.g., check for spam) by the designated expert on a first-come-first-served basis. ๐Ÿ•ต๏ธโ€โ™€๏ธ

the registration procedure begins when a completed registration template, defined in the sections below, is sent to scim@ietf.org and iana@iana.org. within two weeks, the designated expert is expected to tell IANA and the submitter of the registration whether it's approved, approved with minor changes, or rejected with cause. when a registration is rejected with cause, it can be resubmitted if the concerns listed in the cause are addressed ๐Ÿ”

decisions made by the designated expert can be appealed to the IESG Applications Area Director, then to the IESG. they follow the normal appeals procedure for IESG decisions โš–๏ธ

once the registration procedure wraps up successfully, IANA creates or modifies the corresponding record in the SCIM schema registry, and the completed registration template is discarded ๐Ÿ—‘๏ธ

an RFC specifying one or more new schema URIs MUST include the completed registration templates, which MAY be expanded with additional information. these completed templates are meant to go in the body of the document, not in the IANA Considerations section. the RFC SHOULD include any attributes defined. ๐Ÿ“„โœจ

10.3.2. Schema Registration Template ๐ŸŒท

a SCIM schema URI is defined by filling out the following template:

Schema URI:  A unique URI for the SCIM schema extension.

Schema Name:  A descriptive name of the schema extension (e.g.,
   "Generic Device").

Intended or Associated Resource Type:  A value defining the resource
   type (e.g., "Device").

Purpose:  A description of the purpose of the extension and/or its
   intended use.

Single-value Attributes:  A list and description of single-valued
   attributes defined, including complex attributes.

Multi-valued Attributes:  A list and description of multi-valued
   attributes defined, including complex attributes.

10.4. Initial SCIM Schema Registry โœจ

The IANA already filled up the "System for Cross-domain Identity Management (SCIM) Schema URIs" registry ๐Ÿงš with the registries for SCIM schema URIs below, each pointing to its reference document. Quick heads-up: the schema URIs are split across two lines in the tables so they fit on the page. ๐ŸŽ€

Here's the first batch, the core and extension schemas ๐Ÿ’…:

+-----------------------------------+-----------------+-------------+
| Schema URI                        | Name            | Reference   |
+-----------------------------------+-----------------+-------------+
| urn:ietf:params:scim:schemas:     | User Resource   | See Section |
| core:2.0:User                     |                 | 4.1         |
|                                   |                 |             |
| urn:ietf:params:scim:schemas:     | Enterprise User | See Section |
| extension:enterprise:2.0:User     | Extension       | 4.3         |
|                                   |                 |             |
| urn:ietf:params:scim:schemas:     | Group Resource  | See Section |
| core:2.0:Group                    |                 | 4.2         |
+-----------------------------------+-----------------+-------------+

SCIM Schema URIs for Data Resources ๐ŸŒธ

Then comes the second batch, the data resource schemas, and these ones are giving structure ๐Ÿ‘‘:

+-----------------------------------+-------------------+-----------+
| Schema URI                        | Name              | Reference |
+-----------------------------------+-------------------+-----------+
| urn:ietf:params:scim:schemas:     | Service Provider  | See       |
| core:2.0:ServiceProviderConfig    | Configuration     | Section 5 |
|                                   | Schema            |           |
|                                   |                   |           |
| urn:ietf:params:scim:schemas:     | Resource Type     | See       |
| core:2.0:ResourceType             | Configuration     | Section 6 |
|                                   |                   |           |
| urn:ietf:params:scim:schemas:     | Schema            | See       |
| core:2.0:Schema                   | Definitions       | Section 7 |
|                                   | Schema            |           |
+-----------------------------------+-------------------+-----------+

SCIM Server-Related Schema URIs ๐Ÿฆ‹


11. References ๐Ÿ“š

11.1. Normative References ๐Ÿ’œ

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>.

[RFC2141] Moats, R., "URN Syntax", RFC 2141, DOI 10.17487/RFC2141, May 1997, <http://www.rfc-editor.org/info/rfc2141>.

[RFC3553] Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An IETF URN Sub-namespace for Registered Protocol Parameters", BCP 73, RFC 3553, DOI 10.17487/RFC3553, June 2003, <http://www.rfc-editor.org/info/rfc3553>.

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <http://www.rfc-editor.org/info/rfc3629>.

[RFC3966] Schulzrinne, H., "The tel URI for Telephone Numbers", RFC 3966, DOI 10.17487/RFC3966, December 2004, <http://www.rfc-editor.org/info/rfc3966>.

[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <http://www.rfc-editor.org/info/rfc3986>.

[RFC4647] Phillips, A. and M. Davis, "Matching of Language Tags", BCP 47, RFC 4647, DOI 10.17487/RFC4647, September 2006, <http://www.rfc-editor.org/info/rfc4647>.

[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, <http://www.rfc-editor.org/info/rfc4648>.

[RFC5234] Crocker, D., Ed., and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/ RFC5234, January 2008, <http://www.rfc-editor.org/info/rfc5234>.

[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008, <http://www.rfc-editor.org/info/rfc5280>.

[RFC5321] Klensin, J., "Simple Mail Transfer Protocol", RFC 5321, DOI 10.17487/RFC5321, October 2008, <http://www.rfc-editor.org/info/rfc5321>.

[RFC5646] Phillips, A., Ed., and M. Davis, Ed., "Tags for Identifying Languages", BCP 47, RFC 5646, DOI 10.17487/RFC5646, September 2009, <http://www.rfc-editor.org/info/rfc5646>.

[RFC6557] Lear, E. and P. Eggert, "Procedures for Maintaining the Time Zone Database", BCP 175, RFC 6557, DOI 10.17487/RFC6557, February 2012, <http://www.rfc-editor.org/info/rfc6557>.

[RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 2014, <http://www.rfc-editor.org/info/rfc7159>.

[RFC7231] Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI 10.17487/RFC7231, June 2014, <http://www.rfc-editor.org/info/rfc7231>.

[RFC7232] Fielding, R., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests", RFC 7232, DOI 10.17487/RFC7232, June 2014, <http://www.rfc-editor.org/info/rfc7232>.

[RFC7644] Hunt, P., Ed., Grizzle, K., Ansari, M., Wahlstroem, E., and C. Mortimore, "System for Cross-domain Identity Management: Protocol", RFC 7644, DOI 10.17487/RFC7644, September 2015, <http://www.rfc-editor.org/info/rfc7644>.

11.2. Informative References ๐ŸŒˆ

[ISO3166] International Organization for Standardization, "Codes for the representation of names of countries and their subdivisions - Part 1: Country codes", ISO 3166-1:2013, November 2013, <http://www.iso.org>.

[Olson-TZ] Internet Assigned Numbers Authority, "IANA Time Zone Database", <https://www.iana.org/time-zones>.

[PortableContacts] Smarr, J., "Portable Contacts 1.0 Draft C - Schema Only", August 2008, <http://www.portablecontacts.net/draft-spec.html>.

[RFC2277] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, DOI 10.17487/RFC2277, January 1998, <http://www.rfc-editor.org/info/rfc2277>.

[RFC4512] Zeilenga, K., Ed., "Lightweight Directory Access Protocol (LDAP): Directory Information Models", RFC 4512, DOI 10.17487/RFC4512, June 2006, <http://www.rfc-editor.org/info/rfc4512>.

[RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, DOI 10.17487/RFC5226, May 2008, <http://www.rfc-editor.org/info/rfc5226>.

[RFC6350] Perreault, S., "vCard Format Specification", RFC 6350, DOI 10.17487/RFC6350, August 2011, <http://www.rfc-editor.org/info/rfc6350>.

[RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, October 2012, <http://www.rfc-editor.org/info/rfc6749>.

[RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 Threat Model and Security Considerations", RFC 6819, DOI 10.17487/RFC6819, January 2013, <http://www.rfc-editor.org/info/rfc6819>.

[XML-Schema] Peterson, D., Gao, S., Malhotra, A., Sperberg-McQueen, C., and H. Thompson, "XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes", April 2012, <http://www.w3.org/TR/xmlschema11-2/>.


Acknowledgements ๐Ÿซถ

The editor would like to give a huge shoutout to the people who drafted earlier versions of this document ๐Ÿ’–:

  • Chuck Mortimore, Salesforce
  • Patrick Harding, Ping
  • Paul Madsen, Ping
  • Trey Drake, UnboundID

The SCIM Community also wants to thank the following people for their work on the research, formulation, drafting, editing, and support of this specification ๐Ÿ™Œ:

  • Morteza Ansari (morteza.ansari@cisco.com)
  • Sidharth Choudhury (schoudhury@salesforce.com)
  • Samuel Erdtman (samuel@erdtman.se)
  • Kelly Grizzle (kelly.grizzle@sailpoint.com)
  • Chris Phillips (cjphillips@gmail.com)
  • Erik Wahlstroem (erik.wahlstrom@nexusgroup.com)
  • Phil Hunt (phil.hunt@yahoo.com)

Special thanks to Joseph Smarr, whose excellent work on the Portable Contacts Specification [PortableContacts] gave the SCIM schema structure and text a foundation. Iconic behaviour ๐Ÿ‘‘โœจ


Authors' Addresses ๐Ÿ’Œ

Phil Hunt (editor) Oracle Corporation

Email: phil.hunt@yahoo.com

Kelly Grizzle SailPoint

Email: kelly.grizzle@sailpoint.com

Erik Wahlstroem Nexus Technology

Email: erik.wahlstrom@nexusgroup.com

Chuck Mortimore Salesforce.com

Email: cmortimore@salesforce.com

๐Ÿ“ฆ where this page comes from