--- 1/draft-ietf-scim-api-03.txt 2014-04-23 09:14:36.081748136 -0700 +++ 2/draft-ietf-scim-api-04.txt 2014-04-23 09:14:36.177750481 -0700 @@ -1,25 +1,25 @@ Network Working Group K. Grizzle Internet-Draft SailPoint Intended status: Standards Track P. Hunt, Ed. -Expires: August 16, 2014 Oracle +Expires: October 25, 2014 Oracle M. Ansari Cisco E. Wahlstroem Technology Nexus C. Mortimore Salesforce - February 12, 2014 + April 23, 2014 System for Cross-Domain Identity Management:Protocol - draft-ietf-scim-api-03 + draft-ietf-scim-api-04 Abstract 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 @@ -36,21 +36,21 @@ Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at http://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." - This Internet-Draft will expire on August 16, 2014. + This Internet-Draft will expire on October 25, 2014. Copyright Notice Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents @@ -66,47 +66,47 @@ 1.1. Intended Audience . . . . . . . . . . . . . . . . . . . . 3 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 3 1.3. Definitions . . . . . . . . . . . . . . . . . . . . . . . 3 2. Authentication and Authorization . . . . . . . . . . . . . . 3 3. API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3.1. Creating Resources . . . . . . . . . . . . . . . . . . . 6 3.1.1. Resource Types . . . . . . . . . . . . . . . . . . . 7 3.2. Retrieving Resources . . . . . . . . . . . . . . . . . . 7 3.2.1. Retrieving a known Resource . . . . . . . . . . . . . 7 3.2.2. List/Query Resources . . . . . . . . . . . . . . . . 9 - 3.2.3. Querying Resources Using HTTP POST . . . . . . . . . 17 - 3.3. Modifying Resources . . . . . . . . . . . . . . . . . . . 19 - 3.3.1. Modifying with PUT . . . . . . . . . . . . . . . . . 20 - 3.3.2. Modifying with PATCH . . . . . . . . . . . . . . . . 22 - 3.4. Deleting Resources . . . . . . . . . . . . . . . . . . . 30 - 3.5. Bulk . . . . . . . . . . . . . . . . . . . . . . . . . . 31 - 3.6. Data Input/Output Formats . . . . . . . . . . . . . . . . 46 - 3.7. Additional retrieval query parameters . . . . . . . . . . 47 - 3.8. Attribute Notation . . . . . . . . . . . . . . . . . . . 48 - 3.9. HTTP Response Codes . . . . . . . . . . . . . . . . . . . 48 - 3.10. API Versioning . . . . . . . . . . . . . . . . . . . . . 50 - 3.11. Versioning Resources . . . . . . . . . . . . . . . . . . 50 - 3.12. HTTP Method Overloading . . . . . . . . . . . . . . . . . 52 - 4. Multi-Tenancy . . . . . . . . . . . . . . . . . . . . . . . . 52 - 4.1. Associating Clients to Tenants . . . . . . . . . . . . . 53 - 4.1.1. URL Prefix Example . . . . . . . . . . . . . . . . . 54 - 4.1.2. Subdomain Example . . . . . . . . . . . . . . . . . . 54 - 4.1.3. HTTP Header . . . . . . . . . . . . . . . . . . . . . 54 - 4.2. SCIM Identifiers with Multiple Tenants . . . . . . . . . 54 - 5. Security Considerations . . . . . . . . . . . . . . . . . . . 54 - 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 54 - 6.1. Normative References . . . . . . . . . . . . . . . . . . 55 - 6.2. Informative References . . . . . . . . . . . . . . . . . 55 - Appendix A. Contributors . . . . . . . . . . . . . . . . . . . . 56 - Appendix B. Acknowledgments . . . . . . . . . . . . . . . . . . 56 - Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 56 - Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 57 + 3.2.3. Querying Resources Using HTTP POST . . . . . . . . . 19 + 3.3. Modifying Resources . . . . . . . . . . . . . . . . . . . 21 + 3.3.1. Modifying with PUT . . . . . . . . . . . . . . . . . 22 + 3.3.2. Modifying with PATCH . . . . . . . . . . . . . . . . 24 + 3.4. Deleting Resources . . . . . . . . . . . . . . . . . . . 33 + 3.5. Bulk . . . . . . . . . . . . . . . . . . . . . . . . . . 34 + 3.6. Data Input/Output Formats . . . . . . . . . . . . . . . . 49 + 3.7. Additional retrieval query parameters . . . . . . . . . . 50 + 3.8. Attribute Notation . . . . . . . . . . . . . . . . . . . 51 + 3.9. HTTP Response Codes . . . . . . . . . . . . . . . . . . . 51 + 3.10. API Versioning . . . . . . . . . . . . . . . . . . . . . 53 + 3.11. Versioning Resources . . . . . . . . . . . . . . . . . . 53 + 3.12. HTTP Method Overloading . . . . . . . . . . . . . . . . . 55 + 4. Multi-Tenancy . . . . . . . . . . . . . . . . . . . . . . . . 55 + 4.1. Associating Clients to Tenants . . . . . . . . . . . . . 56 + 4.1.1. URL Prefix Example . . . . . . . . . . . . . . . . . 57 + 4.1.2. Subdomain Example . . . . . . . . . . . . . . . . . . 57 + 4.1.3. HTTP Header . . . . . . . . . . . . . . . . . . . . . 57 + 4.2. SCIM Identifiers with Multiple Tenants . . . . . . . . . 57 + 5. Security Considerations . . . . . . . . . . . . . . . . . . . 57 + 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 57 + 6.1. Normative References . . . . . . . . . . . . . . . . . . 58 + 6.2. Informative References . . . . . . . . . . . . . . . . . 59 + Appendix A. Contributors . . . . . . . . . . . . . . . . . . . . 59 + Appendix B. Acknowledgments . . . . . . . . . . . . . . . . . . 59 + Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 59 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 60 1. Introduction and Overview The SCIM Protocol is an application-level, REST 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. 1.1. Intended Audience @@ -120,21 +120,21 @@ "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. For purposes of readability examples are not URL encoded. Implementers MUST percent encode URLs as described in Section 2.1 - [RFC3896]. + [RFC3986]. 1.3. Definitions Base URL: The SCIM REST 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: https://example.com/scim/v2/ 2. Authentication and Authorization @@ -397,26 +397,28 @@ requested resources. This may be a subset of the full set of resources if pagination (Section 3.2.2.4) is requested. REQUIRED. startIndex The 1-based index of the first result in the current set of list results. REQUIRED if pagination (Section 3.2.2.4) is requested. itemsPerPage The number of resources returned in a list response page. REQUIRED if pagination (Section 3.2.2.4) is requested. - The below example returns the userName for all Users: + The query example below requests the userName for all Users: GET /Users?attributes=userName Host: example.com Accept: application/json Authorization: Bearer h480djs93hd8 + The following is an example response to the query above: + HTTP/1.1 200 OK Content-Type: application/json { "schemas":["urn:scim:schemas:core:2.0:ListResponse"], "totalResults":2, "Resources":[ { "userName":"bjensen" }, @@ -451,24 +453,21 @@ attribute as if there is no attribute value. For example, a presence or equality filter for an undefined attribute evaluates as FALSE. 3.2.2.2. Filtering 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. The literal values can be strings enclosed in double - quotes, numbers, date times enclosed in double quotes, and Boolean - values; i.e., true or false. String literals MUST be valid - [RFC4627]. + literals. The attribute name and attribute operator are case insensitive. For example, the following two expressions will evaluate to the same logical value: filter=userName Eq "john" filter=Username eq "john" The filter parameter MUST contain at least one valid Boolean @@ -565,20 +564,59 @@ | | | 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. | +----------+-------------+------------------------------------------+ Table 4: Grouping Operators + SCIM filters MUST conform to the following ABNF rules as per + [RFC5234] below: + + 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 + + Figure 1: ABNF Specification of SCIM Filters + + In the above ABNF, the "compValue" (comparison value) rule is built + on JSON Data Interchange format ABNF rules as specified in [RFC7159], + "DIGIT" and "ALPHA" are defined per Appendix B.1 of [RFC5234] and, + "URI" is defined per Appendix A of [RFC3986]. + Filters MUST be evaluated using standard order of operations [Order-Operations]. 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. 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 @@ -633,26 +671,28 @@ 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=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]] + Example Filters + 3.2.2.3. Sorting 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. 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 @@ -718,26 +758,30 @@ | | e.g., 10. | | totalResults | Non-negative Integer. Specifies the total number | | | of results matching the client query; e.g., 1000. | | startIndex | The 1-based index of the first result in the | | | current set of search results; e.g., 1. | +--------------+----------------------------------------------------+ Table 6: Pagination Response Elements For example, to retrieve the first 10 Users set the startIndex to 1 - and the count to 10. + and the count to 10: GET /Users?startIndex=1&count=10 Host: example.com Accept: application/json Authorization: Bearer h480djs93hd8 + The response to the query above returns metadata regarding paging + similar to the following example (actual resources removed for + brevity): + { "totalResults":100, "itemsPerPage":10, "startIndex":1, "schemas":["urn:scim:schemas:core:2.0"], "Resources":[{ ... }] } @@ -799,21 +843,21 @@ Content-Length: ... { "schemas": ["urn:scim:schemas:core:2.0:SearchRequest"], "attributes": ["displayName", "userName"], "filter": "displayName sw \"smith\"", "startIndex": 1, "count": 10 } - Figure 1: Example POST Search Request + Figure 2: Example POST Search Request A search response is shown with the first page of results. For brevity reasons, only two matches are shown: one User and one Group. HTTP/1.1 200 OK Content-Type: application/json Location: https://example.com/.search { "schemas": ["urn:scim:schemas:core:2.0:ListResponse"], "totalResults":100, @@ -836,21 +880,21 @@ "https://example.com/Groups/c8596b90-7539-4f20968d1908", "resourceType":"Group", "lastModified": ... }, "displayName":"Smith Family" }, ... ] } - Figure 2: Example POST Search Response + Figure 3: Example POST Search Response 3.3. Modifying Resources Resources can be modified in whole or in part via PUT or PATCH, respectively. Implementers MUST support PUT as specified in Section 9.6 [RFC2616] . Resources such as Groups may be very large hence implementers SHOULD support PATCH [RFC5789] to enable partial resource modifications. 3.3.1. Modifying with PUT @@ -872,22 +916,22 @@ be specified; and, readOnly Any values provided (e.g. meta.resourceType) SHALL be ignored. If an attribute is "required", the client MUST specify the attribute in the PUT request. If a value provided for an immutable attribute with an existing value is NOT matched, the server SHALL respond with an HTTP response code - of 400 and an apprpriate human readable message indicating an attempt - to change an immutable attribute. + of 400 and an appropriate human readable message indicating an + attempt to change an immutable attribute. 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: PUT /Users/2819c223-7f76-453a-919d-413861904646 Host: example.com Accept: application/json Content-Type: application/json @@ -907,22 +951,21 @@ }, "emails":[ { "value":"bjensen@example.com" }, { "value":"babs@jensen.org" } ] } - - The service responds with the entire, updated User + The service responds with the entire, updated User: HTTP/1.1 200 OK Content-Type: application/json ETag: W/"b431af54f0671a2" Location:"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646" { "schemas":["urn:scim:schemas:core:2.0:User"], "id":"2819c223-7f76-453a-919d-413861904646", "userName":"bjensen", "externalId":"bjensen", @@ -944,343 +987,403 @@ "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\"" } } 3.3.2. Modifying with PATCH - PATCH is OPTIONAL. PATCH enables clients to send only those - attributes requiring modification, reducing network and processing - overhead. Attributes may be deleted, replaced, merged, or added in a - single request. + 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 "add", "remove", or "replace" values. The general form + of the SCIM patch request is based on JavaScript Object Notation + (JSON) Patch [RFC6902]. One difference between SCIM patch and JSON + patch is that SCIM servers do not support array indexing and may not + support all [RFC6902] operation types. - The body of a PATCH request MUST contain a partial resource with the - desired modifications. The server MUST return either a 200 OK + 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 "add", "remove", or "replace" . The semantics of each + operation are defined below. + + Operation objects MUST have exactly one "path" member which is a + "String" containing an attribute path as specified by the following + ABNF syntax rule: + + PATH = attrPath / valuePath [subAttr] + + Figure 4: SCIM Patch PATH Rule + + The rules, "attrPath", "valuePath", and "subAttr" are defined in + Section 3.2.2.2. The "valuePath" rule allows specific values of a + complex, multi-valued attribute to be selected. + + Valid examples of "path" values are as follows: + + "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" + + Each operation against an attribute MUST be compatible with the + attribute's mutability and schema as defined in the Attribute Types + Section of [I-D.ietf-scim-core-schema]. For example, a client MAY + NOT modify an attribute that has mutability "readOnly"or "immutable". + However, a client MAY "add" a value to an"immutable" 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. + + 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. + + 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. + + If a request fails. the server SHALL return an HTTP response status + code of 400 and a JSON detail error response containing an "error" + object that SHOULD be one of the following string values: + + malformed_operation + The JSON operation elements could not successfully be parsed. + This may be due to an invalid or missing operation attribute, or + it could be due to a missing attribute required by a specific + operation. + + mutability + The operation requested is not compatible with the mutability of + the selected attribute. + + invalid_path + The path attribute was invalid or malformed. + + no_target + The "path" specified did not return a target against which the + operation could be performed. + + invalid_value + The operation "value" was missing or was not compatable with the + targeted attribute's type + + The following is a non-normative example of an error response to a + patch request. + + HTTP/1.1 400 Bad Request + Content-Type: application/json;charset=UTF-8 + Cache-Control: no-store + Pragma: no-cache + + { + "error":"mutability", + "error_description":"Attribute 'id' is readOnly." + } + + On successful completion, the server MUST return either a 200 OK response code and the entire resource (subject to the "attributes" query parameter - see Additional Retrieval Query Parameters (Section 3.7)) within the response body, or a 204 No Content response - code and the appropriate response headers for a successful PATCH + 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. - The server MUST process a PATCH request by first removing any - attributes specified in the meta.attributes Sub-Attribute (if - present) and then merging the attributes in the PATCH request body - into the resource. +3.3.2.1. Add Operation - The meta.attributes Sub-Attribute MAY contain a list of attributes to - be removed from the resource. If the PATCH request body contains an - attribute that is present in the meta.attributes list, the attribute - on the resource is replaced with the value from the PATCH body. If - the attribute is complex the attribute name must be a path to a Sub- - Attribute in standard attribute notation (Section 3.8); e.g., - name.givenName. + The "add" operation performs one of the following functions, + depending upon what the target location indicated by "path" + references: - Attributes that exist in the PATCH request body but not in the - meta.attributes Sub-Attribute will be either be updated or added to - the resource according to the following rules. + o If the target location does not exist, the attribute and value is + added. - Singular attributes: Singular attributes in the PATCH request body - replace the attribute on the resource. + o If the target location specifies a multi-valued attribute, a new + value is added to the attribute. - Complex attributes: Complex Sub-Attribute values in the PATCH - request body are merged into the complex attribute on the + o if the target location specifies a single-valued attribute, the + existing value is replaced. + + o If the target location specifies an attribute that does not exist + (has no value), the attribute is added with the new value. + + o If the target location exists, the value is replaced. + + o 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. - Multi-valued attributes: An attribute value in the PATCH request - body is added to the value collection if the value does not exist - and merged if a matching value is present. Values are matched by - comparing the value Sub-Attribute from the PATCH request body to - the value Sub-Attribute of the resource. Attributes that do not - have a value Sub-Attribute; e.g., addresses, or do not have unique - value Sub-Attributes cannot be matched and must instead be deleted - then added. Specific values can be removed from a resource by - adding an "operation" Sub-Attribute with the value "delete" to the - attribute in the PATCH request body. As with adding/updating - attribute value collections, the value to delete is determined by - comparing the value Sub-Attribute from the PATCH request body to - the value Sub-Attribute of the resource. Attributes that do not - have a value Sub-Attribute or that have a non-unique value Sub- - Attribute are matched by comparing all Sub-Attribute values from - the PATCH request body to the Sub-Attribute values of the - resource. A delete operation is ignored if the attribute's name - is in the meta.attributes list. If the requested value to delete - does not match a unique value on the resource the server MAY - return a HTTP 400 error. + The operation MUST contain a "value" 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 "path". - The following example shows how to add a member to a group: + The following example shows how to add a member to a group. Some + text removed for readability ("..."): PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" { - "schemas": ["urn:scim:schemas:core:2.0:Group"], - "members": [ + "op":"add", + "path":"members", + "value":[ { "display": "Babs Jensen", - "$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646", + "$ref": "https://example.com/v2/Users/2819c223...413861904646", "value": "2819c223-7f76-453a-919d-413861904646" } ] } 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: HTTP/1.1 204 No Content Authorization: Bearer h480djs93hd8 ETag: W/"b431af54f0671a2" -Location: "https://example.com/v2/Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce" +Location: "https://example.com/Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce" + +3.3.2.2. Remove Operation + + The "remove" operation removes the value at the target location + specified by the "path". The operation performs the following + functions depending on the target location specified by "path": + + o If the target location is a single-value attribute, the attribute + and its associated value is removed. + + o If the target location is a multi-valued attribute and no filter + is specified, the attribute and all values are removed. + + o If the target location is a multi-valued attribute and a complex + filter is specified comparing a "value", the values matched by the + filter are removed. + + o 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. 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. Note that server responses have been omitted for the rest of the PATCH examples. + Remove a single member from a group. Some text removed for + readability ("..."): + PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" { - "schemas": ["urn:scim:schemas:core:2.0:Group"], - "members": [ - { - "display": "Babs Jensen", - "$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646", - "value": "2819c223-7f76-453a-919d-413861904646", - "operation": "delete" - } - ] + "op":"remove", + "path":"members[value eq \"2819c223-7f76-...413861904646\"]" } - The following example shows how to remove all members from a group: + Remove all members of a group: PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" + { "op":"remove","path":"members"} + + Removal of a value from a complex-multi-valued attribute (request + headers removed for brevity): + { - "schemas": ["urn:scim:schemas:core:2.0:Group"], - "meta": { - "attributes": [ - "members" - ] - } + "op":"remove", + "path":"emails[type eq \"work\" and value ew \"example.com\"]" } - - The following example shows how to replace all of the members of a - group with a different members list: + Example request to remove and add a member. Some text removed for + readability ("..."): PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" + [ { - "schemas": ["urn:scim:schemas:core:2.0:Group"], - "meta": { - "attributes": [ - "members" - ] + "op":"remove", + "path":"members[value eq\"2819c223...919d-413861904646\"]" }, - "members": [ { - "display": "Babs Jensen", - "$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646", - "value": "2819c223-7f76-453a-919d-413861904646" - }, + "op":"add", + "path":"members", + "value": [ { "display": "James Smith", - "$ref": "https://example.com/v2/Users/08e1d05d-121c-4561-8b96-473d93df9210", - "value": "08e1d05d-121c-4561-8b96-473d93df9210" + "$ref": "https://example.com/v2/Users/08e1d05d...473d93df9210", + "value": "08e1d05d...473d93df9210" } ] } - - The following example shows how to add a member to and remove a - member from a Group in a single request: + ] + The following example shows how to replace all the members of a group + with a different members list. Some text removed for readabilty + ("..."): PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" + [ + { "op":"remove","path":"members"}, { - "schemas": ["urn:scim:schemas:core:2.0:Group"], - "members": [ + "op":"add", + "path":"members", + "value":[ { "display": "Babs Jensen", - "$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646", - "value": "2819c223-7f76-453a-919d-413861904646", - "operation": "delete" + "$ref": "https://example.com/v2/Users/2819c223...413861904646", + "value": "2819c223-7f76-453a-919d-413861904646" }, { "display": "James Smith", - "$ref": "https://example.com/v2/Users/08e1d05d-121c-4561-8b96-473d93df9210", + "$ref": "https://example.com/v2/Users/08e1d05d...473d93df9210", "value": "08e1d05d-121c-4561-8b96-473d93df9210" + }] } ] -} - The following example shows how to change a User's primary email. If - the User already has the email address, it is made the primary - address and the current primary address (if present) is made non- - primary. If the User does not already have the email address, it is - added and made the primary address. +3.3.2.3. Replace Operation - PATCH /Users/2819c223-7f76-453a-919d-413861904646 + The "replace" operation replaces the value at the target location + specified by the "path". The operation performs the following + functions depending on the target location specified by "path": + + o If the target location is a single-value attribute, the attributes + value is replaced. + + o If the target location is a multi-valued attribute and no filter + is specified, the attribute and all values are replaced. + + o If the target location is a multi-valued attribute and a complex + filter is specified comparing a "value", the values matched by the + filter are replaced. + + o 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. + + o If the target location is a complex-multi-valued attribute with a + complex filter and a specific sub-attribute (e.g. "addresses[type + eq "work"].streetAddress"), the matching sub-attribute of the + matching record is replaced. + + 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 ("..."): + + PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" { - "schemas": ["urn:scim:schemas:core:2.0:User"], - "emails": [ + "op":"replace", + "path":"members", + "value":[ { - "value": "bjensen@example.com", - "primary": true + "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" } ] } - 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. + The following example shows how to change a User's entire "work" + address. PATCH /Users/2819c223-7f76-453a-919d-413861904646 Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" { - "schemas": ["urn:scim:schemas:core:2.0:User"], - "addresses": [ - { - "type": "work", - "streetAddress": "100 Universal City Plaza", - "locality": "Hollywood", - "region": "CA", - "postalCode": "91608", - "country": "US", - "formatted": "100 Universal City Plaza\nHollywood, CA 91608 US", - "primary": true, - "operation": "delete" - }, + "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 } - ] - } - - The following example shows how to change a User's nickname: - - PATCH /Users/2819c223-7f76-453a-919d-413861904646 - Host: example.com - Accept: application/json - Content-Type: application/json - Authorization: Bearer h480djs93hd8 - If-Match: W/"a330bc54f0671c9" - - { - "schemas": ["urn:scim:schemas:core:2.0:User"], - "nickName": "Barbie" - } - - The following example shows how to remove a User's nickname: - - PATCH /Users/2819c223-7f76-453a-919d-413861904646 - Host: example.com - Accept: application/json - Content-Type: application/json - Authorization: Bearer h480djs93hd8 - If-Match: W/"a330bc54f0671c9" - - { - "schemas": ["urn:scim:schemas:core:2.0:User"], - "meta": { - "attributes": [ - "nickName" - ] - } - } - - The following example shows how to change a User's familyName. This - only updates the familyName and formatted on the "name" complex - attribute. Any other name Sub-Attributes on the resource remain - unchanged. - - PATCH /Users/2819c223-7f76-453a-919d-413861904646 - Host: example.com - Accept: application/json - Content-Type: application/json - Authorization: Bearer h480djs93hd8 - If-Match: W/"a330bc54f0671c9" - - { - "schemas": ["urn:scim:schemas:core:2.0:User"], - "name": { - "formatted": "Ms. Barbara J Jensen III", - "familyName": "Jensen" - } } - The following example shows how to remove a complex Sub-Attribute and - an extended schema attribute from a User. + 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. PATCH /Users/2819c223-7f76-453a-919d-413861904646 Host: example.com Accept: application/json Content-Type: application/json Authorization: Bearer h480djs93hd8 If-Match: W/"a330bc54f0671c9" { - "schemas": ["urn:scim:schemas:core:2.0:User"], - "meta": { - "attributes": [ - "name.formatted", - "urn:hr:schemas:user:age" - ] - } + "op":"replace", + "path":"addresses[type eq \"work\"].streetAddress", + "value":"911 Universal City Plaza" } 3.4. Deleting Resources 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 @@ -1467,31 +1569,32 @@ "data":{ "schemas": ["urn:scim:schemas:core:2.0:User"], "id":"b7c14771-226c-4d05-8860-134711653041", "userName":"Bob" } }, { "method":"PATCH", "path":"/Users/5d8d29d3-342c-4b5f-8683-a3cb6763ffcc", - "version":"W\/\"edac3253e2c0ef2\"", - "data":{ - "schemas":["urn:scim:schemas:core:2.0:User"], - "id":"5d8d29d3-342c-4b5f-8683-a3cb6763ffcc", - "userName":"Dave", - "meta":{ - "attributes":[ - "nickName" - ] - } + "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\"" } ] } The service provider returns the following response. @@ -1902,21 +2005,21 @@ Clients MUST specify the format in which the data is submitted via the Section 14.17 HTTP header content-type [RFC2616] and MAY specify the desired response data format via an HTTP Accept Header; e.g.,"Accept: application/json" or via URI suffix; e.g., GET /Users/2819c223-7f76-453a-919d-413861904646.json Host: example.com Service providers MUST support the Accept Headers "Accept: - application/json" for [RFC4627]. The format defaults to JSON if no + application/json" for [RFC7159]. The format defaults to JSON if no format is specified. Singular attributes are encoded as string name-value-pairs in JSON; e.g., "attribute": "value" Multi-valued attributes in JSON are encoded as arrays; e.g., "attributes": [ "value1", "value2" ] @@ -2267,62 +2370,75 @@ interoperability. 6. References 6.1. Normative References [I-D.ietf-httpbis-p2-semantics] Fielding, R. and J. Reschke, "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", draft-ietf- httpbis-p2-semantics-25 (work in progress), November 2013. + [I-D.ietf-scim-core-schema] + Grizzle, K., Hunt, P., Wahlstroem, E., and C. Mortimore, + "System for Cross-Domain Identity Management: Core + Schema", draft-ietf-scim-core-schema-03 (work in + progress), February 2014. + [I-D.reschke-http-status-308] Reschke, J., "The Hypertext Transfer Protocol (HTTP) Status Code 308 (Permanent Redirect)", draft-reschke-http- status-308-07 (work in progress), March 2012. [IANA.Language] Internet Assigned Numbers Authority (IANA), "Language Subtag Registry", 2005. [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC 2246, January 1999. [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999. - [RFC3896] Nicklass, O., "Definitions of Managed Objects for the DS3/ - E3 Interface Type", RFC 3896, September 2004. + [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform + Resource Identifier (URI): Generic Syntax", STD 66, RFC + 3986, January 2005. - [RFC4627] Crockford, D., "The application/json Media Type for - JavaScript Object Notation (JSON)", RFC 4627, July 2006. + [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax + Specifications: ABNF", STD 68, RFC 5234, January 2008. [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, August 2008. [RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789, March 2010. [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", RFC 6750, October 2012. + [RFC7159] Bray, T., "The JavaScript Object Notation (JSON) Data + Interchange Format", RFC 7159, March 2014. + 6.2. Informative References [OpenSearch] Clinton, D., "OpenSearch Protocol 1.1, Draft 5", . [Order-Operations] Wikipedia, "Order of Operations: Programming Languages", . + [RFC6902] Bryan, P. and M. Nottingham, "JavaScript Object Notation + (JSON) Patch", RFC 6902, April 2013. + Appendix A. Contributors Samuel Erdtman (samuel@erdtman.se) Patrick Harding (pharding@pingidentity.com) Appendix B. Acknowledgments The editors would like to acknowledge the contribution and work of the past draft editors: @@ -2356,22 +2471,31 @@ 53 - Standard use of term client (some was consumer) 55 - Redirect support (3xx) 56 - Make manager attribute consistent with other $ref attrs 57 - Update all "/v1" examples to '/v2" 59 - Fix capitalization per IETF editor practices + 60 - Changed tags to normal and tags + Draft 04 - PH - Revisions based on the following tickets: + + 18 - New PATCH command based on JSON Patch (RFC6902) + + - Provided ABNF specification for filters (used in PATCH) + + - Updated references to RFC4627 to RFC7159 + Authors' Addresses Kelly Grizzle SailPoint Email: kelly.grizzle@sailpoint.com Phil Hunt (editor) Oracle Corporation