The following sections detail the profiling and extensions of OAuth 2.0 for constrained environments, which constitutes the ACE framework.
-
Credential Provisioning
-
In constrained environments, it cannot be assumed that the client and the RS are part of a common key infrastructure. Therefore, the AS provisions credentials and associated information to allow mutual authentication between the client and the RS. The resulting security association between the client and the RS may then also be used to bind these credentials to the access tokens the client uses.
-
Proof of Possession
-
The ACE framework, by default, implements proof of possession for access tokens, i.e., that the token holder can prove being a holder of the key bound to the token. The binding is provided by the cnf (confirmation) claim [RFC 8747], indicating what key is used for proof of possession. If a client needs to submit a new access token, e.g., to obtain additional access rights, they can request that the AS binds this token to the same key as the previous one.
-
ACE Profiles
-
The client or RS may be limited in the encodings or protocols it supports. To support a variety of different deployment settings, specific interactions between the client and RS are defined in an ACE profile. In the ACE framework, the AS is expected to manage the matching of compatible profile choices between a client and an RS. The AS informs the client of the selected profile using the ace_profile parameter in the token response.
OAuth 2.0 requires the use of TLS to protect the communication between the AS and client when requesting an access token between the client and RS when accessing a resource and between the AS and RS if introspection is used. In constrained settings, TLS is not always feasible or desirable. Nevertheless, it is
REQUIRED that the communications named above are encrypted, integrity protected, and protected against message replay. It is also
REQUIRED that the communicating endpoints perform mutual authentication. Furthermore, it
MUST be assured that responses are bound to the requests in the sense that the receiver of a response can be certain that the response actually belongs to a certain request. Note that setting up such a secure communication may require some unprotected messages to be exchanged first (e.g., sending the token from the client to the RS).
Profiles
MUST specify a communication security protocol between the client and RS that provides the features required above. Profiles
MUST specify a communication security protocol
RECOMMENDED to be used between the client and AS that provides the features required above. Profiles
MUST specify, for introspection, a communication security protocol
RECOMMENDED to be used between the RS and AS that provides the features required above. These recommendations enable interoperability between different implementations without the need to define a new profile if the communication between the C and AS, or between the RS and AS, is protected with a different security protocol complying with the security requirements above.
In OAuth 2.0, the communication with the Token and the Introspection endpoints at the AS is assumed to be via HTTP and may use Uri-query parameters. When profiles of this framework use CoAP instead, it is
REQUIRED to use of the following alternative instead of Uri-query parameters: The sender (client or RS) encodes the parameters of its request as a CBOR map and submits that map as the payload of the POST request. The CBOR encoding for a number of OAuth 2.0 parameters is specified in this document; if a profile needs to use other OAuth 2.0 parameters with CoAP, it
MUST specify their CBOR encoding.
Profiles that use CBOR encoding of protocol message parameters at the outermost encoding layer
MUST use the Content-Format "application/ace+cbor". If CoAP is used for communication, the Content-Format
MUST be abbreviated with the ID: 19 (see
Section 8.16).
The OAuth 2.0 AS uses a JSON structure in the payload of its responses both to the client and RS. If CoAP is used, it is
REQUIRED to use CBOR [
RFC 8949] instead of JSON. Depending on the profile, the CBOR payload
MAY be enclosed in a non-CBOR cryptographic wrapper.
The C must discover the AS in charge of the RS to determine where to request the access token. To do so, the C 1) must find out the AS URI to which the token request message must be sent and 2)
MUST validate that the AS with this URI is authorized to provide access tokens for this RS.
In order to determine the AS URI, the C
MAY send an initial Unauthorized Resource Request message to the RS. The RS then denies the request and sends the address of its AS back to the C (see
Section 5.2). How the C validates the AS authorization is not in scope for this document. The C may, for example, ask its owner if this AS is authorized for this RS. The C may also use a mechanism that addresses both problems at once (e.g., by querying a dedicated secure service provided by the client owner) .
An Unauthorized Resource Request message is a request for any resource hosted by the RS for which the client does not have authorization granted. The RSs
MUST treat any request for a protected resource as an Unauthorized Resource Request message when any of the following hold:
-
The request has been received on an unsecured channel.
-
The RS has no valid access token for the sender of the request regarding the requested action on that resource.
-
The RS has a valid access token for the sender of the request, but that token does not authorize the requested action on the requested resource.
Note: These conditions ensure that the RS can handle requests autonomously once access was granted and a secure channel has been established between the C and RS. The authz-info endpoint, as part of the process for authorizing to protected resources, is not itself a protected resource and
MUST NOT be protected as specified above (cf.
Section 5.10.1).
Unauthorized Resource Request messages
MUST be denied with an "unauthorized_client" error response. In this response, the resource server
SHOULD provide proper AS Request Creation Hints to enable the client to request an access token from the RS's AS, as described in
Section 5.3.
The handling of all client requests (including unauthorized ones) by the RS is described in
Section 5.10.2.
The AS Request Creation Hints are sent by an RS as a response to an Unauthorized Resource Request message (see
Section 5.2) to help the sender of the Unauthorized Resource Request message acquire a valid access token. The AS Request Creation Hints are a CBOR or JSON map, with an
OPTIONAL element
AS specifying an absolute URI (see
Section 4.3 of
RFC 3986) that identifies the appropriate AS for the RS.
The message can also contain the following
OPTIONAL parameters:
-
An audience element contains an identifier the client should request at the AS, as suggested by the RS. With this parameter, when included in the access token request to the AS, the AS is able to restrict the use of the access token to specific RSs. See Section 6.9 for a discussion of this parameter.
-
A kid (key identifier) element contains the key identifier of a key used in an existing security association between the client and the RS. The RS expects the client to request an access token bound to this key in order to avoid having to reestablish the security association.
-
A cnonce element contains a client-nonce. See Section 5.3.1.
-
A scope element contains the suggested scope that the client should request towards the AS.
Table 1 summarizes the parameters that may be part of the AS Request Creation Hints.
Name |
CBOR Key |
Value Type |
AS |
1 |
text string |
kid |
2 |
byte string |
audience |
5 |
text string |
scope |
9 |
text or byte string |
cnonce |
39 |
byte string |
Table 1: AS Request Creation Hints
Note that the schema part of the AS parameter may need to be adapted to the security protocol that is used between the client and the AS. Thus, the example AS value "coap://as.example.com/token" might need to be transformed to "coaps://as.example.com/token". It is assumed that the client can determine the correct schema part on its own depending on the way it communicates with the AS.
Figure 2 shows an example for an AS Request Creation Hints payload using diagnostic notation.
4.01 Unauthorized
Content-Format: application/ace+cbor
Payload :
{
/ AS / 1 : "coaps://as.example.com/token",
/ audience / 5 : "coaps://rs.example.com",
/ scope / 9 : "rTempC",
/ cnonce / 39 : h'e0a156bb3f'
}
In the example above, the response parameter
AS points the receiver of this message to the URI "coaps://as.example.com/token" to request access tokens. The RS sending this response uses an internal clock that is not synchronized with the clock of the AS. Therefore, it cannot reliably verify the expiration time of access tokens it receives. Nevertheless, to ensure a certain level of access token freshness, the RS has included a
cnonce parameter (see
Section 5.3.1) in the response. (The hex sequence of the
cnonce parameter is encoded in CBOR-based notation in this example.)
Figure 3 illustrates the mandatory use of binary encoding of the message payload shown in
Figure 2.
a4 # map(4)
01 # unsigned(1) (=AS)
78 1c # text(28)
636f6170733a2f2f61732e657861
6d706c652e636f6d2f746f6b656e # "coaps://as.example.com/token"
05 # unsigned(5) (=audience)
76 # text(22)
636f6170733a2f2f72732e657861
6d706c652e636f6d # "coaps://rs.example.com"
09 # unsigned(9) (=scope)
66 # text(6)
7254656d7043 # "rTempC"
18 27 # unsigned(39) (=cnonce)
45 # bytes(5)
e0a156bb3f #
If the RS does not synchronize its clock with the AS, it could be tricked into accepting old access tokens that are either expired or have been compromised. In order to ensure some level of token freshness in that case, the RS can use the
cnonce (client-nonce) parameter. The processing requirements for this parameter are as follows:
-
An RS sending a cnonce parameter in an AS Request Creation Hints message MUST store information to validate that a given cnonce is fresh. How this is implemented internally is out of scope for this specification. Expiration of client-nonces should be based roughly on the time it would take a client to obtain an access token after receiving the AS Request Creation Hints, with some allowance for unexpected delays.
-
A client receiving a cnonce parameter in an AS Request Creation Hints message MUST include this in the parameters when requesting an access token at the AS, using the cnonce parameter from Section 5.8.4.4.
-
If an AS grants an access token request containing a cnonce parameter, it MUST include this value in the access token, using the cnonce claim specified in Section 5.10.
-
An RS that is using the client-nonce mechanism and that receives an access token MUST verify that this token contains a cnonce claim, with a client-nonce value that is fresh according to the information stored at the first step above. If the cnonce claim is not present or if the cnonce claim value is not fresh, the RS MUST discard the access token. If this was an interaction with the authz-info endpoint, the RS MUST also respond with an error message using a response code equivalent to the CoAP code 4.01 (Unauthorized).
To request an access token, the client obtains authorization from the resource owner or uses its client credentials as a grant. The authorization is expressed in the form of an authorization grant.
The OAuth framework [
RFC 6749] defines four grant types. The grant types can be split up into two groups: those granted on behalf of the resource owner (password, authorization code, implicit) and those for the client (client credentials). Further grant types have been added later, such as an assertion-based authorization grant defined in [
RFC 7521].
The grant type is selected depending on the use case. In cases where the client acts on behalf of the resource owner, the authorization code grant is recommended. If the client acts on behalf of the resource owner but does not have any display or has very limited interaction possibilities, it is recommended to use the device code grant defined in [
RFC 8628]. In cases where the client acts autonomously, the client credentials grant is recommended.
For details on the different grant types, see
Section 1.3 of
RFC 6749. The OAuth 2.0 framework provides an extension mechanism for defining additional grant types, so profiles of this framework
MAY define additional grant types, if needed.
Authentication of the client is mandatory independent of the grant type when requesting an access token from the token endpoint. In the case of the client credentials grant type, the authentication and grant coincide.
Client registration and provisioning of client credentials to the client is out of scope for this specification.
The OAuth framework defines one client credential type in
Section 2.3.1 of
RFC 6749 that comprises the client_id and client_secret values. [
OAUTH-RPCC] adds raw public key and pre-shared key to the client credentials type. Profiles of this framework
MAY extend it with an additional client credentials type using client certificates.
The client credentials grant does not, by default, authenticate the AS that the client connects to. In classic OAuth, the AS is authenticated with a TLS server certificate.
Profiles of this framework
MUST specify how clients authenticate the AS and how communication security is implemented. By default, server side TLS certificates, as defined by OAuth 2.0, are required.
The OAuth 2.0 authorization endpoint is used to interact with the resource owner and obtain an authorization grant in certain grant flows. The primary use case for the ACE-OAuth framework is for machine-to-machine interactions that do not involve the resource owner in the authorization flow; therefore, this endpoint is out of scope here. Future profiles may define constrained adaptation mechanisms for this endpoint as well. Nonconstrained clients interacting with constrained resource servers can use the specification in
Section 3.1 of
RFC 6749 and the attack countermeasures suggested in
Section 4.2 of
RFC 6819.
In standard OAuth 2.0, the AS provides the token endpoint for submitting access token requests. This framework extends the functionality of the token endpoint, giving the AS the possibility to help the client and RS establish shared keys or exchange their public keys. Furthermore, this framework defines encodings using CBOR as a substitute for JSON.
The endpoint may also be exposed over HTTPS, as in classical OAuth or even other transports. A profile
MUST define the details of the mapping between the fields described below and these transports. If HTTPS with JSON is used, the semantics of Sections
4.1.3 and
4.1.4 of the OAuth 2.0 specification [
RFC 6749]
MUST be followed (with additions as described below). If CBOR is used as the payload format, the semantics described in this section
MUST be followed.
For the AS to be able to issue a token, the client
MUST be authenticated and present a valid grant for the scopes requested. Profiles of this framework
MUST specify how the AS authenticates the client and how the communication between the client and AS is protected, fulfilling the requirements specified in
Section 5.
The default name of this endpoint in a url-path
SHOULD be '/token'. However, implementations are not required to use this name and can define their own instead.
The client sends a POST request to the token endpoint at the AS. The profile
MUST specify how the communication is protected. The content of the request consists of the parameters specified in the relevant subsection of Section
4 of the OAuth 2.0 specification [
RFC 6749], depending on the grant type, with the following exceptions and additions:
-
The grant_type parameter is OPTIONAL in the context of this framework (as opposed to REQUIRED in [RFC 6749]). If that parameter is missing, the default value "client_credentials" is implied.
-
The audience parameter from [RFC 8693] is OPTIONAL to request an access token bound to a specific audience.
-
The cnonce parameter defined in Section 5.8.4.4 is REQUIRED if the RS provided a client-nonce in the AS Request Creation Hints message (Section 5.3).
-
The scope parameter MAY be encoded as a byte string instead of the string encoding specified in Section 3.3 of RFC 6749 or in order to allow compact encoding of complex scopes. The syntax of such a binary encoding is explicitly not specified here and left to profiles or applications. Note specifically that a binary encoded scope does not necessarily use the space character '0x20' to delimit scope-tokens.
-
The client can send an empty (null value) ace_profile parameter to indicate that it wants the AS to include the ace_profile parameter in the response. See Section 5.8.4.3.
-
A client MUST be able to use the parameters from [RFC 9201] in an access token request to the token endpoint, and the AS MUST be able to process these additional parameters.
The default behavior is that the AS generates a symmetric proof-of-possession key for the client. In order to use an asymmetric key pair or to reuse a key previously established with the RS, the client is supposed to use the
req_cnf parameter from [
RFC 9201].
If CoAP is used, then these parameters
MUST be provided in a CBOR map (see
Table 5).
When HTTP is used as a transport, then the client makes a request to the token endpoint; the parameters
MUST be encoded as defined in
Appendix B of
RFC 6749.
The following examples illustrate different types of requests for proof-of-possession tokens.
Figure 4 shows a request for a token with a symmetric proof-of-possession key, using diagnostic notation.
Header: POST (Code=0.02)
Uri-Host: "as.example.com"
Uri-Path: "token"
Content-Format: application/ace+cbor
Payload:
{
/ client_id / 24 : "myclient",
/ audience / 5 : "tempSensor4711"
}
Figure 5 shows a request for a token with an asymmetric proof-of-possession key. Note that, in this example, OSCORE [
RFC 8613] is used to provide object-security; therefore, the Content-Format is "application/oscore" wrapping the "application/ace+cbor" type content. The OSCORE option has a decoded interpretation appended in parentheses for the reader's convenience. Also note that, in this example, the audience is implicitly known by both the client and AS. Furthermore, note that this example uses the
req_cnf parameter from [
RFC 9201].
Header: POST (Code=0.02)
Uri-Host: "as.example.com"
Uri-Path: "token"
OSCORE: 0x09, 0x05, 0x44, 0x6C
(h=0, k=1, n=001, partialIV= 0x05, kid=[0x44, 0x6C])
Content-Format: application/oscore
Payload:
0x44025d1/ ... (full payload omitted for brevity) ... /68b3825e
Decrypted payload:
{
/ client_id / 24 : "myclient",
/ req_cnf / 4 : {
/ COSE_Key / 1 : {
/ kty / 1 : 2 / EC2 /,
/ kid / 2 : h'11',
/ crv / -1 : 1 / P-256 /,
/ x / -2 : b64'usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8',
/ y / -3 : b64'IBOL+C3BttVivg+lSreASjpkttcsz+1rb7btKLv8EX4'
}
}
}
Figure 6 shows a request for a token where a previously communicated proof-of-possession key is only referenced using the
req_cnf parameter from [
RFC 9201].
Header: POST (Code=0.02)
Uri-Host: "as.example.com"
Uri-Path: "token"
Content-Format: application/ace+cbor
Payload:
{
/ client_id / 24 : "myclient",
/ audience / 5 : "valve424",
/ scope / 9 : "read",
/ req_cnf / 4 : {
/ kid / 3 : b64'6kg0dXJM13U'
}
}
Refresh tokens are typically not stored as securely as proof-of-possession keys in requesting clients. Proof-of-possession-based refresh token requests
MUST NOT request different proof-of-possession keys or different audiences in token requests. Refresh token requests can only be used to request access tokens bound to the same proof-of-possession key and the same audience as access tokens issued in the initial token request.
If the access token request has been successfully verified by the AS and the client is authorized to obtain an access token corresponding to its access token request, the AS sends a response with the response code equivalent to the CoAP response code 2.01 (Created). If the client request was invalid, or not authorized, the AS returns an error response, as described in
Section 5.8.3.
Note that the AS decides which token type and profile to use when issuing a successful response. It is assumed that the AS has prior knowledge of the capabilities of the client and the RS (see
Appendix D). This prior knowledge may, for example, be set by the use of a dynamic client registration protocol exchange [
RFC 7591]. If the client has requested a specific proof-of-possession key using the
req_cnf parameter from [
RFC 9201], this may also influence which profile the AS selects, as it needs to support the use of the key type requested by the client.
The content of the successful reply is the Access Information. When using CoAP, the payload
MUST be encoded as a CBOR map; when using HTTP, the encoding is a JSON map, as specified in
Section 5.1 of
RFC 6749. In both cases, the parameters specified in
Section 5.1 of
RFC 6749 are used, with the following additions and changes:
-
ace_profile:
-
This parameter is OPTIONAL unless the request included an empty ace_profile parameter, in which case it is MANDATORY. This indicates the profile that the client MUST use towards the RS. See Section 5.8.4.3 for the formatting of this parameter. If this parameter is absent, the AS assumes that the client implicitly knows which profile to use towards the RS.
-
token_type:
-
This parameter is OPTIONAL, as opposed to REQUIRED in [RFC 6749]. By default, implementations of this framework SHOULD assume that the token_type is "PoP". If a specific use case requires another token_type (e.g., "Bearer") to be used, then this parameter is REQUIRED.
Furthermore, [
RFC 9201] defines additional parameters that the AS
MUST be able to use when responding to a request to the token endpoint.
Table 2 summarizes the parameters that can currently be part of the Access Information. Future extensions may define additional parameters.
Table 2: Access Information Parameters
Figure 7 shows a response containing a token and a
cnf parameter with a symmetric proof-of-possession key, which is defined in [
RFC 9201]. Note that the key identifier
kid is only used to simplify indexing and retrieving the key, and no assumptions should be made that it is unique in the domains of either the client or the RS.
Header: Created (Code=2.01)
Content-Format: application/ace+cbor
Payload:
{
/ access_token / 1 : b64'SlAV32hk'/ ...
(remainder of CWT omitted for brevity;
CWT contains COSE_Key in the cnf claim)/,
/ ace_profile / 38 : "coap_dtls",
/ expires_in / 2 : 3600,
/ cnf / 8 : {
/ COSE_Key / 1 : {
/ kty / 1 : 4 / Symmetric /,
/ kid / 2 : b64'39Gqlw',
/ k / -1 : b64'hJtXhkV8FJG+Onbc6mxC'
}
}
}
The error responses for interactions with the AS are generally equivalent to the ones defined in
Section 5.2 of
RFC 6749, with the following exceptions:
-
When using CoAP, the payload MUST be encoded as a CBOR map, with the Content-Format "application/ace+cbor". When using HTTP, the payload is encoded in JSON, as specified in Section 5.2 of RFC 6749.
-
A response code equivalent to the CoAP code 4.00 (Bad Request) MUST be used for all error responses, except for invalid_client, where a response code equivalent to the CoAP code 4.01 (Unauthorized) MAY be used under the same conditions as specified in Section 5.2 of RFC 6749.
-
The parameters error, error_description, and error_uri MUST be abbreviated using the codes specified in Table 5, when a CBOR encoding is used.
-
The error code (i.e., value of the error parameter) MUST be abbreviated, as specified in Table 3, when a CBOR encoding is used.
Table 3: CBOR Abbreviations for Common Error Codes
In addition to the error responses defined in OAuth 2.0, the following behavior
MUST be implemented by the AS:
-
If the client submits an asymmetric key in the token request that the RS cannot process, the AS MUST reject that request with a response code equivalent to the CoAP code 4.00 (Bad Request), including the error code "unsupported_pop_key" specified in Table 3.
-
If the client and the RS it has requested an access token for do not share a common profile, the AS MUST reject that request with a response code equivalent to the CoAP code 4.00 (Bad Request), including the error code "incompatible_ace_profiles" specified in Table 3.
This section provides more detail about the new parameters that can be used in access token requests and responses, as well as abbreviations for more compact encoding of existing parameters and common parameter values.
The
token_type parameter, defined in
Section 5.1 of
RFC 6749, allows the AS to indicate to the client which type of access token it is receiving (e.g., a bearer token).
This document registers the new value "PoP" for the "OAuth Access Token Types" registry, specifying a proof-of-possession token. How the proof of possession by the client to the RS is performed
MUST be specified by the profiles.
The values in the
token_type parameter
MUST use the CBOR abbreviations defined in the registry specified by
Section 8.7 if a CBOR encoding is used.
In this framework, the "pop" value for the
token_type parameter is the default. The AS may, however, provide a different value from those registered in [
IANA.OAuthAccessTokenTypes].
Profiles of this framework
MUST define the communication protocol and the communication security protocol between the client and the RS. The security protocol
MUST provide encryption, integrity, and replay protection. It
MUST also provide a binding between requests and responses. Furthermore, profiles
MUST define a list of allowed proof-of-possession methods if they support proof-of-possession tokens.
A profile
MUST specify an identifier that
MUST be used to uniquely identify itself in the
ace_profile parameter. The textual representation of the profile identifier is intended for human readability and for JSON-based interactions; it
MUST NOT be used for CBOR-based interactions. Profiles
MUST register their identifier in the registry defined in
Section 8.8.
Profiles
MAY define additional parameters for both the token request and the Access Information in the access token response in order to support negotiation or signaling of profile-specific parameters.
Clients that want the AS to provide them with the
ace_profile parameter in the access token response can indicate that by sending an
ace_profile parameter with a null value for CBOR-based interactions, or an empty string if CBOR is not used, in the access token request.
This parameter
MUST be sent from the client to the AS if it previously received a
cnonce parameter in the AS Request Creation Hints (
Section 5.3). The parameter is encoded as a byte string for CBOR-based interactions and as a string (base64url without padding encoded binary [
RFC 4648]) if CBOR is not used. It
MUST copy the value from the
cnonce parameter in the AS Request Creation Hints.
If CBOR encoding is used, all OAuth parameters in access token requests and responses
MUST be mapped to CBOR types, as specified in the registry defined by
Section 8.10, using the given integer abbreviation for the map keys.
Note that we have aligned the abbreviations corresponding to claims with the abbreviations defined in [
RFC 8392].
Note also that abbreviations from -24 to 23 have a 1-byte encoding size in CBOR. We have thus chosen to assign abbreviations in that range to parameters we expect to be used most frequently in constrained scenarios.
Name |
CBOR Key |
Value Type |
Original Specification |
access_token
|
1 |
byte string |
[RFC 6749]
|
expires_in
|
2 |
unsigned integer |
[RFC 6749]
|
audience
|
5 |
text string |
[RFC 8693]
|
scope
|
9 |
text or byte string |
[RFC 6749]
|
client_id
|
24 |
text string |
[RFC 6749]
|
client_secret
|
25 |
byte string |
[RFC 6749]
|
response_type
|
26 |
text string |
[RFC 6749]
|
redirect_uri
|
27 |
text string |
[RFC 6749]
|
state
|
28 |
text string |
[RFC 6749]
|
code
|
29 |
byte string |
[RFC 6749]
|
error
|
30 |
integer |
[RFC 6749]
|
error_description
|
31 |
text string |
[RFC 6749]
|
error_uri
|
32 |
text string |
[RFC 6749]
|
grant_type
|
33 |
unsigned integer |
[RFC 6749]
|
token_type
|
34 |
integer |
[RFC 6749]
|
username
|
35 |
text string |
[RFC 6749]
|
password
|
36 |
text string |
[RFC 6749]
|
refresh_token
|
37 |
byte string |
[RFC 6749]
|
ace_profile
|
38 |
integer |
RFC 9200 |
cnonce
|
39 |
byte string |
RFC 9200 |
Table 5: CBOR Mappings Used in Token Requests and Responses
Token introspection [
RFC 7662]
MAY be implemented by the AS and the RS. When implemented, it
MAY be used by the RS and to query the AS for metadata about a given token, e.g., validity or scope. Analogous to the protocol defined in [
RFC 7662] for HTTP and JSON, this section defines adaptations to more constrained environments using CBOR and leaving the choice of the application protocol to the profile. The client
MAY also implement and use introspection analogously to the RS to obtain information about a given token.
Communication between the requesting entity and the introspection endpoint at the AS
MUST be integrity protected and encrypted. The communication security protocol
MUST also provide a binding between requests and responses. Furthermore, the two interacting parties
MUST perform mutual authentication. Finally, the AS
SHOULD verify that the requesting entity has the right to access introspection information about the provided token. Profiles of this framework that support introspection
MUST specify how authentication and communication security between the requesting entity and the AS is implemented.
The default name of this endpoint in a url-path
SHOULD be '/introspect'. However, implementations are not required to use this name and can define their own instead.
The requesting entity sends a POST request to the introspection endpoint at the AS. The profile
MUST specify how the communication is protected. If CoAP is used, the payload
MUST be encoded as a CBOR map with a
token entry containing the access token. Further optional parameters representing additional context that is known by the requesting entity to aid the AS in its response
MAY be included.
For CoAP-based interaction, all messages
MUST use the content type "application/ace+cbor". For HTTP, the encoding defined in
Section 2.1 of
RFC 7662 is used.
The same parameters are required and optional as in
Section 2.1 of
RFC 7662.
For example,
Figure 8 shows an RS calling the token introspection endpoint at the AS to query about an OAuth 2.0 proof-of-possession token. Note that object security based on OSCORE [
RFC 8613] is assumed in this example; therefore, the Content-Format is "application/oscore".
Figure 9 shows the decoded payload.
Header: POST (Code=0.02)
Uri-Host: "as.example.com"
Uri-Path: "introspect"
OSCORE: 0x09, 0x05, 0x25
Content-Format: application/oscore
Payload:
... COSE content ...
{
/ token / 11 : b64'7gj0dXJQ43U',
/ token_type_hint / 33 : 2 / PoP /
}
If the introspection request is authorized and successfully processed, the AS sends a response with the response code equivalent to the CoAP code 2.01 (Created). If the introspection request was invalid, not authorized, or couldn't be processed, the AS returns an error response, as described in
Section 5.9.3.
In a successful response, the AS encodes the response parameters in a map. If CoAP is used, this
MUST be encoded as a CBOR map; if HTTP is used, the JSON encoding specified in
Section 2.2 of
RFC 7662 is used. The map containing the response payload includes the same required and optional parameters as in
Section 2.2 of
RFC 7662, with the following additions:
-
ace_profile
-
This parameter is OPTIONAL. This indicates the profile that the RS MUST use with the client. See Section 5.8.4.3 for more details on the formatting of this parameter. If this parameter is absent, the AS assumes that the RS implicitly knows which profile to use towards the client.
-
cnonce
-
This parameter is OPTIONAL. This is a client-nonce provided to the AS by the client. The RS MUST verify that this corresponds to the client-nonce previously provided to the client in the AS Request Creation Hints. See Sections [5.3] and [5.8.4.4]. Its value is a byte string when encoded in CBOR and is the base64url encoding of this byte string without padding when encoded in JSON [RFC 4648].
-
cti
-
This parameter is OPTIONAL. This is the cti claim associated to this access token. This parameter has the same meaning and processing rules as the jti parameter defined in Section 3.1.2 of RFC 7662 except that its value is a byte string when encoded in CBOR and is the base64url encoding of this byte string without padding when encoded in JSON [RFC 4648].
-
exi
-
This parameter is OPTIONAL. This is the expires_in claim associated to this access token. See Section 5.10.3.
Furthermore, [
RFC 9201] defines more parameters that the AS
MUST be able to use when responding to a request to the introspection endpoint.
For example,
Figure 10 shows an AS response to the introspection request in
Figure 8. Note that this example contains the
cnf parameter defined in [
RFC 9201].
Header: Created (Code=2.01)
Content-Format: application/ace+cbor
Payload:
{
/ active / 10 : true,
/ scope / 9 : "read",
/ ace_profile / 38 : 1 / coap_dtls /,
/ cnf / 8 : {
/ COSE_Key / 1 : {
/ kty / 1 : 4 / Symmetric /,
/ kid / 2 : b64'39Gqlw',
/ k / -1 : b64'hJtXhkV8FJG+Onbc6mxC'
}
}
}
The error responses for CoAP-based interactions with the AS are equivalent to the ones for HTTP-based interactions, as defined in
Section 2.3 of
RFC 7662, with the following differences:
-
If content is sent and CoAP is used, the payload MUST be encoded as a CBOR map and the Content-Format "application/ace+cbor" MUST be used. For HTTP, the encoding defined in Section 2.3 of RFC 6749 is used.
-
If the credentials used by the requesting entity (usually the RS) are invalid, the AS MUST respond with the response code equivalent to the CoAP code 4.01 (Unauthorized) and use the required and optional parameters from Section 2.3 of RFC 7662.
-
If the requesting entity does not have the right to perform this introspection request, the AS MUST respond with a response code equivalent to the CoAP code 4.03 (Forbidden). In this case, no payload is returned.
-
The parameters error, error_description, and error_uri MUST be abbreviated using the codes specified in Table 5.
-
The error codes MUST be abbreviated using the codes specified in the registry defined by Section 8.4.
Note that a properly formed and authorized query for an inactive or otherwise invalid token does not warrant an error response by this specification. In these cases, the authorization server
MUST instead respond with an introspection response with the
active field set to "false".
If CBOR is used, the introspection request and response parameters
MUST be mapped to CBOR types, as specified in the registry defined by
Section 8.12, using the given integer abbreviation for the map key.
Note that we have aligned abbreviations that correspond to a claim with the abbreviations defined in [
RFC 8392] and the abbreviations of parameters with the same name from
Section 5.8.5.
Parameter name |
CBOR Key |
Value Type |
Original Specification |
iss
|
1 |
text string |
[RFC 7662]
|
sub
|
2 |
text string |
[RFC 7662]
|
aud
|
3 |
text string |
[RFC 7662]
|
exp
|
4 |
integer or floating-point number |
[RFC 7662]
|
nbf
|
5 |
integer or floating-point number |
[RFC 7662]
|
iat
|
6 |
integer or floating-point number |
[RFC 7662]
|
cti
|
7 |
byte string |
RFC 9200 |
scope
|
9 |
text or byte string |
[RFC 7662]
|
active
|
10 |
True or False |
[RFC 7662]
|
token
|
11 |
byte string |
[RFC 7662]
|
client_id
|
24 |
text string |
[RFC 7662]
|
error
|
30 |
integer |
[RFC 7662]
|
error_description
|
31 |
text string |
[RFC 7662]
|
error_uri
|
32 |
text string |
[RFC 7662]
|
token_type_hint
|
33 |
text string |
[RFC 7662]
|
token_type
|
34 |
integer |
[RFC 7662]
|
username
|
35 |
text string |
[RFC 7662]
|
ace_profile
|
38 |
integer |
RFC 9200 |
cnonce
|
39 |
byte string |
RFC 9200 |
exi |
40 |
unsigned integer |
RFC 9200 |
Table 6: CBOR Mappings for Token Introspection Parameters
In this framework, the use of CBOR Web Token (CWT) as specified in [
RFC 8392] is
RECOMMENDED.
In order to facilitate offline processing of access tokens, this document uses the
cnf claim from [
RFC 8747] and the
scope claim from [
RFC 8693] for JWT- and CWT-encoded tokens. In addition to string encoding specified for the
scope claim, a binary encoding
MAY be used. The syntax of such an encoding is explicitly not specified here and left to profiles or applications, specifically note that a binary encoded scope does not necessarily use the space character '0x20' to delimit scope-tokens.
If the AS needs to convey a hint to the RS about which profile it should use to communicate with the client, the AS
MAY include an
ace_profile claim in the access token, with the same syntax and semantics as defined in
Section 5.8.4.3.
If the client submitted a
cnonce parameter in the access token request (
Section 5.8.4.4), the AS
MUST include the value of this parameter in the
cnonce claim specified here. The
cnonce claim uses binary encoding.
The access token, containing authorization information and information about the proof-of-possession method used by the client, needs to be transported to the RS so that the RS can authenticate and authorize the client request.
This section defines a method for transporting the access token to the RS using a RESTful protocol, such as CoAP. Profiles of this framework
MAY define other methods for token transport.
The method consists of an authz-info endpoint, implemented by the RS. A client using this method
MUST make a POST request to the authz-info endpoint at the RS with the access token in the payload. The CoAP Content-Format or HTTP media type
MUST reflect the format of the token, e.g., "application/cwt", for CBOR Web Tokens; if no Content-Format or media type is defined for the token format, "application/octet-stream"
MUST be used.
The RS receiving the token
MUST verify the validity of the token. If the token is valid, the RS
MUST respond to the POST request with a response code equivalent to CoAP code 2.01 (Created).
Section 5.10.1.1 outlines how an RS
MUST proceed to verify the validity of an access token.
The RS
MUST be prepared to store at least one access token for future use. This is a difference as to how access tokens are handled in OAuth 2.0, where the access token is typically sent along with each request and therefore not stored at the RS.
When using this framework, it is
RECOMMENDED that an RS stores only one token per proof-of-possession key. This means that an additional token linked to the same key will supersede any existing token at the RS by replacing the corresponding authorization information. The reason is that this greatly simplifies (constrained) implementations, with respect to required storage and resolving a request to the applicable token. The use of multiple access tokens for a single client increases the strain on the resource server, as it must consider every access token and calculate the actual permissions of the client. Also, tokens may contradict each other, which may lead the server to enforce wrong permissions. If one of the access tokens expires earlier than others, the resulting permissions may offer insufficient protection.
If the payload sent to the authz-info endpoint does not parse to a token, the RS
MUST respond with a response code equivalent to the CoAP code 4.00 (Bad Request).
The RS
MAY make an introspection request to validate the token before responding to the POST request to the authz-info endpoint, e.g., if the token is an opaque reference. Some transport protocols may provide a way to indicate that the RS is busy and the client should retry after an interval; this type of status update would be appropriate while the RS is waiting for an introspection response.
Profiles
MUST specify whether the authz-info endpoint is protected, including whether error responses from this endpoint are protected. Note that since the token contains information that allows the client and the RS to establish a security context in the first place, mutual authentication may not be possible at this point.
The default name of this endpoint in a url-path is '/authz-info'; however, implementations are not required to use this name and can define their own instead.
When an RS receives an access token, it
MUST verify it before storing it. The details of token verification depends on various aspects, including the token encoding, the type of token, the security protection applied to the token, and the claims. The token encoding matters since the security protection differs between the token encodings. For example, a CWT token uses COSE, while a JWT token uses JSON Object Signing and Encryption (JOSE). The type of token also has an influence on the verification procedure since tokens may be self-contained, whereby token verification may happen locally at the RS, while a reference token requires further interaction with the authorization server, for example, using token introspection, to obtain the claims associated with the token reference. Self-contained tokens
MUST at least be integrity protected, but they
MAY also be encrypted.
For self-contained tokens, the RS
MUST process the security protection of the token first, as specified by the respective token format. For CWT, the description can be found in [
RFC 8392]; for JWT, the relevant specification is [
RFC 7519]. This
MUST include a verification that security protection (and thus the token) was generated by an AS that has the right to issue access tokens for this RS.
In case the token is communicated by reference, the RS needs to obtain the claims first. When the RS uses token introspection, the relevant specification is [
RFC 7662] with CoAP transport specified in
Section 5.9.
Errors may happen during this initial processing stage:
-
If the verification of the security wrapper fails, or the token was issued by an AS that does not have the right to issue tokens for the receiving RS, the RS MUST discard the token and, if this was an interaction with authz-info, return an error message with a response code equivalent to the CoAP code 4.01 (Unauthorized).
-
If the claims cannot be obtained, the RS MUST discard the token and, in case of an interaction via the authz-info endpoint, return an error message with a response code equivalent to the CoAP code 4.00 (Bad Request).
Next, the RS
MUST verify claims, if present, contained in the access token. Errors are returned when claim checks fail, in the order of priority of this list:
-
iss
-
The iss claim (if present) must identify the AS that has produced the security protection for the access token. If that is not the case, the RS MUST discard the token. If this was an interaction with authz-info, the RS MUST also respond with a response code equivalent to the CoAP code 4.01 (Unauthorized).
-
exp
-
The expiration date must be in the future. If that is not the case, the RS MUST discard the token. If this was an interaction with authz-info, the RS MUST also respond with a response code equivalent to the CoAP code 4.01 (Unauthorized). Note that the RS has to terminate access rights to the protected resources at the time when the tokens expire.
-
aud
-
The aud claim must refer to an audience that the RS identifies with. If that is not the case, the RS MUST discard the token. If this was an interaction with authz-info, the RS MUST also respond with a response code equivalent to the CoAP code 4.03 (Forbidden).
-
scope
-
The RS must recognize value of the scope claim. If that is not the case, the RS MUST discard the token. If this was an interaction with authz-info, the RS MUST also respond with a response code equivalent to the CoAP code 4.00 (Bad Request). The RS MAY provide additional information in the error response to clarify what went wrong.
Additional processing may be needed for other claims in a way specific to a profile or the underlying application.
Note that the
sub (Subject) claim cannot always be verified when the token is submitted to the RS since the client may not have authenticated yet. Also note that a counter for the
exi (expires in) claim
MUST be initialized when the RS first verifies this token.
Also note that profiles of this framework may define access token transport mechanisms that do not allow for error responses. Therefore, the error messages specified here only apply if the token was sent to the authz-info endpoint.
When sending error responses, the RS
MAY use the error codes from
Section 3.1 of
RFC 6750 to provide additional details to the client.
As this framework can be used in RESTful environments, it is important to make sure that attackers cannot perform unauthorized requests on the authz-info endpoints, other than submitting access tokens.
Specifically, it
SHOULD NOT be possible to perform GET, DELETE, or PUT on the authz-info endpoint.
The RS
SHOULD implement rate-limiting measures to mitigate attacks aiming to overload the processing capacity of the RS by repeatedly submitting tokens. For CoAP-based communication, the RS could use the mechanisms from [
RFC 8516] to indicate that it is overloaded.
Before sending a request to an RS, the client
MUST verify that the keys used to protect this communication are still valid. See
Section 5.10.4 for details on how the client determines the validity of the keys used.
If an RS receives a request from a client and the target resource requires authorization, the RS
MUST first verify that it has an access token that authorizes this request and that the client has performed the proof-of-possession binding for that token to the request.
The response code
MUST be 4.01 (Unauthorized) in case the client has not performed the proof of possession or if the RS has no valid access token for the client. If the RS has an access token for the client but the token does not authorize access for the resource that was requested, the RS
MUST reject the request with a 4.03 (Forbidden). If the RS has an access token for the client but it does not cover the action that was requested on the resource, the RS
MUST reject the request with a 4.05 (Method Not Allowed).
Note: The use of the response codes 4.03 and 4.05 is intended to prevent infinite loops where a client optimistically tries to access a requested resource with any access token received from AS. As malicious clients could pretend to be the C to determine the C's privileges, these detailed response codes must be used only when a certain level of security is already available, which can be achieved only when the client is authenticated.
Note: The RS
MAY use introspection for timely validation of an access token at the time when a request is presented.
Note: Matching the claims of the access token (e.g.,
scope) to a specific request is application specific.
If the request matches a valid token and the client has performed the proof of possession for that token, the RS continues to process the request as specified by the underlying application.
Depending on the capabilities of the RS, there are various ways in which it can verify the expiration of a received access token. The following is a list of the possibilities including what functionality they require of the RS.
-
The token is a CWT and includes an exp claim and possibly the nbf claim. The RS verifies these by comparing them to values from its internal clock, as defined in [RFC 7519]. In this case, the RS's internal clock must reflect the current date and time or at least be synchronized with the AS's clock. How this clock synchronization would be performed is out of scope for this specification.
-
The RS verifies the validity of the token by performing an introspection request, as specified in Section 5.9. This requires the RS to have a reliable network connection to the AS and to be able to handle two secure sessions in parallel (C to RS and RS to AS).
-
In order to support token expiration for devices that have no reliable way of synchronizing their internal clocks, this specification defines the following approach: The claim exi (expires in) can be used to provide the RS with the lifetime of the token in seconds from the time the RS first receives the token. This mechanism only works for self-contained tokens, i.e., CWTs and JWTs. For CWTs, this parameter is encoded as an unsigned integer, while JWTs encode this as JSON number.
-
Processing this claim requires that the RS does the following:
-
For each token the RS receives that contains an exi claim, keep track of the time it received that token and revisit that list regularly to expunge expired tokens.
-
Keep track of the identifiers of tokens containing the exi claim that have expired (in order to avoid accepting them again). In order to avoid an unbounded memory usage growth, this MUST be implemented in the following way when the exi claim is used:
-
When creating the token, the AS MUST add a cti claim (or jti for JWTs) to the access token. The value of this claim MUST be created as the binary representation of the concatenation of the identifier of the RS with a sequence number counting the tokens containing an exi claim, issued by this AS for the RS.
-
The RS MUST store the highest sequence number of an expired token containing the exi claim that it has seen and treat tokens with lower sequence numbers as expired. Note that this could lead to discarding valid tokens with lower sequence numbers if the AS where to issue tokens of different validity time for the same RS. The assumption is that typically tokens in such a scenario would all have the same validity time.
If a token that authorizes a long-running request, such as a CoAP Observe [
RFC 7641], expires, the RS
MUST send an error response with the response code equivalent to the CoAP code 4.01 (Unauthorized) to the client and then terminate processing the long-running request.
The AS provides the client with key material that the RS uses. This can either be a common symmetric PoP key or an asymmetric key used by the RS to authenticate towards the client. Since there is currently no expiration metadata associated to those keys, the client has no way of knowing if these keys are still valid. This may lead to situations where the client sends requests containing sensitive information to the RS using a key that is expired and possibly in the hands of an attacker or where the client accepts responses from the RS that are not properly protected and could possibly have been forged by an attacker.
In order to prevent this, the client must assume that those keys are only valid as long as the related access token is. Since the access token is opaque to the client, one of the following methods
MUST be used to inform the client about the validity of an access token:
-
The client knows a default validity time for all tokens it is using (i.e., how long a token is valid after being issued). This information could be provisioned to the client when it is registered at the AS or published by the AS in a way that the client can query.
-
The AS informs the client about the token validity using the expires_in parameter in the Access Information.
A client that is not able to obtain information about the expiration of a token
MUST NOT use this token.