Version: | 1.0.1 |
Date: | 2015-12-28 |
Editor: | Thomas Hardjono, MIT |
Contributors: | Eve Maler, ForgeRock |
Maciej Machulak, Synergetics | |
Domenico Catalano, Oracle |
This specification defines a resource set registration mechanism between an OAuth 2.0 authorization server and resource server. The resource server registers information about the semantics and discovery properties of its resources with the authorization server.
This specification was developed by the User-Managed Access Work Group and approved by the Membership of the Kantara Initiative as a Recommendation according to its Operating Procedures.
Copyright (c) 2015 Kantara Initiative and the persons identified as the document authors. All rights reserved.
This document is subject to the Kantara IPR Policy - Option Patent & Copyright: Reciprocal Royalty Free with Opt-Out to Reasonable And Non discriminatory (RAND) (HTML version).
There are various circumstances under which an OAuth 2.0 [RFC6749] resource server may need to communicate information about its protected resources to its authorization server:
This specification defines an API through which the resource server can register information about resource sets with the authorization server.
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].
Unless otherwise noted, all protocol properties and values are case sensitive. JSON [RFC7159] data structures defined by this specification MAY contain extension properties that are not defined in this specification. Any entity receiving or retrieving a JSON data structure SHOULD ignore extension properties it is unable to understand. Extension names that are unprotected from collisions are outside the scope of this specification.
This specification introduces the following new terms and enhancements of OAuth term definitions.
If the authorization server declares its endpoints and any other configuration data in a machine-readable form, it SHOULD convey its resource set registration endpoint in this fashion as well.
This specification defines a resource set registration API. The endpoint for this API SHOULD also require some form of authentication to access this endpoint, such as Client Authentication as described in [RFC6749] or a separate OAuth access token. The methods of managing and validating these authentication credentials are out of scope of this specification.
For any of the resource owner's sets of resources this authorization server needs to be aware of, the resource server MUST register these resource sets at the authorization server's registration endpoint.
Note: When a client attempts access to a presumptively protected resource without an access token, as occurs in [UMA], the resource server needs to derive the authorization server and resource set identifier associated with that resource from some other aspect of the client's request. This effectively means that the resource server’s API needs to be structured in such a way that the client's request without an access token uniquely identifies the resource set. In practice, this information likely needs to be passed through the URI, headers, or body of the request.
The resource server defines a resource set that the authorization server needs to be aware of by registering a resource set description at the authorization server. This registration process results in a unique identifier for the resource set that the resource server can later use for managing its description.
The resource server is free to use its own methods of describing resource sets. A resource set description is a JSON document with the following properties:
For example, this description characterizes a resource set (a photo album) that can potentially be viewed or printed; the scope URI points to a scope description as defined in Section 2.1.1:
{ "name" : "Photo Album", "icon_uri" : "http://www.example.com/icons/flower.png", "scopes" : [ "view", "http://photoz.example.com/dev/scopes/print" ], "type" : "http://www.example.com/rsets/photoalbum" }
A scope description is a JSON document with the following properties:
For example, this scope description characterizes a scope that involves reading or viewing resources (vs. creating them or editing them in some fashion):
{ "name" : "View", "icon_uri" : "http://www.example.com/icons/reading-glasses" }
See Section 7 for a long-form example of scope descriptions used in resource set registration.
If the resource server uses a plain string for a scope, then the resource server and authorization server are presumed to have negotiated any required interpretation of scope handling out of band.
If the resource server uses a URI for a scope, the scope's published scope description MAY reside anywhere on the web; a resource server is not required to self-host scope descriptions and may wish to point to standardized scope descriptions residing elsewhere. It is the resource server's responsibility to ensure that scope descriptions are accessible to authorization servers through GET calls to support any user interface requirements.
The resource server uses the RESTful API at the authorization server's resource set registration endpoint to create, read, update, and delete resource set descriptions, along with retrieving lists of such descriptions.
(Note carefully the similar but distinct senses in which the word "resource" is used in this section. The resource set descriptions are themselves managed as web resources at the authorization server through this API.)
The authorization server MUST present an API for registering resource set descriptions at a set of URIs with the following structure:
{rsreguri}/resource_set
The {rsreguri} component is the authorization server's resource set registration endpoint as advertised in its configuration data (see Section 1.3). Following is a summary of the five registration operations the authorization server is REQUIRED to support. Each is defined in its own section below. All other methods are unsupported. The {_id} is the authorization server-assigned identifier for the web resource corresponding to the resource set at the time it was created, included within the URL returned in the Location header.
Within the JSON body of a successful response, the authorization server includes common properties, possibly in addition to method-specific properties, as follows:
If the request to the resource set registration endpoint is incorrect, then the authorization server instead responds with an error message by including one of the following error codes with the response (see Section 3):
Adds a new resource set description using the POST method. If the request is successful, the authorization server MUST respond with a status message that includes an _id property.
Form of a create request, with an access token in the header:
POST /rs/resource_set HTTP/1.1 Content-Type: application/json Authorization: Bearer MHg3OUZEQkZBMjcx ... { "name" : "Tweedl Social Service", "icon_uri" : "http://www.example.com/icons/sharesocial.png", "scopes" : [ "read-public", "post-updates", "read-private", "http://www.example.com/scopes/all" ], "type" : "http://www.example.com/rsets/socialstream/140-compatible" }
Form of a successful response:
HTTP/1.1 201 Created Content-Type: application/json Location: /rs/resource_set/KX3A-39WE ... { "_id" : "KX3A-39WE", "user_access_policy_uri" : "http://as.example.com/rs/222/resource/KX3A-39WE/policy" }
Reads a previously registered resource set description using the GET method. If the request is successful, the authorization server MUST respond with a status message that includes a body containing the referenced resource set description, along with an _id property.
Form of a read request, with an access token in the header:
GET /rs/resource_set/KX3A-39WE HTTP/1.1 Authorization: Bearer MHg3OUZEQkZBMjcx ...
Form of a successful response:
HTTP/1.1 200 OK Content-Type: application/json ... { "_id" : "KX3A-39WE", "name" : "Tweedl Social Service", "icon_uri" : "http://www.example.com/icons/sharesocial.png", "scopes" : [ "read-public", "post-updates", "read-private", "http://www.example.com/scopes/all" ], "type" : "http://www.example.com/rsets/socialstream/140-compatible" }
If the referenced resource set does not exist, the authorization server MUST produce an error response with an error property value of not_found, as defined in Section 2.2.
Updates a previously registered resource set description, by means of a complete replacement of the previous resource set description, using the PUT method. If the request is successful, the authorization server MUST respond with a status message that includes an _id property.
Form of an update request, with an access token in the header:
PUT /rs/resource_set/9UQU-DUWW HTTP/1.1 Content-Type: application/json Authorization: Bearer 204c69636b6c69 ... { "name" : "Photo Album", "icon_uri" : "http://www.example.com/icons/sky.png", "scopes" : [ "http://photoz.example.com/dev/scopes/view", "public-read" ], "type" : "http://www.example.com/rsets/photoalbum" }
Form of a successful response:
HTTP/1.1 200 OK ... { "_id": "9UQU-DUWW" }
Deletes a previously registered resource set description using the DELETE method, thereby removing it from the authorization server's protection regime.
Form of a delete request, with an access token in the header:
DELETE /rs/resource_set/9UQU-DUWW Authorization: Bearer 204c69636b6c69 ...
Form of a successful response:
HTTP/1.1 204 No content ...
If the referenced resource set does not exist, the authorization server MUST produce an error response with an error property value of not_found, as defined in Section 2.2.
Lists all previously registered resource set identifiers for this user using the GET method. The authorization server MUST return the list in the form of a JSON array of {_id} string values.
The resource server uses this method as a first step in checking whether its understanding of protected resources is in full synchronization with the authorization server's understanding.
Form of a list request, with an access token in the header:
GET /rs/resource_set HTTP/1.1 Authorization: Bearer 204c69636b6c69 ...
Form of a successful response:
HTTP/1.1 200 OK ... [ "KX3A-39WE", "9UQU-DUWW" ]
When a resource server attempts to access the resource set registration endpoint at the authorization server, if the request is successfully authenticated by OAuth means, but is invalid for another reason, the authorization server produces an error response by adding the following properties to the entity body of the HTTP response:
This specification largely relies on the base API security method, such as OAuth, for API security and shares its security and vulnerability considerations.
Some form of trust relationship between the authorization server and resource server is presumed. However, where this pairwise trust relationship is weak or loosely coupled, for example, if dynamic client registration is supported for resource servers as OAuth clients of the resource set registration API, the authorization server must be extremely careful with any information supplied during resource set registration that may be displayed to the resource owner in a user interface or be used to drive authorization server-based workflows.
For example, a rogue resource server could register a resource set or scope with a reference to a drive-by download in icons returned by the icon_uri, enticing the resource owner to click on the icon during the policy setting process. The authorization server SHOULD check to see if all URIs defined in the icon_uri and in the array of redirect_uris resolve to valid web pages. Since these are URI values that are intended to be displayed to the resource owner in a policy-setting interface, the authorization server SHOULD protect the resource owner from malicious content hosted at the URIs where possible.
Additionally, a rogue resource server could supply misleading names for a resource set or scope, or mislabel the type of a resource set, leading a resource owner to set policy incorrectly.
One approach to mitigating the threat of bad URIs is that, before presenting clickable icons, the authorization server could download the content hosted at the linked URIs, check the content against a malware scanner and blacklist filter, determine whether or not there is mixed secure and non-secure content at the URL, and other possible server-side mitigations. Note that the content in these URIs can change at any time and the authorization server cannot provide complete confidence in the safety of the URIs, but these practices could help. To further mitigate this kind of threat, the authorization server can also warn the user that the links have been provided by a third party, should be treated with caution, and are not hosted by the authorization server itself. For instance, instead of providing the links directly in an HTML anchor, the authorization server can direct the user to an interstitial warning page before allowing the user to continue to the target URI.
An alternative approach may be available in deployment ecosystems where trust relationships with resource servers may be weak but APIs, resource set semantics, and scopes have been standardized. A resource server could potentially increase the likelihood of an authorization server trusting the URIs it registers by using well-known and third-party-standardized URIs. This may benefit resource set type values as well, if these are represented as URIs.
In many ways, the resource server depends more heavily on elements of the pairwise trust relationship than does the authorization server. Since the resource server needs to outsource a variety of resource protection-related processes to the authorization server, a rogue or impersonated authorization server would present great risk. Using OAuth with its attendant channel security requirements for API authentication would mitigate the risk of impersonation.
A small example of the risk posed by a rogue authorization server is the user_access_policy_uri property, which is the one case of a URI passed from authorization server to resource server rather than the reverse. The resource server, in taking advantage of this URI, could redirect a resource owner to a third-party web page infected with malware or similar. To mitigate this specific risk, the resource server could check that the URI is fully qualified and matches the host and scheme of the authorization server.
The communication between the authorization server and resource server may expose personally identifiable information of a resource owner. The context in which this API is used SHOULD account for its own unique privacy considerations.
This document makes no request of IANA.
The following non-normative example illustrates the intent and usage of resource set descriptions and scope descriptions as part of resource set registration in the context of [UMA].
This example contains some steps that are exclusively in the realm of user experience rather than web protocol, to achieve realistic illustration. These steps are labeled "user experience only". Some other steps are exclusively internal to the operation of the entity being discussed. These are labeled "internal only".
This example also does not contain any information regarding the mechanism that is used to authenticate the resource server at the authorization server, and mechanisms such as OAuth can be used for this purpose.
A resource owner, Alice Adams, has just uploaded a photo of her new puppy to a resource server, Photoz.example.com, and wants to ensure that this specific photo is not publicly accessible.
Alice has already introduced this resource server to her authorization server, CopMonkey.example.com. However, Alice has not previously instructed Photoz to use CopMonkey to protect any photos of hers.
CopMonkey has a "default-deny" setup, so until such time as Alice maps some other more permissive policies to any resource sets registered by Photoz, the policy is not to share them. Policies she may eventually map to particular photos or albums might be "Share only with husband@email.example.net" or "Share only with people in my 'family' group".
Photoz has a publicly documented application-specific API that offers two dozen different methods that apply to single photos, such as addTags and getSizes, but rolls them up into two photo-related scopes of access: "view" (consisting of various read-only operations) and "print" (consisting of various printing operations). It defines two scope descriptions that represent these scopes, which it is able to reuse for all of its users (not just Alice), and ensures that these scope description documents are available through HTTP GET requests that may be made by authorization servers.
Photoz constructs scope description documents for the scopes in order to provide data that will help them be displayed in user interfaces. (This means that any scope strings it supplies in resource set registration descriptions will need to be URIs referring to these documents. The alternative would have been simple scope strings without the additional user interface data.)
The "name" property values in the scope descriptions are intended to be seen by Alice when she maps authorization constraints to specific resource sets and actions while visiting CopMonkey, such that Alice would see the strings "View Photo and Related Info" and "Print Photo", likely accompanied by the referenced icons, in the CopMonkey interface. (Other users of Photoz might similarly see the same labels at CopMonkey or whatever other authorization server they use. Photoz could distinguish natural-language labels per user if it wishes, by pointing to scopes with differently translated names.)
Example of the viewing-related scope description document available at http://photoz.example.com/dev/scopes/view:
{ "name" : "View Photo and Related Info", "icon_uri" : "http://www.example.com/icons/reading-glasses.png" }
Example of the scope description document available at http://photoz.example.com/dev/scopes/print:
{ "name" : "Print Photo", "icon_uri" : "http://www.example.com/icons/printer.png" }
While visiting Photoz, Alice selects a link or button that instructs the site to "Protect" or "Share" this single photo (user experience only; Photoz could have made this a default or preference setting).
As a result, Photoz defines for itself a resource set that represents this photo (internal only; Photoz is the only application that knows how to map a particular photo to a particular resource set). Photoz also prepares the following resource set description, which is specific to Alice and her photo. The "name" property value is intended to be seen by Alice in mapping authorization policies to specific resource sets and actions when she visits CopMonkey. Alice would see the string "Steve the puppy!", likely accompanied by the referenced icon, in the CopMonkey interface. The possible scopes of access on this resource set are indicated with URI references to the scope descriptions, as shown just above.
{ "name" : "Steve the puppy!", "icon_uri" : "http://www.example.com/icons/flower.png", "scopes" : [ "http://photoz.example.com/dev/scopes/view", "http://photoz.example.com/dev/scopes/print" ] }
Photoz uses the Create method of CopMonkey's standard OAuth resource set registration API, presenting its Alice-specific access token to use the API to register and assign an identifier to the resource set description.
POST /rs/resource_set HTTP/1.1 Content-Type: application/json ... { "name" : "Steve the puppy!", "icon_uri" : "http://www.example.com/icons/flower.png", "scopes" : [ "http://photoz.example.com/dev/scopes/view", "http://photoz.example.com/dev/scopes/print" ] }
If the registration attempt succeeds, CopMonkey responds in the following fashion.
HTTP/1.1 201 Created Content-Type: application/json ... { "_id" : "112210f47de98100", "user_access_policy_uri" : "http://as.example.com/rs/222/resource/112210f47de98100/policy" }
At the time Alice indicates she would like this photo protected, Photoz can choose to redirect Alice to CopMonkey for further policy setting, access auditing, and other authorization server-related tasks (user experience only).
Once it has successfully registered this description, Photoz is responsible for outsourcing protection to CopMonkey for access attempts made to this photo.
Over time, as Alice uploads other photos and creates and organizes photo albums, Photoz can use additional methods of the resource set registration API to ensure that CopMonkey's understanding of Alice's protected resources matches its own.
For example, if Photoz suspects that somehow its understanding of the resource set has gotten out of sync with CopMonkey's, it can ask to read the resource set description as follows.
GET /rs/resource_set/112210f47de98100 HTTP/1.1 Host: as.example.com ...
CopMonkey responds with the full content of the resource set description, including its _id, as follows:
Example of an HTTP response to a "read resource set description" request, containing a resource set description from the authorization server:
HTTP/1.1 200 OK Content-Type: application/json ... { "_id" : "112210f47de98100", "name" : "Steve the puppy!", "icon_uri" : "http://www.example.com/icons/flower.png", "scopes" : [ "http://photoz.example.com/dev/scopes/view", "http://photoz.example.com/dev/scopes/print" ] }
If for some reason Photoz and CopMonkey have gotten dramatically out of sync, Photoz can ask for the list of resource set identifiers CopMonkey currently knows about:
GET /rs/resource_set HTTP/1.1 Host: as.example.com ...
CopMonkey's response might look as follows:
HTTP/1.1 200 OK ... [ "112210f47de98100", "34234df47eL95300" ]
If Alice later changes the photo's title (user experience only) on Photoz from "Steve the puppy!" to "Steve on October 14, 2011", Photoz would use the Update method to ensure that Alice's experience of policy-setting at CopMonkey remains consistent with what she sees at Photoz. Following is an example of this request. Note that the entire updated resource set description has to be included in the PUT request.
PUT /rs/resource_set/112210f47de98100 HTTP/1.1 Content-Type: application/json Host: as.example.com ... { "name" : "Steve on October 14, 2011", "icon_uri" : "http://www.example.com/icons/flower.png", "scopes" : [ "http://photoz.example.com/dev/scopes/view", "http://photoz.example.com/dev/scopes/print" ] }
CopMonkey would respond as follows.
HTTP/1.1 201 Created Content-Type: application/json ... { "_id" : "112210f47de98100" }
There are other reasons Photoz might want to update resource set descriptions, having nothing to do with Alice's actions or wishes. For example, it might extend its API to include new features such as photo resizing, and want to add new scopes to all of Alice's and other users' resource set descriptions.
if Alice later decides to entirely remove sharing protection (user experience only) on this photo while visiting Photoz, ensuring that the public can get access without any protection, Photoz is responsible for deleting the relevant resource set registration, as follows:
DELETE /rs/resource_set/112210f47de98100 HTTP/1.1 Host: as.example.com ...
The following people made significant text contributions to the specification:
Additional contributors to this specification include the Kantara UMA Work Group participants, a list of whom can be found at [UMAnitarians].
[RFC2119] | Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>. |
[RFC6749] | Hardt, D., Ed., “The OAuth 2.0 Authorization Framework”, RFC 6749, DOI 10.17487/RFC6749, October 2012, <http://www.rfc-editor.org/info/rfc6749>. |
[RFC7159] | Bray, T., Ed., “The JavaScript Object Notation (JSON) Data Interchange Format”, RFC 7159, DOI 10.17487/RFC7159, March 2014, <http://www.rfc-editor.org/info/rfc7159>. |
[OpenIDConnect] | Sakimura, N., “OpenID Connect Core 1.0 incorporating errata set 1”, November 2014, <http://openid.net/specs/openid-connect-core-1_0.html>. |
[UMA] | Hardjono, T., “User-Managed Access (UMA) Profile of OAuth 2.0”, December 2015, <https://docs.kantarainitiative.org/uma/rec-uma-core-v1_0_1.html>. |
[UMAnitarians] | Maler, E., “UMA Participant Roster”, 2015, <https://kantarainitiative.org/confluence/display/uma/Participant+Roster>. |
Thomas Hardjono
(editor)
MIT
EMail: hardjono@mit.edu
Eve Maler
ForgeRock
EMail: eve.maler@forgerock.com
Maciej Machulak
Synergetics
EMail: maciej@synergetics.be
Domenico Catalano
Oracle
EMail: domenico.catalano@oracle.com