One document matched: draft-ietf-scim-api-07.xml
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='http://xml.resource.org/authoring/rfc2629.xslt' ?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="std" docName="draft-ietf-scim-api-07" ipr="trust200902">
<front>
<title abbrev="draft-ietf-scim-api-07">System for Cross-Domain Identity
Management:Protocol</title>
<author fullname="Phil Hunt" initials="P." role="editor" surname="Hunt">
<organization abbrev="Oracle">Oracle Corporation</organization>
<address>
<email>phil.hunt@yahoo.com</email>
</address>
</author>
<author fullname="Kelly Grizzle" initials="K.G." surname="Grizzle">
<organization abbrev="SailPoint">SailPoint</organization>
<address>
<email>kelly.grizzle@sailpoint.com</email>
</address>
</author>
<author fullname="Morteza Ansari" initials="M.A." surname="Ansari">
<organization abbrev="Cisco">Cisco</organization>
<address>
<email>morteza.ansari@cisco.com</email>
</address>
</author>
<author fullname="Erik Wahlström" initials="E.W." surname="Wahlström">
<organization abbrev="Technology Nexus">Technology Nexus</organization>
<address>
<email>erik.wahlstrom@nexussafe.com</email>
</address>
</author>
<author fullname="Chuck Mortimore" initials="C." surname="Mortimore">
<organization abbrev="Salesforce">Salesforce.com</organization>
<address>
<email>cmortimore@salesforce.com</email>
</address>
</author>
<date month="July" year="2014"/>
<keyword>SCIM</keyword>
<abstract>
<t>The System for Cross-Domain Identity Management (SCIM) specification
is designed to make managing user identity in cloud based applications
and services easier. The specification suite seeks to build upon
experience with existing schemas and deployments, placing specific
emphasis on simplicity of development and integration, while applying
existing authentication, authorization, and privacy models. It's intent
is to reduce the cost and complexity of user management operations by
providing a common user schema and extension model, as well as binding
documents to provide patterns for exchanging this schema using standard
protocols. In essence, make it fast, cheap, and easy to move users in
to, out of, and around the cloud.</t>
</abstract>
</front>
<middle>
<section anchor="intro" title="Introduction and Overview" toc="default">
<t>The SCIM Protocol is an application-level, HTTP protocol for
provisioning and managing identity data on the web. The protocol
supports creation, modification, retrieval, and discovery of core
identity resources; i.e., Users and Groups, as well as custom resource
extensions.</t>
<section title="Intended Audience" toc="default">
<t>This document is intended as a guide to SCIM API usage for both
identity service providers and clients.</t>
</section>
<section anchor="notat" title="Notational Conventions" toc="default">
<t>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
keywords are capitalized when used to unambiguously specify
requirements of the protocol or application features and behavior that
affect the interoperability and security of implementations. When
these words are not capitalized, they are meant in their
natural-language sense.</t>
<t>For purposes of readability examples are not URL encoded.
Implementers MUST percent encode URLs as described in <xref
target="RFC3986">Section 2.1 </xref>.</t>
</section>
<section anchor="defs" title="Definitions" toc="default">
<t><list style="hanging">
<t hangText="Base URL:">The SCIM HTTP API is always relative to a
Base URL. The Base URL MUST NOT contain a query string as clients
may append additional path information and query parameters as
part of forming the request. Example: <spanx style="verb">https://example.com/scim/</spanx></t>
<t>For readability, all examples in this document are expressed
assuming the SCIM service root and the server root are the same.
It is expected that SCIM servers may be deployed using any URI
prefix. For example, a SCIM server might be have a prefix of
<spanx style="verb">https://example.com/</spanx>, or <spanx
style="verb">https://example.com/scim/tenancypath/</spanx>.
Additionally client may also apply a version number to the server
root prefix (see <xref target="api-versioning"/> ).</t>
</list></t>
</section>
</section>
<section anchor="aa" title="Authentication and Authorization"
toc="default">
<t>The SCIM protocol does not define a scheme for authentication and
authorization therefore implementers are free to choose mechanisms
appropriate to their use cases. The choice of authentication mechanism
will impact interoperability. It is RECOMMENDED that clients be
implemented in such a way that new authentication schemes can be
deployed. Implementers SHOULD support existing
authentication/authorization schemes. In particular, OAuth2 <xref
target="RFC6750"/> is RECOMMENDED. Appropriate security considerations
of the selected authentication and authorization schemes SHOULD be
taken. Because this protocol uses HTTP response status codes as the
primary means of reporting the result of a request, servers are advised
to respond to unauthorized or unauthenticated requests using the 401
response code in accordance with <xref target="RFC7235">Section 3.1
of</xref>.</t>
<t>All examples assume OAuth2 bearer token <xref target="RFC6750"/> ;
e.g.,</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646 HTTP/1.1
Host: example.com
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>The context of the request (i.e. the user for whom data is being
requested) MUST be inferred by service providers.</t>
</section>
<section anchor="api" title="API">
<t>The SCIM protocol specifies well known endpoints and HTTP methods for
managing resources defined in the core schema; i.e., <spanx
style="verb">User</spanx> and <spanx style="verb">Group</spanx>
resources correspond to <spanx style="verb">/Users</spanx> and <spanx
style="verb">/Groups</spanx> respectively. Service providers that
support extended resources SHOULD define resource endpoints using the
established convention; pluralize the resource name defined in the
extended schema by appending an 's'. Given there are cases where
resource pluralization is ambiguous; e.g., a resource named <spanx
style="verb">Person</spanx> is legitimately <spanx style="verb">Persons</spanx>
and <spanx style="verb">People</spanx> clients SHOULD discover resource
endpoints via the <spanx style="verb">/ResourceTypes</spanx>
endpoint.</t>
<t><list style="hanging">
<t hangText="GET">Retrieves a complete or partial resource.</t>
<t hangText="POST">Create new resources, create a search request, or
bulk modify resources.</t>
<t hangText="PUT">Modifies a resource by replacing existing
attributes with a specified set of replacement attributes (replace).
PUT SHOULD NOT be used to create new resources.</t>
<t hangText="PATCH">Modifies a resource with a set of client
specified changes (partial update).</t>
<t hangText="DELETE">Deletes a resource.</t>
</list></t>
<texttable anchor="endpoint-summary" title="Defined endpoints">
<ttcol align="left">Resource</ttcol>
<ttcol align="left">Endpoint</ttcol>
<ttcol align="left">Operations</ttcol>
<ttcol align="left">Description</ttcol>
<c>User</c>
<c>/Users</c>
<c><xref format="default" target="get-resource">GET</xref>, <xref
format="default" target="create-resource">POST</xref>, <xref
format="default" target="edit-resource-with-put">PUT</xref>, <xref
format="default" target="edit-resource-with-patch">PATCH</xref>, <xref
format="default" target="delete-resource">DELETE</xref></c>
<c>Retrieve/Add/Modify Users</c>
<c>Group</c>
<c>/Groups</c>
<c><xref format="default" target="get-resource">GET</xref>, <xref
format="default" target="create-resource">POST</xref>, <xref
format="default" target="edit-resource-with-put">PUT</xref>, <xref
format="default" target="edit-resource-with-patch">PATCH</xref>, <xref
format="default" target="delete-resource">DELETE</xref></c>
<c>Retrieve/Add/Modify Groups</c>
<c>Service Provider Configuration</c>
<c>/ServiceProviderConfigs</c>
<c><xref format="default" target="get-resource">GET</xref></c>
<c>Retrieve the service provider's configuration</c>
<c>Resource Type</c>
<c>/ResourceTypes</c>
<c><xref format="default" target="get-resource">GET</xref></c>
<c>Retrieve the supported resource types</c>
<c>Schema</c>
<c>/Schemas</c>
<c><xref format="default" target="get-resource">GET</xref></c>
<c>Retrieve a resource's schema</c>
<c>Bulk</c>
<c>/Bulk</c>
<c><xref format="default" target="bulk-resources">POST</xref></c>
<c>Bulk modify resources</c>
<c>Search</c>
<c>[prefix]/.search</c>
<c><xref format="default" target="query-post">POST</xref></c>
<c>Perform a search at system root or within a resource endpoint for
one or more resource types using POST.</c>
</texttable>
<t>All requests to the service provider are made via HTTP Methods as per
<xref target="RFC7231">Section 4.3</xref> on a URL derived from the Base
URL. Responses are returned in the body of the HTTP response, formatted
as JSON. Response and error codes SHOULD be transmitted via the HTTP
status code of the response (if possible), and SHOULD also be specified
in the body of the response.</t>
<section anchor="create-resource" title="Creating Resources"
toc="default">
<t>To create new resources, clients send POST requests to the resource
container endpoint such as: <spanx style="verb">/Users</spanx> or
<spanx style="verb">/Groups</spanx>.</t>
<t>Attributes whose mutability is <spanx style="verb">readOnly</spanx>,
that are included in the request body SHALL be ignored.</t>
<t>Attributes whose mutability is <spanx style="verb">readWrite</spanx>,
that are omitted from the request body, MAY be assumed to be not
asserted by the client. The service provider MAY assign a default
value to non-asserted attributes in the final resource representation.
Service providers MAY take into account whether a client has access
to, or understands, all of the resource's attributes when deciding
whether non-asserted attributes SHALL be defaulted. Clients that would
like to override a server defaults, MAY specify <spanx style="verb">null</spanx>
for a single-valued attribute or an empty array <spanx style="verb">[]</spanx>
for a multi-valued attribute to clear all values.</t>
<t>Successful resource creation is indicated with a 201 ("Created")
response code. Upon successful creation, the response body MUST
contain the newly created resource. Since the server is free to alter
and/or ignore POSTed content, returning the full representation can be
useful to the client, enabling it to correlate the client and server
views of the new resource. When a resource is created, its URI must be
returned in the response Location header.</t>
<t>If the service provider determines creation of the requested
resource conflicts with existing resources; e.g., a <spanx
style="verb">User</spanx> resource with a duplicate <spanx
style="verb">userName</spanx>, the service provider MUST return a 409
error and SHOULD indicate the conflicting attribute(s) in the body of
the response.</t>
<t>Below, the client sends a POST request containing a user</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">POST /Users HTTP/1.1
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
}
}
</artwork>
</figure>
<t>The server signals a successful creation with a status code of 201.
The response includes a Location header indicating the User URI, and a
representation of that user in the body of the response.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 201 Created
Content-Type: application/scim+json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"e180ee84f0671b1"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"externalId":"bjensen",
"meta":{
"resourceType":"User",
"created":"2011-08-01T21:32:44.882Z",
"lastModified":"2011-08-01T21:32:44.882Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"e180ee84f0671b1\""
},
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
},
"userName":"bjensen"
}
</artwork>
</figure>
<section anchor="resourceTypes" title="Resource Types">
<t>When adding a resource to a specific endpoint, the meta attribute
<spanx style="verb">resourceType</spanx> SHALL be set by the service
provider to the corresponding resource Type for the endpoint. For
example, <spanx style="verb">/Users</spanx> will set <spanx
style="verb">resourceType</spanx> to <spanx style="verb">User</spanx>,
and <spanx style="verb">/Groups</spanx> will set <spanx
style="verb">resourceType</spanx> to <spanx style="verb">Group</spanx>.</t>
</section>
</section>
<section anchor="get-resources-ops" title="Retrieving Resources"
toc="default">
<t><spanx style="verb">User</spanx> and <spanx style="verb">Group</spanx>
resources are retrieved via opaque, unique URLs or via Query. Service
providers MAY choose to respond with a sub-set of resource attributes,
though MUST minimally return the resource id and meta attributes.</t>
<section anchor="get-resource" title="Retrieving a known Resource"
toc="default">
<t>To retrieve a known resource, clients send GET requests to the
resource endpoint; e.g., <spanx style="verb">/Users/{id}</spanx> or
<spanx style="verb">/Groups/{id}</spanx>.</t>
<t>If the resource exists the server responds with a status code of
200 and includes the result in the body of the response.</t>
<t>The below example retrieves a single User via the <spanx
style="verb">/Users</spanx> endpoint.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">GET /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/scim+json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>The server responds with:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 200 OK
Content-Type: application/scim+json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"f250dd84f0671c3"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"externalId":"bjensen",
"meta":{
"resourceType":"User",
"created":"2011-08-01T18:29:49.793Z",
"lastModified":"2011-08-01T18:29:49.793Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"f250dd84f0671c3\""
},
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
},
"userName":"bjensen",
"phoneNumbers":[
{
"value":"555-555-8377",
"type":"work"
}
],
"emails":[
{
"value":"bjensen@example.com",
"type":"work"
}
]
}
</artwork>
</figure>
</section>
<section anchor="query-resources" title="List/Query Resources"
toc="default">
<t>SCIM defines a standard set of operations that can be used to
filter, sort, and paginate response results. The operations are
specified by adding query parameters to the resource's endpoint (see
following sub-sections). Service providers MAY support additional
query parameters not specified here, and Providers SHOULD ignore any
query parameters they don't recognize.</t>
<t>List and query responses MUST be identified using the following
URI: <spanx style="verb">urn:scim:api:messages:2.0:ListResponse</spanx>.
The following attributes are defined for list and query
responses:</t>
<t><list style="hanging">
<t hangText="totalResults">The total number of results returned
by the list or query operation. This may not be equal to the
number of elements in the resources attribute of the list
response if <xref format="default"
target="pagination">pagination</xref> is requested.
REQUIRED.</t>
<t hangText="Resources">A multi-valued list of complex objects
containing the requested resources. This may be a subset of the
full set of resources if <xref format="default"
target="pagination">pagination</xref> is requested. REQUIRED if
<spanx style="verb">totalResults</spanx> is non-zero.</t>
<t hangText="startIndex">The 1-based index of the first result
in the current set of list results. REQUIRED if <xref
format="default" target="pagination">pagination</xref> is
requested.</t>
<t hangText="itemsPerPage">The number of resources returned in a
list response page. REQUIRED if <xref format="default"
target="pagination">pagination</xref> is requested.</t>
</list></t>
<t>A query that does not return any matches SHALL return success
with <spanx style="verb">totalResults</spanx> set to a value of
0.</t>
<t/>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<preamble>The query example below requests the userName for all
Users:</preamble>
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">GET /Users?attributes=userName
Host: example.com
Accept: application/scim+json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t/>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<preamble>The following is an example response to the query
above:</preamble>
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"schemas":["urn:scim:api:messages:2.0:ListResponse"],
"totalResults":2,
"Resources":[
{
"userName":"bjensen"
},
{
"userName":"jsmith"
}
]
} </artwork>
</figure>
<section anchor="query-endpoints" title="Query Endpoints">
<t>Queries MAY be performed against a SCIM resource object or a
resource type endpoint. For example: <list>
<t><spanx style="verb">/Users/{userid}</spanx></t>
<t><spanx style="verb">/Users</spanx></t>
<t><spanx style="verb">/Groups</spanx></t>
</list></t>
<t>A server MAY support searches against the server root (e.g.
"/"). A search against a server root indicates that ALL resources
within the server SHALL be included subject to filtering. A filter
expression using <spanx style="verb">meta.resourceType</spanx> MAY
be used to restrict results to one or more specific resource types
(e.g. <spanx style="verb">User</spanx> ).</t>
<t>When processing search operations across endpoints that include
more than one SCIM resource type (e.g. a search from the server
root endpoint), filters MUST be processed in the same fashion as
outlined in <xref target="filtering"/>. For filtered attributes
that are not part of a particular resource type, the service
provider SHALL treat the attribute as if there is no attribute
value. For example, a presence or equality filter for an undefined
attribute evaluates as FALSE.</t>
</section>
<section anchor="filtering" title="Filtering">
<t>Filtering is OPTIONAL. Clients may request a subset of
resources by specifying the 'filter' URL query parameter
containing a filter expression. When specified only those
resources matching the filter expression SHALL be returned. The
expression language that is used in the filter parameter supports
references to attributes and literals.</t>
<t>The attribute name and attribute operator are case insensitive.
For example, the following two expressions will evaluate to the
same logical value:</t>
<figure align="center" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
filter=userName Eq "john"
filter=Username eq "john"
</artwork>
</figure>
<t>The filter parameter MUST contain at least one valid Boolean
expression. Each expression MUST contain an attribute name
followed by an attribute operator and optional value. Multiple
expressions MAY be combined using the two logical operators.
Furthermore expressions can be grouped together using "()".</t>
<t>The operators supported in the expression are listed in the
following table.</t>
<texttable align="center" anchor="filter-operator-table"
title="Attribute Operators">
<ttcol align="left">Operator</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Behavior</ttcol>
<c>eq</c>
<c>equal</c>
<c>The attribute and operator values must be identical for a
match.</c>
<c>ne</c>
<c>not equal</c>
<c>The attribute and operator values are not identical.</c>
<c>co</c>
<c>contains</c>
<c>The entire operator value must be a substring of the
attribute value for a match.</c>
<c>sw</c>
<c>starts with</c>
<c>The entire operator value must be a substring of the
attribute value, starting at the beginning of the attribute
value. This criterion is satisfied if the two strings are
identical.</c>
<c>ew</c>
<c>ends with</c>
<c>The entire operator value must be a substring of the
attribute value, matching at the end of the attribute value.
This criterion is satisfied if the two strings are
identical.</c>
<c>pr</c>
<c>present (has value)</c>
<c>If the attribute has a non-empty value, or if it contains a
non-empty node for complex attributes there is a match.</c>
<c>gt</c>
<c>greater than</c>
<c>If the attribute value is greater than operator value, there
is a match. The actual comparison is dependent on the attribute
type. For string attribute types, this is a lexicographical
comparison and for DateTime types, it is a chronological
comparison.</c>
<c>ge</c>
<c>greater than or equal</c>
<c>If the attribute value is greater than or equal to the
operator value, there is a match. The actual comparison is
dependent on the attribute type. For string attribute types,
this is a lexicographical comparison and for DateTime types, it
is a chronological comparison.</c>
<c>lt</c>
<c>less than</c>
<c>If the attribute value is less than operator value, there is
a match. The actual comparison is dependent on the attribute
type. For string attribute types, this is a lexicographical
comparison and for DateTime types, it is a chronological
comparison.</c>
<c>le</c>
<c>less than or equal</c>
<c>If the attribute value is less than or equal to the operator
value, there is a match. The actual comparison is dependent on
the attribute type. For string attribute types, this is a
lexicographical comparison and for DateTime types, it is a
chronological comparison.</c>
</texttable>
<t/>
<texttable align="center" anchor="logical-operator-table"
title="Logical Operators">
<ttcol align="left">Operator</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Behavior</ttcol>
<c>and</c>
<c>Logical And</c>
<c>The filter is only a match if both expressions evaluate to
true.</c>
<c>or</c>
<c>Logical or</c>
<c>The filter is a match if either expression evaluates to
true.</c>
<c>not</c>
<c>Not function</c>
<c>The filter is a match if the expression evaluates to
false.</c>
</texttable>
<t/>
<texttable align="center" anchor="grouping-operator-table"
title="Grouping Operators">
<ttcol align="left">Operator</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Behavior</ttcol>
<c>( )</c>
<c>Precedence grouping</c>
<c>Boolean expressions may be grouped using parentheses to
change the standard order of operations; i.e., evaluate OR
logical operators before logical AND operators.</c>
<c>[ ]</c>
<c>Complex attribute filter grouping</c>
<c>Service providers MAY support complex filters where
expressions MUST be applied to the same value of a parent
attribute specified immediately before the left square bracket
("["). The expression within square brackets ("[" and "]") MUST
be a valid filter expression based upon sub-attributes of the
parent attribute. Nested expressions MAY be used. See examples
below.</c>
</texttable>
<t><figure align="left" anchor="filterABNF"
title="ABNF Specification of SCIM Filters">
<preamble>SCIM filters MUST conform to the following ABNF
rules as per <xref target="RFC5234"/> below:</preamble>
<artwork align="center">FILTER = attrExp / logExp / valuePath / *1"not" "(" FILTER ")"
valuePath = attrPath "[" FILTER "]"
; FILTER uses sub-attribs of a parent attrPath
ATTRNAME = ALPHA *(nameChar)
nameChar = "-" / "_" / DIGIT / ALPHA
attrPath = [URI ":"] ATTRNAME *1subAttr
; SCIM attribute name
; URI is SCIM "schema" URI
subAttr = "." ATTRNAME
; a sub-attribute of a complex attribute
attrExpr = (attrPath SP "pr") /
(attrPath SP compareOp SP compValue)
compValue = false / null / true / number / string
; rules from JSON (RFC7159)
compareOp = "eq" / "ne" / "co" /
"sw" / "ew" /
"gt" / "lt" /
"ge" / "le"
logExp = FILTER ("and" / "or") FILTER</artwork>
</figure></t>
<t>In the above ABNF, the <spanx style="verb">compValue</spanx>
(comparison value) rule is built on JSON Data Interchange format
ABNF rules as specified in <xref target="RFC7159"/>, <spanx
style="verb">DIGIT</spanx> and <spanx style="verb">ALPHA</spanx>
are defined per <xref target="RFC5234">Appendix B.1 of</xref> and,
<spanx style="verb">URI</spanx> is defined per <xref
target="RFC3986">Appendix A of</xref>.</t>
<t>Filters MUST be evaluated using standard order of operations
<xref target="Order-Operations"> </xref>. Attribute operators have
the highest precedence, followed by the grouping operator (i.e,
parentheses), followed by the logical AND operator, followed by
the logical OR operator.</t>
<t>If the specified attribute in a filter expression is a
multi-valued attribute, the resource MUST match if any of the
instances of the given attribute match the specified criterion;
e.g. if a User has multiple emails values, only one has to match
for the entire User to match. For complex attributes, a fully
qualified Sub-Attribute MUST be specified using standard <xref
format="default" target="attribute-notation">attribute
notation</xref>. For example, to filter by userName the parameter
value is userName and to filter by first name, the parameter value
is name.givenName.</t>
<t>Providers MAY support additional filter operations if they
choose. Providers MUST decline to filter results if the specified
filter operation is not recognized and return a HTTP 400 error
with an appropriate human readable response. For example, if a
client specified an unsupported operator named 'regex' the service
provider should specify an error response description identifying
the client error; e.g., 'The operator 'regex' is not
supported.'</t>
<t>String type attributes are case insensitive by default unless
the attribute type is defined as case exact. Attribute comparison
operators 'eq', 'co', and 'sw' MUST perform caseIgnore matching
for all string attributes unless the attribute is defined as case
exact. By default all string attributes are case insensitive.</t>
<t>Clients MAY search by schema or schema extensions by using a
filter expression including the "schemas" attribute.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="Example Filters" width="">
<preamble>The following are examples of valid filters. Some
attributes (e.g. rooms and rooms.number) are hypothetical
extensions and are not part of SCIM core schema:</preamble>
<artwork align="center" alt="" height="" name="" type=""
width="" xml:space="preserve">filter=userName eq "bjensen"
filter=name.familyName co "O'Malley"
filter=userName sw "J"
filter=title pr
filter=meta.lastModified gt "2011-05-13T04:42:34Z"
filter=meta.lastModified ge "2011-05-13T04:42:34Z"
filter=meta.lastModified lt "2011-05-13T04:42:34Z"
filter=meta.lastModified le "2011-05-13T04:42:34Z"
filter=title pr and userType eq "Employee"
filter=title pr or userType eq "Intern"
filter=schemas eq "urn:scim:schemas:extension:enterprise:2.0:User"
filter=userType eq "Employee" and (emails co "example.com" or emails
co "example.org")
filter=userType ne "Employee" and not (emails co "example.com" or
emails co "example.org")
filter=userType eq "Employee" and (emails.type eq "work")
filter=userType eq "Employee" and emails[type eq "work" and
value co “@example.com"]
filter=emails[type eq "work" and value co “@example.com"] or
ims[type eq "xmpp" and value co "@foo.com"]
filter=addresses[state eq "CA" and rooms[type eq "bedroom" and
number gt 2]] </artwork>
</figure>
</section>
<section anchor="sorting" title="Sorting">
<t>Sort is OPTIONAL. Sorting allows clients to specify the order
in which resources are returned by specifying a combination of
sortBy and sortOrder URL parameters.</t>
<t><list style="hanging">
<t hangText="sortBy:">The sortBy parameter specifies the
attribute whose value SHALL be used to order the returned
responses. If the sortBy attribute corresponds to a singular
attribute, resources are sorted according to that attribute's
value; if it's a multi-valued attribute, resources are sorted
by the value of the primary attribute, if any, or else the
first value in the list, if any. If the attribute is complex
the attribute name must be a path to a sub-attribute in
standard <xref format="default"
target="attribute-notation">attribute notation</xref> ; e.g.,
<spanx style="verb">sortBy=name.givenName</spanx>. For all
attribute types, if there is no data for the specified <spanx
style="verb">sortBy</spanx> value they are sorted via the
<spanx style="verb">sortOrder</spanx> parameter; i.e., they
are ordered last if ascending and first if descending.</t>
<t hangText="sortOrder:">The order in which the sortBy
parameter is applied. Allowed values are <spanx style="verb">ascending</spanx>
and <spanx style="verb">descending</spanx>. If a value for
sortBy is provided and no sortOrder is specified, the
sortOrder SHALL default to ascending. String type attributes
are case insensitive by default unless the attribute type is
defined as a case exact string. <spanx style="verb">sortOrder</spanx>
MUST sort according to the attribute type; i.e., for caee
insensitive attributes, sort the result using case
insensitive, unicode alphabetic sort order, with no specific
locale implied and for case exact attribute types, sort the
result using case sensitive, Unicode alphabetic sort
order.</t>
</list></t>
</section>
<section anchor="pagination" title="Pagination">
<t>Pagination parameters can be used together to "page through"
large numbers of resources so as not to overwhelm the client or
service provider. Pagination is not session based hence clients
SHOULD never assume repeatable results. For example, a request for
a list of 10 resources beginning with a startIndex of 1 may return
different results when repeated as a resource in the original
result could be deleted or new ones could be added in-between
requests. Pagination parameters and general behavior are derived
from the OpenSearch Protocol <xref target="OpenSearch"/>.</t>
<t>The following table describes the URL pagination
parameters.</t>
<texttable align="center"
anchor="consumer-pagination-options-table"
title="Pagination Request parameters">
<ttcol align="left">Parameter</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Default</ttcol>
<c>startIndex</c>
<c>The 1-based index of the first search result. A value less
than 1 SHALL be interpreted as 1.</c>
<c>1</c>
<c>count</c>
<c>Non-negative Integer. Specifies the desired maximum number of
search results per page; e.g., 10. A negative value SHALL be
interpreted as <spanx style="verb">0</spanx>. A value of <spanx
style="verb">0</spanx> indicates no resource results are to be
returned except for <spanx style="verb">totalResults</spanx>.</c>
<c>None. When specified the service provider MUST not return
more results than specified though MAY return fewer results. If
unspecified, the maximum number of results is set by the service
provider.</c>
</texttable>
<t>The following table describes the query response pagination
attributes specified by the service provider.</t>
<texttable align="center"
anchor="response-pagination-options-table"
title="Pagination Response Elements">
<ttcol align="left">Element</ttcol>
<ttcol align="left">Description</ttcol>
<c>itemsPerPage</c>
<c>Non-negative Integer. Specifies the number of search results
returned in a query response page; e.g., 10.</c>
<c>totalResults</c>
<c>Non-negative Integer. Specifies the total number of results
matching the client query; e.g., 1000.</c>
<c>startIndex</c>
<c>The 1-based index of the first result in the current set of
search results; e.g., 1.</c>
</texttable>
<t><figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<preamble>For example, to retrieve the first 10 Users set the
startIndex to 1 and the count to 10:</preamble>
<artwork align="left" alt="" height="" name="" type=""
width="" xml:space="preserve">
GET /Users?startIndex=1&count=10
Host: example.com
Accept: application/scim+json
Authorization: Bearer h480djs93hd8
</artwork>
</figure> <figure align="left" alt="" height=""
suppress-title="false" title="" width="">
<preamble>The response to the query above returns metadata
regarding paging similar to the following example (actual
resources removed for brevity):</preamble>
<artwork align="left" alt="" height="" name="" type=""
width="" xml:space="preserve">
{
"totalResults":100,
"itemsPerPage":10,
"startIndex":1,
"schemas":["urn:scim:api:messages:2.0"],
"Resources":[{
...
}]
}
</artwork>
</figure> Given the example above, to continue paging set the
startIndex to 11 and re-fetch; i.e.,
/Users?startIndex=11&count=10</t>
</section>
<section anchor="attributesParam" title="Attributes">
<t>The following attributes control which attributes SHALL be
returned with a returned resource.<list style="hanging">
<t hangText="attributes">A multi-valued list of strings
indicating the names of resource attributes to return in the
response overriding the set of attributes that would be
returned by default. Attribute names MUST be in standard <xref
format="default" target="attribute-notation">attribute
notation</xref> form. See <xref format="default"
target="addtl-retrieval-query-params">additional retrieval
query parameters</xref>. OPTIONAL.</t>
<t hangText="excludedAttributes">A multi-valued list of
strings indicating the names of resource attributes to be
removed from the default set of attributes to return. This
parameter SHALL have no effect on attributes whose schema
<spanx style="verb">returned</spanx> setting is <spanx
style="verb">always</spanx> see <xref
target="I-D.ietf-scim-core-schema">Server Schema</xref>.
Attribute names MUST be in standard <xref format="default"
target="attribute-notation">attribute notation</xref> form.
See <xref format="default"
target="addtl-retrieval-query-params">additional retrieval
query parameters</xref>. OPTIONAL.</t>
</list></t>
</section>
</section>
<section anchor="query-post"
title="Querying Resources Using HTTP POST">
<t>Clients MAY execute queries without passing parameters on the URL
by using the HTTP POST verb combined with the '/.search' path
extension. The inclusion of '/.search' on the end of a valid SCIM
endpoint SHALL be used to indicate the HTTP POST verb is intended to
be a query operation.</t>
<t>To create a new search result set, a SCIM client sends an HTTP
POST request to the desired SCIM resource endpoint (ending in
'/.search'). The body of the POST request MAY include any of the
parameters as defined in <xref target="query-resources"/>.</t>
<t>Search requests MUST be identified using the following URI:
'urn:scim:api:messages:2.0:SearchRequest'. The following attributes
are defined for search requests:</t>
<t><list style="hanging">
<t hangText="attributes">A multi-valued list of strings
indicating the names of resource attributes to return in the
response overriding the set of attributes that would be returned
by default. Attribute names MUST be in standard <xref
format="default" target="attribute-notation">attribute
notation</xref> form. See <xref format="default"
target="addtl-retrieval-query-params">additional retrieval query
parameters</xref>. OPTIONAL.</t>
<t hangText="excludedAttributes">A multi-valued list of strings
indicating the names of resource attributes to be removed from
the default set of attributes to return. This parameter SHALL
have no effect on attributes whose schema <spanx style="verb">returned</spanx>
setting is <spanx style="verb">always</spanx> see <xref
target="I-D.ietf-scim-core-schema">Server Schema</xref>.
Attribute names MUST be in standard <xref format="default"
target="attribute-notation">attribute notation</xref> form. See
<xref format="default"
target="addtl-retrieval-query-params">additional retrieval query
parameters</xref>. OPTIONAL.</t>
<t hangText="filter">The filter string used to request a subset
of resources. The filter string MUST be a valid <xref
format="default" target="filtering">filter</xref> expression.
OPTIONAL.</t>
<t hangText="sortBy">A string indicating the attribute whose
value SHALL be used to order the returned responses. The sortBy
attribute MUST be in standard <xref format="default"
target="attribute-notation">attribute notation</xref> form. See
<xref format="default" target="sorting">sorting</xref>.
OPTIONAL.</t>
<t hangText="sortOrder">A string indicating the order in which
the sortBy parameter is applied. Allowed values are "ascending"
and "descending". See <xref format="default"
target="sorting">sorting</xref>. OPTIONAL.</t>
<t hangText="startIndex">An integer indicating the 1-based index
of the first search result. See <xref format="default"
target="pagination">pagination</xref>. OPTIONAL.</t>
<t hangText="count">An integer indicating the desired maximum
number of search results per page. See <xref format="default"
target="pagination">pagination</xref>. OPTIONAL.</t>
</list></t>
<t>After receiving a HTTP POST request, a response is returned as
specified in <xref target="query-resources"/>.</t>
<figure align="left" alt="POST Example" anchor="POSTExample"
title="Example POST Search Request">
<preamble>The following example shows an HTTP POST Search request
with search parameters attributes, filter, and count
included:</preamble>
<artwork align="center" height="13">POST /.search
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:api:messages:2.0:SearchRequest"],
"attributes": ["displayName", "userName"],
"filter": "displayName sw \"smith\"",
"startIndex": 1,
"count": 10
}</artwork>
</figure>
<t/>
<figure align="left" anchor="ExampleResponse"
title="Example POST Search Response">
<preamble>A search response is shown with the first page of
results. For brevity reasons, only two matches are shown: one User
and one Group.</preamble>
<artwork align="center">HTTP/1.1 200 OK
Content-Type: application/scim+json
Location: https://example.com/.search
{
"schemas": ["urn:scim:api:messages:2.0:ListResponse"],
"totalResults":100,
"itemsPerPage":10,
"startIndex":1,
"Resources":[
{
"meta":{
"location":
"https://example.com/Users/2819c223-7f76-413861904646",
"resourceType":"User",
"lastModified": ...
},
"userName":"jsmith",
"displayName":"Smith, James"
},
{
"meta":{
"location":
"https://example.com/Groups/c8596b90-7539-4f20968d1908",
"resourceType":"Group",
"lastModified": ...
},
"displayName":"Smith Family"
},
...
]
} </artwork>
</figure>
</section>
</section>
<section title="Modifying Resources" toc="default">
<t>Resources can be modified in whole or in part via PUT or PATCH,
respectively. Implementers MUST support PUT as specified in <xref
target="RFC7231">Section 4.3</xref>. Resources such as Groups may be
very large hence implementers SHOULD support <xref
target="RFC5789">PATCH </xref> to enable partial resource
modifications.</t>
<section anchor="edit-resource-with-put" title="Replacing with PUT"
toc="default">
<t>HTTP PUT is used to perform a full update of a resource's
attributes. Clients that MAY have previously retrieved the entire
resource in advance and revised it, MAY replace the resource using
an HTTP PUT. Because SCIM resource identifiers are typically
assigned by the service provider, HTTP PUT SHOULD NOT be used to
create new resources.</t>
<t>As the operation intent is to replace all attributes, SCIM
clients MAY send all attributes regardless of each attribute's
mutability. The server will apply attribute by attribute replace
according to the following attribute mutability rules: <list
style="hanging">
<t hangText="readWrite, writeOnly">Any values provided SHALL
replace the existing attribute values.</t>
<t hangText="immutable">If value(s) are already set for the
attribute, the input value(s) MUST match or HTTP status 400
SHOULD be returned with error code <spanx style="verb">mutability</spanx>.
If the service provider has no existing values, the new value(s)
SHALL be applied.</t>
<t hangText="readOnly">Any values provided (e.g.
meta.resourceType) SHALL be ignored.</t>
</list></t>
<t>If an attribute is <spanx style="verb">required</spanx>, clients
MUST specify the attribute in the PUT request.</t>
<t>Attributes whose mutability is <spanx style="verb">readWrite</spanx>,
that are omitted from the request body, MAY be assumed to be not
asserted by the client. The service provider MAY assume any existing
values are to be cleared or the service provider MAY assign a
default value to the final resource representation. Service
providers MAY take into account whether a client has access to, or
understands, all of the resource's attributes when deciding whether
non-asserted attributes SHALL be removed or defaulted. Clients that
would like to override a server defaults, MAY specify <spanx
style="verb">null</spanx> for a single-valued attribute or an empty
array <spanx style="verb">[]</spanx> for a multi-valued attribute to
clear all values.</t>
<t>Unless otherwise specified a successful PUT operation returns a
200 OK response code and the entire resource within the response
body, enabling the client to correlate the client's and Provider's
views of the updated resource. Example:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PUT /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas":["urn:scim:api:messages:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara",
"middleName":"Jane"
},
"roles":[],
"emails":[
{
"value":"bjensen@example.com"
},
{
"value":"babs@jensen.org"
}
]
}</artwork>
</figure>
<t/>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<preamble>The service responds with the entire, updated
User:</preamble>
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 200 OK
Content-Type: application/scim+json
ETag: W/"b431af54f0671a2"
Location:"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646"
{
"schemas":["urn:scim:api:messages:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara",
"middleName":"Jane"
},
"emails":[
{
"value":"bjensen@example.com"
},
{
"value":"babs@jensen.org"
}
],
"meta": {
"resourceType":"User",
"created":"2011-08-08T04:56:22Z",
"lastModified":"2011-08-08T08:00:12Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"b431af54f0671a2\""
}
} </artwork>
</figure>
</section>
<section anchor="edit-resource-with-patch"
title="Modifying with PATCH" toc="default">
<t>HTTP PATCH is an OPTIONAL server function that enables clients to
update one or more attributes of a SCIM resource using a sequence of
operations to <spanx style="verb">add</spanx>, <spanx style="verb">remove</spanx>,
or <spanx style="verb">replace</spanx> values. The general form of
the SCIM patch request is based on JavaScript Object Notation (JSON)
Patch <xref target="RFC6902"/>. One difference between SCIM patch
and JSON patch is that SCIM servers do not support array indexing
and may not support all <xref target="RFC6902"/> operation
types.</t>
<t>The body of an HTTP PATCH request MUST contain one or more patch
operation objects. A patch operation object MUST have exactly one
"op" member, whose value indicates the operation to perform and MAY
be one of <spanx style="verb">add</spanx>, <spanx style="verb">remove</spanx>,
or <spanx style="verb">replace</spanx>. The semantics of each
operation are defined below.</t>
<t>Each operation object MUST contain the following <spanx
style="verb">schemas</spanx> URI: <spanx style="verb">urn:scim:api:messages:2.0:PatchOp</spanx></t>
<t/>
<figure align="left" anchor="pathABNF" title="SCIM Patch PATH Rule">
<preamble>Operation objects MUST have exactly one <spanx
style="verb">path</spanx> member which is a <spanx style="verb">String</spanx>
containing an attribute path as specified by the following ABNF
syntax rule:</preamble>
<artwork align="center">PATH = attrPath / valuePath [subAttr]</artwork>
</figure>
<t>The rules, <spanx style="verb">attrPath</spanx>, <spanx
style="verb">valuePath</spanx>, and <spanx style="verb">subAttr</spanx>
are defined in <xref target="filtering"/>. The <spanx style="verb">valuePath</spanx>
rule allows specific values of a complex, multi-valued attribute to
be selected. <figure align="left">
<preamble>Valid examples of <spanx style="verb">path</spanx>
values are as follows:</preamble>
<artwork align="center">"path":"members"
"path":"name.familyName"
"path":"addresses[type eq \"work\"]"
"path":"members[value eq
\"2819c223-7f76-453a-919d-413861904646\"]"
"path":"members[value eq
\"2819c223-7f76-453a-919d-413861904646\"].displayName"</artwork>
</figure></t>
<t>Each operation against an attribute MUST be compatible with the
attribute's mutability and schema as defined in the <xref
target="I-D.ietf-scim-core-schema">Attribute Types Section
of</xref>. For example, a client MAY NOT modify an attribute that
has mutability <spanx style="verb">readOnly</spanx> or <spanx
style="verb">immutable</spanx>. However, a client MAY <spanx
style="verb">add</spanx> a value to an <spanx style="verb">immutable</spanx>
attribute if the attribute had no previous value. An operation that
is not compatibile with an attribute's mutability or schema SHALL
return an error as indicated below.</t>
<t>Each patch operation represents a single action to be applied to
the same SCIM resource specified by the request URI. Operations are
applied sequentially in the order they appear in the array. Each
operation in the sequence is applied to the target resource; the
resulting resource becomes the target of the next operation.
Evaluation continues until all operations are successfully applied
or until an error condition is encountered.</t>
<t>A patch request, regardless of the number of operations, SHALL be
treated as atomic. If a single operation encounters an error
condition, the original SCIM resource MUST be restored, and a
failure status SHALL be returned.</t>
<t>If a request fails. the server SHALL return an HTTP response
status code and a JSON detail error response as defined in <xref
target="http-response-codes"/>.</t>
<t>On successful completion, the server MUST return either a 200 OK
response code and the entire resource (subject to the "attributes"
query parameter - see <xref format="default"
target="addtl-retrieval-query-params">Additional Retrieval Query
Parameters</xref> ) within the response body, or a 204 No Content
response code and the appropriate response headers for a successful
patch request. The server MUST return a 200 OK if the "attributes"
parameter is specified on the request.</t>
<section anchor="addOp" title="Add Operation">
<t>The <spanx style="verb">add</spanx> operation performs one of
the following functions, depending upon what the target location
indicated by <spanx style="verb">path</spanx> references: <list
style="symbols">
<t>If the target location does not exist, the attribute and
value is added.</t>
<t>If the target location specifies a multi-valued attribute,
a new value is added to the attribute.</t>
<t>if the target location specifies a single-valued attribute,
the existing value is replaced.</t>
<t>If the target location specifies an attribute that does not
exist (has no value), the attribute is added with the new
value.</t>
<t>If the target location exists, the value is replaced.</t>
<t>If the target location already contains the value
specified, no changes SHOULD be made to the resource and a
success response SHOULD be returned. Unless other operations
change the resource, this operation SHALL NOT change the
modify timestamp of the resource.</t>
</list></t>
<t>The operation MUST contain a <spanx style="verb">value</spanx>
member whose content specifies the value to be added. The value
MAY be a quoted value OR it may be a JSON object containing the
sub-attributes of the complex attribute specified in the
operation's <spanx style="verb">path</spanx>.</t>
<t/>
<figure align="left">
<preamble>The following example shows how to add a member to a
group. Some text removed for readability ("..."):</preamble>
<artwork>PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"add",
"path":"members",
"value":[
{
"display": "Babs Jensen",
"$ref": "https://example.com/v2/Users/2819c223...413861904646",
"value": "2819c223-7f76-453a-919d-413861904646"
}
]
}</artwork>
</figure>
<t>The "display" Sub-Attribute in this request is optional since
the value attribute uniquely identifies the user to be added. If
the user was already a member of this group, no changes should be
made to the resource and a success response should be returned.
The server responds with either the entire updated Group or no
response body:</t>
<figure>
<artwork>HTTP/1.1 204 No Content
Authorization: Bearer h480djs93hd8
ETag: W/"b431af54f0671a2"
Location: "https://example.com/Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce"</artwork>
</figure>
</section>
<section anchor="removeOp" title="Remove Operation">
<t>The <spanx style="verb">remove</spanx> operation removes the
value at the target location specified by the <spanx style="verb">path</spanx>.
The operation performs the following functions depending on the
target location specified by <spanx style="verb">path</spanx> :
<list style="symbols">
<t>If the target location is a single-value attribute, the
attribute and its associated value is removed.</t>
<t>If the target location is a multi-valued attribute and no
filter is specified, the attribute and all values are
removed.</t>
<t>If the target location is a multi-valued attribute and a
complex filter is specified comparing a <spanx style="verb">value</spanx>,
the values matched by the filter are removed.</t>
<t>If the target location is a complex-multi-valued attribute
and a complex filter is specified based on the attribute's
sub-attributes, the matching records are removed.</t>
</list></t>
<t>The following example shows how to remove a member from a
group. As with the previous example, the "display" Sub-Attribute
is optional. If the user was not a member of this group, no
changes should be made to the resource and a success response
should be returned.</t>
<t>Note that server responses have been omitted for the rest of
the PATCH examples.</t>
<figure align="left">
<preamble>Remove a single member from a group. Some text removed
for readability ("..."):</preamble>
<artwork>PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"remove",
"path":"members[value eq \"2819c223-7f76-...413861904646\"]"
}</artwork>
</figure>
<figure align="left">
<preamble>Remove all members of a group:</preamble>
<artwork>PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{ "schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"remove","path":"members"}</artwork>
</figure>
<figure align="left">
<preamble>Removal of a value from a complex-multi-valued
attribute (request headers removed for brevity):</preamble>
<artwork>{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"remove",
"path":"emails[type eq \"work\" and value ew \"example.com\"]"
}</artwork>
</figure>
<figure align="left">
<preamble>Example request to remove and add a member. Some text
removed for readability ("..."):</preamble>
<artwork>PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
[
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"remove",
"path":"members[value eq\"2819c223...919d-413861904646\"]"
},
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"add",
"path":"members",
"value": [
{
"display": "James Smith",
"$ref": "https://example.com/v2/Users/08e1d05d...473d93df9210",
"value": "08e1d05d...473d93df9210"
}
]
}
]</artwork>
</figure>
<figure align="left">
<preamble>The following example shows how to replace all the
members of a group with a different members list. Some text
removed for readabilty ("..."):</preamble>
<artwork>PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
[
{ "schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"remove","path":"members"},
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"add",
"path":"members",
"value":[
{
"display": "Babs Jensen",
"$ref": "https://example.com/v2/Users/2819c223...413861904646",
"value": "2819c223-7f76-453a-919d-413861904646"
},
{
"display": "James Smith",
"$ref": "https://example.com/v2/Users/08e1d05d...473d93df9210",
"value": "08e1d05d-121c-4561-8b96-473d93df9210"
}]
}
]</artwork>
</figure>
</section>
<section anchor="replaceOp" title="Replace Operation">
<t>The <spanx style="verb">replace</spanx> operation replaces the
value at the target location specified by the <spanx style="verb">path</spanx>.
The operation performs the following functions depending on the
target location specified by <spanx style="verb">path</spanx> :
<list style="symbols">
<t>If the target location is a single-value attribute, the
attributes value is replaced.</t>
<t>If the target location is a multi-valued attribute and no
filter is specified, the attribute and all values are
replaced.</t>
<t>If the target location is a multi-valued attribute and a
complex filter is specified comparing a <spanx style="verb">value</spanx>,
the values matched by the filter are replaced.</t>
<t>If the target location is a complex-multi-valued attribute
and a complex filter is specified based on the attribute's
sub-attributes, the matching records are replaced.</t>
<t>If the target location is a complex-multi-valued attribute
with a complex filter and a specific sub-attribute (e.g.
<spanx style="verb">addresses[type eq "work"].streetAddress</spanx>
), the matching sub-attribute of the matching record is
replaced.</t>
</list></t>
<figure align="left">
<preamble>The following example shows how to replace all the
members of a group with a different members list in a single
replace operation. Some text removed for readability
("..."):</preamble>
<artwork>PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"replace",
"path":"members",
"value":[
{
"display": "Babs Jensen",
"$ref": "https://example.com/v2/Users/2819c223...413861904646",
"value": "2819c223...413861904646"
},
{
"display": "James Smith",
"$ref": "https://example.com/v2/Users/08e1d05d...473d93df9210",
"value": "08e1d05d...473d93df9210"
}
]
}</artwork>
</figure>
<figure align="left">
<preamble>The following example shows how to change a User's
entire "work" address.</preamble>
<artwork>PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"replace",
"path":"addresses[type eq \"work\"]",
"value":
{
"type": "work",
"streetAddress": "911 Universal City Plaza",
"locality": "Hollywood",
"region": "CA",
"postalCode": "91608",
"country": "US",
"formatted": "911 Universal City Plaza\nHollywood, CA 91608 US",
"primary": true
}
}</artwork>
</figure>
<figure align="left">
<preamble>The following example shows how to change a User's
address. Since address does not have a value Sub-Attribute, the
existing address must be removed and the modified address
added.</preamble>
<artwork>PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:api:messages:2.0:PatchOp"],
"op":"replace",
"path":"addresses[type eq \"work\"].streetAddress",
"value":"911 Universal City Plaza"
}</artwork>
</figure>
</section>
</section>
</section>
<section anchor="delete-resource" title="Deleting Resources"
toc="default">
<t>Clients request resource removal via DELETE. Service providers MAY
choose not to permanently delete the resource, but MUST return a 404
error code for all operations associated with the previously deleted
Id. Service providers MUST also omit the resource from future query
results. In addition the service provider MUST not consider the
deleted resource in conflict calculation. For example if a User
resource is deleted, a CREATE request for a User resource with the
same userName as the previously deleted resource should not fail with
a 409 error due to userName conflict.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="center" alt="" height="" name="" type="" width=""
xml:space="preserve">
DELETE /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Authorization: Bearer h480djs93hd8
If-Match: W/"c310cd84f0281b7"
</artwork>
</figure>
<t>In response to a successful delete, the server SHALL respond with
successful HTTP status 204 (No Content). A non-normative example
response:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="center" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 204 No Content
</artwork>
</figure>
<t>Example: client attempt to retrieve the previously deleted User</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="center" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>Server Response:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="center" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 404 NOT FOUND
{
"schemas": ["urn:scim:api:messages:2.0:Error"],
"Errors":[
{
"description":"Resource 2819c223-7f76-453a-919d-413861904646 not found",
"code":"404"
}
]
}
</artwork>
</figure>
</section>
<section anchor="bulk-resources" title="Bulk" toc="default">
<t>The SCIM bulk operation is an optional server feature that enables
clients to send a potentially large collection of resource operations
in a single request. The body of a a bulk operation contains a set of
HTTP resource operations using one of the API supported HTTP methods;
i.e., POST, PUT, PATCH or DELETE.</t>
<t>Bulk requests are identified using the following URI:
'urn:scim:api:messages:2.0:BulkRequest'. Bulk responses are identified
using the following URI: 'urn:scim:api:messages:2.0:BulkResponse'.
Bulk requests and bulk responses share many attributes. Unless
otherwise specified, each attribute below is present in both bulk
requests and bulk responses.</t>
<t>The following Singular Attribute is defined in addition to the
common attributes defined in SCIM core schema.</t>
<t><list style="hanging">
<t hangText="failOnErrors">An Integer specifying the number of
errors that the service provider will accept before the operation
is terminated and an error response is returned. OPTIONAL in a
request. Not valid in a response.</t>
</list></t>
<t>The following Complex Multi-valued Attribute is defined in addition
to the common attributes defined in core schema.</t>
<t><list style="hanging">
<t hangText="Operations">Defines operations within a bulk job.
Each operation corresponds to a single HTTP request against a
resource endpoint. REQUIRED. <list style="hanging">
<t hangText="method">The HTTP method of the current operation.
Possible values are POST, PUT, PATCH or DELETE. REQUIRED.</t>
<t hangText="bulkId">The transient identifier of a newly
created resource, unique within a bulk request and created by
the client. The bulkId serves as a surrogate resource id
enabling clients to uniquely identify newly created resources
in the Response and cross reference new resources in and
across operations within a bulk request. REQUIRED when method
is POST.</t>
<t hangText="version">The current resource version. Version is
REQUIRED if the service provider supports ETags and the method
is PUT, DELETE, or PATCH.</t>
<t hangText="path">The resource's relative path. If the method
is POST the value must specify a resource type endpoint; e.g.,
/Users or /Groups whereas all other method values must specify
the path to a specific resource; e.g.,
/Users/2819c223-7f76-453a-919d-413861904646. REQUIRED in a
request.</t>
<t hangText="data">The resource data as it would appear for a
single POST, PUT or PATCH resource operation. REQUIRED in a
request when method is POST, PUT and PATCH.</t>
<t hangText="location">The resource endpoint URL. REQUIRED in
a response, except in the event of a POST failure.</t>
<t hangText="status">A complex type that contains information
about the success or failure of one operation within the bulk
job. REQUIRED in a response. <list style="hanging">
<t hangText="code">The HTTP response code that would have
been returned if a a single HTTP request would have been
used. REQUIRED.</t>
<t hangText="description">A human readable error message.
REQUIRED when an error occurred.</t>
</list></t>
</list></t>
</list></t>
<t>If a bulk job is processed successfully the HTTP response code 200
OK MUST be returned, otherwise an appropriate HTTP error code MUST be
returned.</t>
<t>The service provider MUST continue performing as many changes as
possible and disregard partial failures. The client MAY override this
behavior by specifying a value for failOnErrors attribute. The
failOnErrors attribute defines the number of errors that the service
provider should accept before failing the remaining operations
returning the response.</t>
<t>To be able to reference a newly created resource the attribute
bulkId MUST be specified when creating new resources. The bulkId is
defined by the client as a surrogate identifier in a POST operation.
The service provider MUST return the same bulkId together with the
newly created resource. The bulkId can then be used by the client to
map the service provider id with the bulkId of the created
resource.</t>
<t>There can be more then one operation per resource in each bulk job.
The Service client MUST take notice of the unordered structure of JSON
and the service provider can process operations in any order. For
example, if the Service client sends two PUT operations in one
request, the outcome is non-deterministic.</t>
<t>The service provider response MUST include the result of all
processed operations. A location attribute that includes the
resource's end point MUST be returned for all operations excluding
failed POSTs. The status attribute includes information about the
success or failure of one operation within the bulk job. The attribute
status MUST include the code attribute that holds the HTTP response
code that would have been returned if a single HTTP request would have
been used. If an error occurred the status MUST also include the
description attribute containing a human readable explanation of the
error.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
"status": {
"code": "201"
}
</artwork>
</figure>
<t>The following is an example of a status in a failed operation.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
"status": {
"code": "400",
"description": "Request is unparseable, syntactically incorrect, or violates schema."
}</artwork>
</figure>
<t>The following example shows how to add, update, and remove a user.
The failOnErrors attribute is set to '1' indicating the service
provider should return on the first error. The POST operation's bulkId
value is set to 'qwerty' enabling the client to match the new User
with the returned resource id
'92b725cd-9465-4e7d-8c16-01f8e146b87a'.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:api:messages:2.0:BulkRequest"],
"failOnErrors":1,
"Operations":[
{
"method":"POST",
"path":"/Users",
"bulkId":"qwerty",
"data":{
"schemas": ["urn:scim:api:messages:2.0:User"],
"userName":"Alice"
}
},
{
"method":"PUT",
"path":"/Users/b7c14771-226c-4d05-8860-134711653041",
"version":"W\/\"3694e05e9dff591\"",
"data":{
"schemas": ["urn:scim:api:messages:2.0:User"],
"id":"b7c14771-226c-4d05-8860-134711653041",
"userName":"Bob"
}
},
{
"method": "PATCH",
"path": "/Users/5d8d29d3-342c-4b5f-8683-a3cb6763ffcc",
"version": "W/\"edac3253e2c0ef2\"",
"data": {[
{
"op": "remove",
"path": "nickName"
},
{
"op": "add",
"path": "userName",
"value": "Dave"
}
]}
},
{
"method":"DELETE",
"path":"/Users/e9025315-6bea-44e1-899c-1e07454e468b",
"version":"W\/\"0ee8add0a938e1a\""
}
]
}</artwork>
</figure>
<t>The service provider returns the following response.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"schemas": ["urn:scim:api:messages:2.0:BulkResponse"],
"Operations": [
{
"location": "https://example.com/v2/Users/92b725cd-9465-4e7d-8c16-01f8e146b87a",
"method": "POST",
"bulkId": "qwerty",
"version": "W\/\"oY4m4wn58tkVjJxK\"",
"status": {
"code": "201"
}
},
{
"location": "https://example.com/v2/Users/b7c14771-226c-4d05-8860-134711653041",
"method": "PUT",
"version": "W\/\"huJj29dMNgu3WXPD\"",
"status": {
"code": "200"
}
},
{
"location": "https://example.com/v2/Users/5d8d29d3-342c-4b5f-8683-a3cb6763ffcc",
"method": "PATCH",
"version": "W\/\"huJj29dMNgu3WXPD\"",
"status": {
"code": "200"
}
},
{
"location": "https://example.com/v2/Users/e9025315-6bea-44e1-899c-1e07454e468b",
"method": "DELETE",
"status": {
"code": "204"
}
}
]
}</artwork>
</figure>
<t>The following response is returned if an error occurred when
attempting to create the User 'Alice'. The service provider stops
processing the bulk operation and immediately returns a response to
the client. The response contains the error and any successful results
prior to the error.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"schemas": ["urn:scim:api:messages:2.0:BulkResponse"],
"Operations": [
{
"method": "POST",
"bulkId": "qwerty",
"status": {
"code": "400",
"description": "Request is unparseable, syntactically incorrect, or violates schema."
}
}
]
}</artwork>
</figure>
<t>If the failOnErrors attribute is not specified or the service
provider has not reached the error limit defined by the client the
service provider will continue to process all operations. The
following is an example in which all operations failed.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"schemas": ["urn:scim:api:messages:2.0:BulkResponse"],
"Operations": [
{
"method": "POST",
"bulkId": "qwerty",
"status": {
"code": "400",
"description": "Request is unparseable, syntactically incorrect, or violates schema."
}
},
{
"location": "https://example.com/v2/Users/b7c14771-226c-4d05-8860-134711653041",
"method": "PUT",
"status": {
"code": "412",
"description": "Failed to update as user changed on the server since you last retrieved it."
}
},
{
"location": "https://example.com/v2/Users/5d8d29d3-342c-4b5f-8683-a3cb6763ffcc",
"method": "PATCH",
"status": {
"code": "412",
"description": "Failed to update as user changed on the server since you last retrieved it."
}
},
{
"location": "https://example.com/v2/Users/e9025315-6bea-44e1-899c-1e07454e468b",
"method": "DELETE",
"status": {
"code": "404",
"description": "Specified resource; e.g., User, does not exist."
}
}
]
}</artwork>
</figure>
<t>The client can, within one bulk operation, create a new User, a new
Group and add the newly created User to the newly created Group. In
order to add the new User to the Group the client must use the
surrogate id attribute, bulkId, to reference the User. The bulkId
attribute value must be pre-pended with the literal "bulkId:"; e.g.,
if the bulkId is 'qwerty' the value is “bulkId:qwerty”. The service
provider MUST replace the string “bulkId:qwerty” with the permanent
resource id once created.</t>
<t>The following example creates a User with the userName 'Alice' and
a Group with the displayName 'Tour Guides' with Alice as a member.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:api:messages:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"path": "/Users",
"bulkId": "qwerty",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:User"],
"userName": "Alice"
}
},
{
"method": "POST",
"path": "/Groups",
"bulkId": "ytrewq",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Tour Guides",
"members": [
{
"type": "user",
"value": "bulkId:qwerty"
}
]
}
}
]
}</artwork>
</figure>
<t>The service provider returns the following response.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"schemas": ["urn:scim:api:messages:2.0:BulkResponse"],
"Operations": [
{
"location": "https://example.com/v2/Users/92b725cd-9465-4e7d-8c16-01f8e146b87a",
"method": "POST",
"bulkId": "qwerty",
"version": "W\/\"4weymrEsh5O6cAEK\"",
"status": {
"code": "201"
}
},
{
"location": "https://example.com/v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a",
"method": "POST",
"bulkId": "ytrewq",
"version": "W\/\"lha5bbazU3fNvfe5\"",
"status": {
"code": "201"
}
}
]
}</artwork>
</figure>
<t>A subsequent request for the 'Tour Guides' Group
('e9e30dba-f08f-4109-8486-d5c6a331660a') returns the following:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a
Host: example.com
Accept: application/scim+json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/scim+json
Location: https://example.com/v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a
ETag: W/"lha5bbazU3fNvfe5"
{
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"id": "e9e30dba-f08f-4109-8486-d5c6a331660a",
"displayName": "Tour Guides",
"meta": {
"resourceType": "Group",
"created": "2011-08-01T18:29:49.793Z",
"lastModified": "2011-08-01T20:31:02.315Z",
"location": "https://example.com/v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a",
"version": "W\/\"lha5bbazU3fNvfe5\""
},
"members": [
{
"value": "92b725cd-9465-4e7d-8c16-01f8e146b87a",
"$ref": "https://example.com/v2/Users/92b725cd-9465-4e7d-8c16-01f8e146b87a",
"type": "User"
}
]
}</artwork>
</figure>
<t>Extensions that include references to other resources MUST be
handled in the same way by the service provider. The following example
uses the bulkId attribute within the enterprise extension managerId
attribute.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:api:messages:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"path": "/Users",
"bulkId": "qwerty",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:User"],
"userName": "Alice"
}
},
{
"method": "POST",
"path": "/Users",
"bulkId": "ytrewq",
"data": {
"schemas": [
"urn:scim:schemas:core:2.0:User",
"urn:scim:schemas:extension:enterprise:2.0:User"
],
"userName": "Bob",
"urn:scim:schemas:extension:enterprise:2.0:User": {
"employeeNumber": "11250",
"manager": {
"managerId": "batchId:qwerty",
"displayName": "Alice"
}
}
}
}
]
}</artwork>
</figure>
<t>The service provider MUST try to resolve circular cross references
between resources in a single bulk job but MAY stop after a failed
attempt and instead return the status code 409 Conflict. The following
example exhibits the potential conflict.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:api:messages:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"path": "/Groups",
"bulkId": "qwerty",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group A",
"members": [
{
"type": "group",
"value": "bulkId:ytrewq"
}
]
}
},
{
"method": "POST",
"path": "/Groups",
"bulkId": "ytrewq",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group B",
"members": [
{
"type": "group",
"value": "bulkId:qwerty"
}
]
}
}
]
}</artwork>
</figure>
<t>If the service provider resolved the above circular references the
following is returned from a subsequent GET request.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /v2/Groups?filter=displayName sw 'Group'
Host: example.com
Accept: application/scim+json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/scim+json
{
"schemas": ["urn:scim:api:messages:2.0:ListResponse"],
"totalResults": 2,
"Resources": [
{
"id": "c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group A",
"meta": {
"resourceType": "Group",
"created": "2011-08-01T18:29:49.793Z",
"lastModified": "2011-08-01T18:29:51.135Z",
"location": "https://example.com/v2/Groups/c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"version": "W\/\"mvwNGaxB5SDq074p\""
},
"members": [
{
"value": "6c5bb468-14b2-4183-baf2-06d523e03bd3",
"$ref": "https://example.com/v2/Groups/6c5bb468-14b2-4183-baf2-06d523e03bd3",
"type": "Group"
}
]
},
{
"id": "6c5bb468-14b2-4183-baf2-06d523e03bd3",
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group B",
"meta": {
"resourceType": "Group",
"created": "2011-08-01T18:29:50.873Z",
"lastModified": "2011-08-01T18:29:50.873Z",
"location": "https://example.com/v2/Groups/6c5bb468-14b2-4183-baf2-06d523e03bd3",
"version": "W\/\"wGB85s2QJMjiNnuI\""
},
"members": [
{
"value": "c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"$ref": "https://example.com/v2/Groups/c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"type": "Group"
}
]
}
]
}</artwork>
</figure>
<t>The service provider MUST define the maximum number of operations
and maximum payload size a client may send in a single request. If
either limits are exceeded the service provider MUST return the HTTP
response code 413 Request Entity Too Large. The returned response MUST
specify the limit exceeded in the body of the error response.</t>
<t>The following example the client sent a request exceeding the
service provider's max payload size of 1 megabyte.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/scim+json
Content-Type: application/scim+json
Authorization: Bearer h480djs93hd8
Content-Length: 4294967296
…</artwork>
</figure>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 413 Request Entity Too Large
Content-Type: application/scim+json
Location: https://example.com/v2/Bulk/yfCrVJhFIJagAHj8
{
"schemas":["urn:scim:api:messages:2.0:Error"],
"Errors":[
{
"description":"The size of the bulk operation exceeds the maxPayloadSize (1048576).",
"code":"413"
}
]
}
</artwork>
</figure>
</section>
<section anchor="io-format" title="Data Input/Output Formats">
<t>Servers MUST accept requests and respond with JSON structured
responses using UTF-8 encoding <xref target="RFC3629"/>, UTF-8 SHALL
be the default encoding format.</t>
<t>Clients using other encodings MUST specify the format in which the
data is submitted via HTTP header <spanx style="verb">Content-Type</spanx>
as specified in <xref target="RFC7231">Section 3.1.1.5</xref> and MAY
specify the desired response data format via an HTTP <spanx
style="verb">Accept</spanx> header ( <xref target="RFC7231">Section
5.3.2</xref> ); e.g., <spanx style="verb">Accept: application/scim+json</spanx>
or via URI suffix; e.g., <figure align="left" alt="" height=""
suppress-title="false" title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646.scim
Host: example.com
</artwork>
</figure></t>
<t>Service providers MUST support the accept header <spanx
style="verb">Accept: application/scim+json</spanx> and SHOULD support
header <spanx style="verb">Accept: application/json</spanx> both of
which specify JSON documents conforming to <xref target="RFC7159"/>.
The format defaults to <spanx style="verb">application/scim+json</spanx>
if no format is specified.</t>
<t>Singular attributes are encoded as string name-value-pairs in JSON;
e.g.,</t>
<figure>
<artwork>
"attribute": "value"
</artwork>
</figure>
<t>Multi-valued attributes in JSON are encoded as arrays; e.g.,</t>
<figure>
<artwork>
"attributes": [ "value1", "value2" ]
</artwork>
</figure>
<t>Elements with nested elements are represented as objects in JSON;
e.g,</t>
<figure>
<artwork>
"attribute": { "subattribute1": "value1", "subattribute2": "value2" }
</artwork>
</figure>
</section>
<section anchor="addtl-retrieval-query-params"
title="Additional Operation Response Parameters" toc="default">
<t>For any SCIM operation where a resource representation is returned
(e.g. HTTP GET), the attributes normally returned are defined as the
minimum attribute set plus default attributes. The minimum set are
those attributes whose schema have <spanx style="verb">returned</spanx>
set to <spanx style="verb">always</spanx>. The defaut attribute set
are those attributes whose schema have <spanx style="verb">returned</spanx>
set to <spanx style="verb">default</spanx>.</t>
<t>Clients MAY request a partial resource representation on any
operation that returns a resource within the response by specifying
either of the mutually exclusive URL query parameters <spanx
style="verb">attributes</spanx> OR <spanx style="verb">excludedAtributes</spanx>
as follows: <list hangIndent="8" style="hanging">
<t hangText="attributes">When specified, each resource returned
MUST contain the minimal set of resource attributes and MUST
contain no other attributes or sub-attributes other than those
explicitly requested. The query parameter attributes value is a
comma separated list of resource attribute names in standard <xref
format="default" target="attribute-notation">attribute
notation</xref> form (e.g. userName, name, emails).</t>
<t hangText="excludedAttributes">When specified, each resource
returned MUST contain the minimal set of resource attributes.
Additionally, the default set of attributes minus those attributes
listed in <spanx style="verb">excludedAttributes</spanx> are also
returned. The query parameter attributes value is a comma
separated list of resource attribute names in standard <xref
format="default" target="attribute-notation">attribute
notation</xref> form (e.g. userName, name, emails).</t>
</list>.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646?attributes=userName
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>Giving the response</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"a330bc54f0671c9"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"userName":"bjensen",
"meta":{
"resourceType": "User",
"created":"2011-08-01T18:29:49.793Z",
"lastModified":"2011-08-01T18:29:49.793Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"a330bc54f0671c9\""
}
}
</artwork>
</figure>
</section>
<section anchor="attribute-notation" title="Attribute Notation">
<t>All operations share a common scheme for referencing simple and
complex attributes. In general, attributes are identified by prefixing
the attribute name with its schema URN separated by a ':' character;
e.g., the core User resource attribute 'userName' is identified as
'urn:scim:schemas:core:2.0:User:userName'. Clients MAY omit core
schema attribute URN prefixes though MUST fully qualify extended
attributes with the associated resource URN; e.g., the attribute 'age'
defined in 'urn:hr:schemas:user' is fully encoded as
'urn:hr:schemas:user:age'. A Complex attributes' Sub-Attributes are
referenced via nested, dot ('.') notation; i.e., {urn}:{Attribute
name}.{Sub-Attribute name}. For example, the fully qualified path for
a User's givenName is urn:scim:schemas:core:2.0:User:name.givenName
All facets (URN, attribute and Sub-Attribute name) of the fully
encoded Attribute name are case insensitive.</t>
</section>
<section title=""/Me" Authenticated Subject Alias">
<t>A client MAY use a URL of the form <spanx style="verb"><server-root>/Me</spanx>
as an URL alias for the User or other resource associated with the
currently authenticated subject for any SCIM operation. A service
provider MAY respond in ONE of 3 ways: <list style="symbols">
<t>A service provider that does NOT support this feature SHOULD
respond with status 403 (FORBIDDEN).</t>
<t>A service provider MAY choose to redirect the client using HTTP
status 308 to the resource associated with the authenticated
subject. The client MAY then repeat the request at the indicated
location.</t>
<t>A service provider MAY process the SCIM request directly. In
any response, the HTTP "Location" header MUST be the permanent
location of the aliased resource associated with the authenticated
subject.</t>
</list></t>
</section>
<section anchor="http-response-codes" title="HTTP Error Responses">
<t>The SCIM Protocol uses the response status codes defined in HTTP
<xref target="RFC7231"> Section 6</xref> to indicate operation success
or failure. In addition to returning a HTTP response code implementers
MUST return the errors in the body of the response in the client
requested format containing the error response and, per the HTTP
specification, human-readable explanations. Error responses are
identified using the following <spanx style="verb">schema</spanx> URI:
<spanx style="verb">urn:scim:api:messages:2.0:Error</spanx>. The
following attributes are defined inclusion in a SCIM error response
using a JSON body:<list style="hanging">
<t hangText="status"><vspace blankLines="0"/>The HTTP status value
(e.g. 400). REQUIRED</t>
<t hangText="scimType"><vspace blankLines="0"/>A SCIM detailed
error keyword. See <xref target="scimTypes"/>. OPTIONAL</t>
<t hangText="detail"><vspace blankLines="0"/>A detailed, human
readable message. OPTIONAL</t>
</list></t>
<t>Implementers SHOULD handle the identified errors as described
below.</t>
<texttable anchor="http-error-handling-table"
title="Defined error cases">
<ttcol align="left">Status</ttcol>
<ttcol align="left">Applicability</ttcol>
<ttcol align="left">Suggested Explanation</ttcol>
<c>307 TEMPORARY REDIRECT</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>The client is directed to repeat the same HTTP request at the
location identified. The client SHOULD NOT use the location provided
in the response as a permanent reference to the resource and SHOULD
continue to use the original request URI <xref
target="RFC7231"/>.</c>
<c>308 PERMANENT REDIRECT</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>The client is directed to repeat the same HTTP request at the
location identified. The client SHOULD use the location provided in
the response as the permanent reference to the resource <xref
target="I-D.reschke-http-status-308"/>.</c>
<c>400 BAD REQUEST</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Request is unparseable, syntactically incorrect, or violates
schema</c>
<c>401 UNAUTHORIZED</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Authorization failure</c>
<c>403 FORBIDDEN</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Server does not support requested operation</c>
<c>404 NOT FOUND</c>
<c>GET, PUT, PATCH, DELETE</c>
<c>Specified resource (e.g., User) or end-point, does not exist</c>
<c>409 CONFLICT</c>
<c>POST, PUT, PATCH, DELETE</c>
<c>The specified version number does not match the resource's latest
version number or a service provider refused to create a new,
duplicate resource</c>
<c>412 PRECONDITION FAILED</c>
<c>PUT, PATCH,D ELETE</c>
<c>Failed to update as resource {id} changed on the server last
retrieved</c>
<c>413 REQUEST ENTITY TOO LARGE</c>
<c>POST</c>
<c>{"maxOperations": 1000,"maxPayload": 1048576}</c>
<c>500 INTERNAL SERVER ERROR</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>An internal error. Implementers SHOULD provide descriptive
debugging advice</c>
<c>501 NOT IMPLEMENTED</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Service Provider does not support the request operation; e.g.,
PATCH</c>
</texttable>
<t>For HTTP Status 400 (Bad Request) responses, the following detail
error types are defined:</t>
<texttable anchor="scimTypes"
title="Table of Detail Error Keyword Values">
<ttcol>scimType</ttcol>
<ttcol>Description</ttcol>
<ttcol>Applicability</ttcol>
<c>invalidFilter</c>
<c>The specified filter syntax was invalid (does not comply with
<xref target="filterABNF"/>) or the specified attribute and filter
comparison combination is not supported.</c>
<c>GET(<xref target="query-resources"/>), POST (Search - <xref
target="query-post"/>), PATCH (Path Filter - <xref
target="edit-resource-with-patch"/>)</c>
<c>tooMany</c>
<c>The specified filter yields many more results than the server is
willing calculate or process. For example, a filter such as <spanx
style="verb">userName eq "*"</spanx> would return all entries with a
<spanx style="verb">userName</spanx> and MAY not be acceptable to
the service provider.</c>
<c>GET(<xref target="query-resources"/>), POST (Search - <xref
target="query-post"/>)</c>
<c>uniqueness</c>
<c>One or more of attribute values is already in use or is
reserved.</c>
<c>POST (Create - <xref target="create-resource"/>), PUT (<xref
target="edit-resource-with-put"/>), PATCH (<xref
target="edit-resource-with-patch"/>)</c>
<c>mutability</c>
<c>The attempted modification is not compatible with the target
attributes mutability or current state (e.g. modification of an
immutable attribute with an existing value).</c>
<c>PUT (<xref target="edit-resource-with-put"/>), PATCH (<xref
target="edit-resource-with-patch"/>)</c>
<c>invalidSyntax</c>
<c>The request body message structure was invalid or did not conform
to the request schema.</c>
<c>POST (Search - <xref target="query-resources"/>, Create - <xref
target="create-resource"/>, Bulk - <xref target="bulk-resources"/>),
PUT (<xref target="edit-resource-with-put"/>)</c>
<c>invalidPath</c>
<c>The path attribute was invalid or malformed (see <xref
target="pathABNF"/>).</c>
<c>PATCH (<xref target="edit-resource-with-patch"/>)</c>
<c>noTarget</c>
<c>The specified <spanx style="verb">path</spanx> did not yield an
attribute or attribute value that could be operated on. This occurs
when the specified <spanx style="verb">path</spanx> value contains a
filter that yields no match.</c>
<c>PATCH (<xref target="edit-resource-with-patch"/>)</c>
<c>invalidValue</c>
<c>A required value was missing, or the value specified was not
compatible with the operation or attribute type (see Section 2.1
<xref target="I-D.ietf-scim-core-schema"/>).</c>
<c>GET (<xref target="query-resources"/>), POST (Create - <xref
target="create-resource"/>, Search - <xref
target="query-resources"/>), PUT (<xref
target="edit-resource-with-put"/>), PATCH (<xref
target="edit-resource-with-patch"/>)</c>
<c>invalidVers</c>
<c>The specified API version is not supported (see <xref
target="api-versioning"/>).</c>
<c>GET (<xref target="query-resources"/>), POST (ALL), PUT (<xref
target="edit-resource-with-put"/>), PATCH (<xref
target="edit-resource-with-patch"/>), DELETE (<xref
target="delete-resource"/>)</c>
</texttable>
<t>Note that in the table above (<xref target="scimTypes"/>), the
applicability table applies to the normal HTTP method but MAY apply
within a SCIM Bulk operation (via HTTP POST).</t>
<t>Error example in response to a non-existent GET request.<figure
align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 404 NOT FOUND
{
"schemas": ["urn:scim:api:messages:2.0:Error"],
"detail":"Resource 2819c223-7f76-453a-919d-413861904646 not found",
"status":"404
} </artwork>
</figure></t>
<t>Error example in response to a PUT request.<figure align="left"
alt="" height="" suppress-title="false" title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 400 BAD REQUEST
{
"schemas": ["urn:scim:api:messages:2.0:Error"],
"scimType":"mutability"
"detail":"Attribute 'id' is readOnly",
"status":"400"
} </artwork>
</figure></t>
<t>[[Editor's note: while the detail error codes seem to have
consensus, there is a question about whether the error codes should be
extensible so that individual service providers may define site
specific codes. Should all scimTypes be URIs, so that scimTypes can be
registered via IANA? Should there be a separate field defined for this
purpose? Or, should custom signalling (for non-protocol/schema errors,
be out of scope?]]</t>
</section>
<section anchor="api-versioning" title="API Versioning">
<t>The Base URL MAY be appended with a version identifier as a
separate segment in the URL path. At this time of this specification,
the identifier is 'v2'. If specified, the version identifier MUST
appear in the URL path immediately preceding the resource endpoint and
conform to the following scheme: the character 'v' followed by the
desired SCIM version number; e.g., a version 'v2' User request is
specified as /v2/Users. When specified service providers MUST perform
the operation using the desired version or reject the request. When
omitted service providers SHOULD perform the operation using the most
recent API supported by the service provider.</t>
</section>
<section anchor="etags" title="Versioning Resources">
<t>The API supports resource versioning via standard HTTP ETags <xref
target="RFC7233"> Section 2.3</xref>. Service providers MAY support
weak ETags as the preferred mechanism for performing conditional
retrievals and ensuring clients do not inadvertently overwrite each
others changes, respectively. When supported SCIM ETags MUST be
specified as an HTTP header and SHOULD be specified within the
'version' attribute contained in the resource's 'meta' attribute.</t>
<t>Example:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /Users HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
}
}
</artwork>
</figure>
<t>The server responds with an ETag in the response header and meta
structure.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 201 Created
Content-Type: application/json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"e180ee84f0671b1"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"meta":{
"resourceType":"User",
"created":"2011-08-01T21:32:44.882Z",
"lastModified":"2011-08-01T21:32:44.882Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"e180ee84f0671b1\""
},
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
},
"userName":"bjensen"
}
</artwork>
</figure>
<t>With the returned ETag, clients MAY choose to retrieve the resource
only if the resource has been modified.</t>
<t>Conditional retrieval example using If-None-Match <xref
target="RFC7233">Section 3.2</xref> header:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646?attributes=displayName
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
If-None-Match: W/"e180ee84f0671b1"
</artwork>
</figure>
<t>If the resource has not changed the service provider simply returns
an empty body with a 304 "Not Modified" response code.</t>
<t>If the service providers supports versioning of resources the
client MAY supply an If-Match <xref target="RFC7233">Section
3.1</xref> header for PUT and PATCH operations to ensure that the
requested operation succeeds only if the supplied ETag matches the
latest service provider resource; e.g., If-Match:
W/"e180ee84f0671b1"</t>
</section>
</section>
<section anchor="precis"
title="Preparation and Comparison of Internationalized Strings">
<t>To increase the likelihood that the input and comparison of unicode
usernames and passwords will work in ways that make sense for typical
users throughout the world there are special string preparation and
comparison methods (PRECIS) that MUST be followed for usernames and
passwords. Before comparing or evaluating uniqueness of a <spanx
style="verb">userName</spanx> or <spanx style="verb">password</spanx>
attribute, service providers MUST use the "PRECIS" profile described in
Sections 4 and 5 respectively of <xref
target="I-D.ietf-precis-saslprepbis"/> and is based on the "PRECIS"
framework specification <xref target="I-D.ietf-precis-framework"/>.</t>
</section>
<section anchor="MultiTenancy" title="Multi-Tenancy" toc="default">
<t>A single service provider may expose the SCIM protocol to multiple
clients. Depending on the nature of the service, the clients may have
authority to access and alter resources initially created by other
clients. Alternatively, clients may expect to access disjoint sets of
resources, and may expect that their resources are inaccessible by other
clients. These scenarios are called "multi-tenancy", where each client
is understood to be or represent a "tenant" of the service provider.
Clients may also be multi-tenanted.</t>
<t>The following common cases may occur: <list style="numbers">
<t>All clients share all resources (no tenancy)</t>
<t>Each single client creates and accesses a private subset of
resources (1 client:1 Tenant)</t>
<t>Sets of clients share sets of resources (M clients:1 Tenant)</t>
<t>One client to Multiple Tenants (1 client:M Tenants)</t>
</list> Service providers may implement any subset of the above
cases.</t>
<t>Multi-Tenancy is OPTIONAL. The SCIM protocol does not define a scheme
for multi-tenancy.</t>
<t>The SCIM protocol does not prescribe the mechanisms whereby clients
and service providers interact for: <list style="symbols">
<t>Registering or provisioning Tenants</t>
<t>Associating a subset of clients with a subset of the Tenants</t>
<t>Indicating which tenant is associated with the data in a request
or response, or indicating which Tenant is the subject of a
query</t>
</list></t>
<section anchor="tenantAssoc" title="Associating Clients to Tenants"
toc="default">
<t>The service provider MAY use the authentication mechanism (Section
2) to determine the identity of the client, and thus infer the
associated Tenant.</t>
<t>For implementations where a client is associated with more than one
Tenant, the service provider MAY use one of the following methods for
explicit specification of the Tenant.</t>
<t>If any of these methods of allowing the client to explicitly
specify the Tenant are employed, the service provider should ensure
that access controls are in place to prevent or allow cross-tenant use
cases.</t>
<t>The service provider should consider precedence in cases where a
client may explicitly specify a Tenant while being implicitly
associated with a different Tenant.</t>
<t>In all of these methods, the {tenant_id} is a unique identifier for
the Tenant as defined by the service provider. <list style="symbols">
<t>A URL prefix: <spanx style="verb">https://www.example.com/Tenants/{tenant_id}/v2/Users</spanx></t>
<t>A sub-domain: <spanx style="verb">https://{tenant_id}.example.com/v2/Groups</spanx></t>
<t>The service provider may recognize a {tenant_id} provided by
the client in an HTTP Header as the indicator of the desired
target Tenant.</t>
</list></t>
</section>
<section anchor="tenantIdentifiers"
title="SCIM Identifiers with Multiple Tenants" toc="default">
<t>Considerations for a Multi-Tenant Implementation:</t>
<t>The service provider may choose to implement SCIM ids which are
unique across all resources for all Tenants, but this is not
required.</t>
<t>The externalId, defined by the client, is required to be unique
ONLY within the resources associated with the associated Tenant.</t>
</section>
</section>
<section anchor="Security" title="Security Considerations" toc="default">
<section title="TLS Support">
<t>The SCIM Protocol layers on top of Hypertext Transfer Protocol and
thus subject to the security considerations of HTTP <xref
target="RFC7230">Section 9</xref> and its related specifications.</t>
<t>SCIM resources (e.g., Users and Groups) can contain sensitive
information. Therefore, SCIM clients and service providers MUST
implement TLS. Which version(s) ought to be implemented will vary over
time, and depend on the widespread deployment and known security
vulnerabilities at the time of implementation. At the time of this
writing, TLS version 1.2 <xref target="RFC5246"/> is the most recent
version, but has very limited actual deployment, and might not be
readily available in implementation toolkits. TLS version 1.0 <xref
target="RFC2246"/> is the most widely deployed version, and will give
the broadest interoperability.</t>
</section>
<section title="Request URI Information Leakage">
<t>Clients requesting information using query filters using HTTP GET
SHOULD give consideration to the information content of the filters
and whether their exposure in a URI would represent a breach of
security or confidentiality through leakage in a web browsers or
server logs. This is particularly true for information that is legally
considered "personally identifiable information" or is otherwise
restricted by privacy laws. In these situations to ensure maximum
security and confidentiality, clients SHOULD query using HTTP POST
(see <xref target="query-post"/> ).</t>
<t>Servers that receive HTTP GET requests using filters that contain
restricted or confidential information SHOULD respond with HTTP status
403 indicating the operation is FORBIDDEN. A detialed error, <spanx
style="verb">confidential_restricted</spanx> may be returned
indicating the request must be submitted using POST. A non-normative
example: <figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 403 FORBIDDEN
{
"schemas": ["urn:scim:api:messages:2.0:Error"],
"Errors":[
{
"description":"Query filter involving 'name' is restricted or confidential",
"error":"confidential_restricted"
}
]
}
</artwork>
</figure></t>
</section>
<section title="Case Insensitive Comparision & International Languages">
<t>When comparing unicode strings such as in query filters or testing
for uniqueness of usernames and passwords, strings MUST be
appopriately prepared before comparison. See <xref
target="precis"/>.</t>
</section>
<section title="Universal Identifiers"/>
</section>
<section anchor="IANA" title="IANA Considerations">
<t/>
<section title="Media Type Registration">
<t><list style="hanging">
<t hangText="To:">ietf-types@iana.org</t>
<t hangText="Subject:">Registration of media type
application/scim+json</t>
<t hangText="Type name:">application</t>
<t hangText="Subtype name:">scim+json</t>
<t hangText="Required parameters:">none</t>
<t hangText="Optional parameters:">none</t>
<t hangText="Encoding considerations:">8bit</t>
<t hangText="Security considerations:">See <xref
target="Security"/></t>
<t hangText="Interoperability considerations:">The <spanx
style="verb">application/scim+json</spanx> media type is intended
to identify JSON structure data that conforms to the SCIM 2 api
and schema specifications. Older versions of SCIM are known to
informally use <spanx style="verb">application/json</spanx>.</t>
<t hangText="Published specification:">[[this document]]</t>
<t hangText="Applications that use this media type:">It is
expected that applications that use this type may be special
purpose applications intended for inter-domain provisioning.
Clients may also be applications (e.g. mobile applications) that
need to use SCIM for self-registration of user accounts. SCIM
services may be offered by web applications wishin to offer
support for standards based provisioning or may be a dedicated
SCIM service provider such as a "cloud directory". Content may be
treated as equivalent to <spanx style="verb">application/json</spanx>
type for the purpose of displaying in web browsers.</t>
<t hangText="Additional information:"><list>
<t>Magic number(s):</t>
<t>File extension(s): .scim .scm</t>
<t>Macintosh file type code(s):</t>
</list></t>
<t
hangText="Person & email address to contact for futher information:">SCIM
mailing list <spanx style="verb"><scim@ietf.org></spanx></t>
<t hangText="Intended usage:">COMMON* (see restrictions)</t>
<t hangText="Restrictions on usage:">For most client types, it is
sufficient to recognize the content as equivalent to <spanx
style="verb">application/json</spanx>. Applications intending to
use the SCIM API SHOULD use the application/scim+json media
type.</t>
<t hangText="Author:">Phil Hunt</t>
<t hangText="Change controller:">IETF</t>
</list></t>
</section>
<section title="SCIM API Message Schema Registry">
<t>As per the IANA SCIM Schema Registry in <xref
target="I-D.ietf-scim-core-schema"/>, the following registers and
extends the SCIM Schema Registry to define API request/response JSON
schema URN identifier prefix of <spanx style="verb">urn:scim:api:messages:2.0</spanx>
which is part of the URN sub-Namespace for SCIM. There is no specific
associated resource type.</t>
<texttable title="SCIM Schema URIs for Data Resources">
<ttcol>Schema URI</ttcol>
<ttcol>Name</ttcol>
<ttcol>Reference</ttcol>
<c>urn:scim:api:messages:2.0:ListResponse</c>
<c>List/Query Response</c>
<c>See <xref target="query-resources"/></c>
<c>urn:scim:api:messages:2.0:SearchRequest</c>
<c>POST Query Request</c>
<c>See <xref target="query-post"/></c>
<c>urn:scim:api:messages:2.0:PatchOp</c>
<c>Patch Operation</c>
<c>See <xref target="edit-resource-with-patch"/></c>
<c>urn:scim:api:messages:2.0:BulkRequest</c>
<c>Bulk Operations Request</c>
<c>See <xref target="bulk-resources"/></c>
<c>urn:scim:api:messages:2.0:BulkResponse</c>
<c>Bulk Operations Response</c>
<c>See <xref target="bulk-resources"/></c>
<c>urn:scim:api:messages:2.0:Error</c>
<c>Error Response</c>
<c>See <xref target="http-response-codes"/></c>
</texttable>
</section>
</section>
</middle>
<back>
<references title="Normative References">
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml' ?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2616.xml' ?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.3629.xml' ?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.3986.xml' ?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2246.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.3454.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5234.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5246.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5789.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.6750.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.7159.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.7230.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.7231.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.7233.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.7235.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-ietf-precis-saslprepbis-07.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-ietf-scim-core-schema-06.xml'?>
<reference anchor="IANA.Language">
<front>
<title>Language Subtag Registry</title>
<author>
<organization>Internet Assigned Numbers Authority
(IANA)</organization>
</author>
<date year="2005"/>
</front>
<format target="http://www.iana.org/assignments/language-subtag-registry"
type="TXT"/>
</reference>
</references>
<references title="Informative References">
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2277.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.6902.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-ietf-precis-framework-17.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-reschke-http-status-308-07.xml'?>
<reference anchor="OpenSearch">
<front>
<title>OpenSearch Protocol 1.1, Draft 5</title>
<author fullname="DeWitt Clinton" initials="D." surname="Clinton">
<organization>A9.org</organization>
</author>
<date/>
</front>
<format target="http://www.opensearch.org/Specifications/OpenSearch/1.1"
type="HTML"/>
</reference>
<reference anchor="Order-Operations">
<front>
<title>Order of Operations: Programming Languages</title>
<author>
<organization>Wikipedia</organization>
</author>
<date/>
</front>
<format target="http://en.wikipedia.org/wiki/Order_of_operations#Programming_languages"
type="HTML"/>
</reference>
</references>
<section title="Contributors">
<t><list style="empty">
<t>Samuel Erdtman (samuel@erdtman.se)</t>
<t>Patrick Harding (pharding@pingidentity.com)</t>
</list></t>
</section>
<section title="Acknowledgments">
<t>The editors would like to acknowledge the contribution and work of
the past draft editors: <list>
<t>Trey Drake, UnboundID</t>
<t>Chuck Mortimore, Salesforce</t>
</list></t>
<t>The editor would like to thank the participants in the the SCIM
working group for their support of this specification.</t>
</section>
<section title="Change Log">
<t>[[This section to be removed prior to publication as an RFC]]</t>
<t>Draft 02 - KG - Addition of schema extensibility</t>
<t>Draft 03 - PH - Revisions based on following tickets: <list>
<t>24 - Add filter negation</t>
<t>39 - Clarification on response for DELETE</t>
<t>42 - Make root searches optional</t>
<t>49 - Add "ew" filter</t>
<t>50 - Filters for multi-valued complex attributes</t>
<t>51 - Search by Schema</t>
<t>53 - Standard use of term client (some was consumer)</t>
<t>55 - Redirect support (3xx)</t>
<t>56 - Make manager attribute consistent with other $ref attrs</t>
<t>57 - Update all "/v1" examples to '/v2"</t>
<t>59 - Fix capitalization per IETF editor practices</t>
<t>60 - Changed <eref> tags to normal <xref> and
<reference> tags</t>
</list></t>
<t>Draft 04 - PH - Revisions based on the following tickets: <list>
<t>18 - New PATCH command based on JSON Patch (RFC6902)</t>
<t>- Provided ABNF specification for filters (used in PATCH)</t>
<t>- Updated references to RFC4627 to RFC7159</t>
</list></t>
<t>Draft 05 - PH - Revisions based on the following tickets: <list>
<t>03 - Support for excludedAttributes parameter</t>
<t>13 - Change client use of Etags from MUST to MAY (correction)</t>
<t>23 - Clarifications regarding case exact processing.</t>
<t>41 - Add IANA considerations</t>
<t>65 - Removed X-HTTP-Method-Override support</t>
<t>69 - Added clarifications to intro to align with
draft-nottingham-uri-get-off-my-lawn</t>
<t>70 - Remove SCIM_TENANT_ID header</t>
<t>72 - Added text to indicate UTF-8 is default and mandatory
encoding format per BCP18</t>
<t>74 - Added security considerations for using GET with
confidential attribute filters</t>
<t>- corrected error response in JSON PATCH operation</t>
</list></t>
<t>Draft 06 - PH - Revisions based on the following tickets and
editorial changes <list>
<t>41 - Revised content types from application/json to
application/scim+json, registered API schemas</t>
<t>63 - Revised uri schema prefixes for API json message schemas</t>
<t>66 - Updated references for RFC2616 to HTTPbis</t>
<t>75 - Added security considerations for International Strings and
"PRECIS" support</t>
<t>76 - Clarified handling of PUT (& POST) with regards to
mutability and default values</t>
<t>- Corrected version numbers in sec 3.11 API Versioning to v2
(from v1)</t>
<t>- Clarified that no filter matches should return success
totalResults=0</t>
</list></t>
<t>Draft 07 - PH - Revisions regarding support of detailed errors
(Tickets 37, 46, 67)</t>
</section>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-24 13:19:46 |