Skip to content

Commit 9e62afb

Browse files
committed
added RAR support and updated processing rules for Token Exchange and ID-JAG
1 parent 3bce7fe commit 9e62afb

File tree

1 file changed

+155
-5
lines changed

1 file changed

+155
-5
lines changed

draft-ietf-oauth-identity-assertion-authz-grant.md

Lines changed: 155 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ normative:
4747
RFC8693:
4848
RFC8707:
4949
RFC8725:
50+
RFC9396:
5051
I-D.ietf-oauth-identity-chaining:
52+
I-D.ietf-oauth-rfc7523bis:
5153
IANA.media-types:
5254
IANA.oauth-parameters:
5355
IANA.jwt:
@@ -121,7 +123,7 @@ Resource Server (RS)
121123

122124
# Identity Assertion JWT Authorization Grant {#id-jag}
123125

124-
The Identity Assertion JWT Authorization Grant (ID-JAG) is a profile of the JWT Authorization Grant {{RFC7523}} that grants a client delegated access to a resource in another trust domain on behalf of a user without a direct user-approval step at the authorization server.
126+
The Identity Assertion JWT Authorization Grant (ID-JAG) is a profile of the JWT Authorization Grant {{RFC7523}} that grants a client delegated access to a resource in another trust domain on behalf of a user without a direct user-approval step at the authorization server. This specification supports Rich Authorization Requests (RAR) {{RFC9396}}, allowing clients to request authorization using structured authorization details in addition to traditional scope-based authorization.
125127

126128
An ID-JAG is issued and signed by an IdP Authorization Server similar to an ID Token {{OpenID.Core}}, and contains claims about an End-User. Instead of being issued for a client (Relying Party in {{OpenID.Core}}) as the intended audience for the assertion, it is instead issued with an audience of an Authorization Server in another trust domain (Resource Authorization Server). It replaces the need for the client to obtain an authorization code from the Resource Authorization Server to delegate access to the client, and instead uses the IdP Authorization Server which is trusted by the Resource Authorization Server to delegate access to the client.
127129

@@ -156,6 +158,9 @@ The following claims are used within the Identity Assertion JWT Authorization Gr
156158
`scope`:
157159
: OPTIONAL - a JSON string containing a space-separated list of scopes associated with the token, in the format described in {{Section 3.3 of RFC6749}}.
158160

161+
`authorization_details`:
162+
: OPTIONAL - A JSON array of authorization detail objects as defined in {{Section 2 of RFC9396}}. This claim enables Rich Authorization Requests (RAR) support, allowing structured authorization requests beyond simple scope strings.
163+
159164
`tenant`:
160165
: OPTIONAL - JSON string that represents the tenant identifier for a multi-tenant issuer as defined in {{OpenID.Enterprise}}
161166

@@ -316,6 +321,9 @@ The Client makes a Token Exchange {{RFC8693}} request to the IdP Authorization S
316321
`scope`:
317322
: OPTIONAL - The space-separated list of scopes at the Resource Server that is being requested.
318323

324+
`authorization_details`:
325+
: OPTIONAL - A JSON string containing a JSON array of authorization detail objects as defined in {{Section 2 of RFC9396}}. This parameter enables Rich Authorization Requests (RAR) support, allowing structured authorization requests beyond simple scope strings.
326+
319327
`subject_token`:
320328
: REQUIRED - The Identity Assertion (e.g. the OpenID Connect ID Token or SAML 2.0 Assertion) for the target resource owner.
321329

@@ -346,7 +354,21 @@ The example below uses an ID Token as the Identity Assertion, and uses a JWT Bea
346354

347355
The IdP MUST validate the subject token, and MUST validate that the audience of the Subject Token (e.g. the `aud` claim of the ID Token) matches the `client_id` of the client authentication of the request.
348356

349-
The IdP evaluates administrator-defined policy for the token exchange request and determines if the client should be granted access to act on behalf of the subject for the target audience and scopes.
357+
The IdP evaluates administrator-defined policy for the token exchange request and determines if the client should be granted access to act on behalf of the subject for the target audience, resources, scopes, and authorization details.
358+
359+
When processing the request:
360+
361+
* If `resource` is present, the IdP MUST process it according to {{Section 2 of RFC8707}} and evaluate policy to determine the granted resources. The granted resources MAY be a subset of the requested resources based on policy.
362+
363+
* If `scope` is present, the IdP MUST process it according to {{Section 3.3 of RFC6749}} and evaluate policy to determine the granted scopes. The granted scopes MAY be a subset of the requested scopes based on policy.
364+
365+
* If `authorization_details` is present, the IdP MUST parse it as a JSON array and process each authorization detail object according to {{RFC9396}}. The IdP evaluates policy for each authorization detail and determines which authorization details to include in the issued ID-JAG. The IdP MAY modify, filter, or omit authorization details based on policy.
366+
367+
* If both `resource` and `authorization_details` are present, the IdP MUST process both. The IdP SHOULD ensure consistency between the resource identifiers and authorization details, as they may represent overlapping authorization requests. The IdP MAY derive resource identifiers from authorization details or vice versa, or process them independently based on policy.
368+
369+
* If both `scope` and `authorization_details` are present, the IdP MUST process both. The IdP SHOULD ensure consistency between the scopes and authorization details, as they may represent overlapping authorization requests. The IdP MAY derive scopes from authorization details or vice versa, or process them independently based on policy.
370+
371+
* The IdP MUST include the granted `resource` (if any), `scope` (if any), and `authorization_details` (if any) in the issued ID-JAG. If the IdP modifies the requested resources, scopes, or authorization details, it MUST reflect the granted values in the ID-JAG.
350372

351373
The IdP may also introspect the authentication context described in the SSO assertion to determine if step-up authentication is required.
352374

@@ -379,6 +401,9 @@ If access is granted, the IdP creates a signed Identity Assertion JWT Authorizat
379401
`scope`:
380402
: OPTIONAL if the scope of the issued token is identical to the scope requested by the client; otherwise, it is REQUIRED. Various policies in the IdP may result in different scopes being issued from the scopes the application requested.
381403

404+
`authorization_details`:
405+
: OPTIONAL - A JSON array of authorization detail objects as defined in {{Section 2.2 of RFC9396}}. This parameter MUST be included if the client requested authorization details and the IdP granted authorization details that differ from what was requested, or if the IdP modified the authorization details. If the authorization details in the issued ID-JAG are identical to what was requested, this parameter MAY be omitted.
406+
382407
`expires_in`:
383408
: RECOMMENDED - The lifetime in seconds of the authorization grant.
384409

@@ -414,6 +439,116 @@ The following is a non-normative example of the issued token
414439
.
415440
signature
416441

442+
#### Example with Rich Authorization Requests (RAR)
443+
444+
The following is a non-normative example demonstrating the use of Rich Authorization Requests (RAR) {{RFC9396}} with ID-JAG:
445+
446+
Token Exchange Request with authorization_details:
447+
448+
POST /oauth2/token HTTP/1.1
449+
Host: acme.idp.example
450+
Content-Type: application/x-www-form-urlencoded
451+
452+
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
453+
&requested_token_type=urn:ietf:params:oauth:token-type:id-jag
454+
&audience=https://acme.chat.example/
455+
&authorization_details=[{"type":"chat_read","actions":["read"],"locations":["https://api.chat.example/channels"]},{"type":"chat_history","actions":["read"],"datatypes":["message"]}]
456+
&subject_token=eyJraWQiOiJzMTZ0cVNtODhwREo4VGZCXzdrSEtQ...
457+
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
458+
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
459+
&client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0...
460+
461+
Token Exchange Response:
462+
463+
HTTP/1.1 200 OK
464+
Content-Type: application/json
465+
Cache-Control: no-store
466+
Pragma: no-cache
467+
468+
{
469+
"issued_token_type": "urn:ietf:params:oauth:token-type:id-jag",
470+
"access_token": "eyJhbGciOiJIUzI1NiIsI...",
471+
"token_type": "N_A",
472+
"authorization_details": [
473+
{
474+
"type": "chat_read",
475+
"actions": ["read"],
476+
"locations": ["https://api.chat.example/channels"]
477+
},
478+
{
479+
"type": "chat_history",
480+
"actions": ["read"],
481+
"datatypes": ["message"]
482+
}
483+
],
484+
"expires_in": 300
485+
}
486+
487+
Issued Identity Assertion JWT Authorization Grant with authorization_details:
488+
489+
{
490+
"typ": "oauth-id-jag+jwt"
491+
}
492+
.
493+
{
494+
"jti": "9e43f81b64a33f20116179",
495+
"iss": "https://acme.idp.example/",
496+
"sub": "U019488227",
497+
"aud": "https://acme.chat.example/",
498+
"client_id": "f53f191f9311af35",
499+
"exp": 1311281970,
500+
"iat": 1311280970,
501+
"authorization_details": [
502+
{
503+
"type": "chat_read",
504+
"actions": ["read"],
505+
"locations": ["https://api.chat.example/channels"]
506+
},
507+
{
508+
"type": "chat_history",
509+
"actions": ["read"],
510+
"datatypes": ["message"]
511+
}
512+
],
513+
"auth_time": 1311280970
514+
}
515+
.
516+
signature
517+
518+
Access Token Request:
519+
520+
POST /oauth2/token HTTP/1.1
521+
Host: acme.chat.example
522+
Authorization: Basic yZS1yYW5kb20tc2VjcmV0v3JOkF0XG5Qx2
523+
524+
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
525+
&assertion=eyJhbGciOiJIUzI1NiIsI...
526+
527+
Access Token Response:
528+
529+
HTTP/1.1 200 OK
530+
Content-Type: application/json;charset=UTF-8
531+
Cache-Control: no-store
532+
Pragma: no-cache
533+
534+
{
535+
"token_type": "Bearer",
536+
"access_token": "2YotnFZFEjr1zCsicMWpAA",
537+
"expires_in": 86400,
538+
"authorization_details": [
539+
{
540+
"type": "chat_read",
541+
"actions": ["read"],
542+
"locations": ["https://api.chat.example/channels"]
543+
},
544+
{
545+
"type": "chat_history",
546+
"actions": ["read"],
547+
"datatypes": ["message"]
548+
}
549+
]
550+
}
551+
417552
#### Error Response
418553

419554
On an error condition, the IdP returns an OAuth 2.0 Token Error response as defined in {{Section 5.2 of RFC6749}}, e.g:
@@ -455,9 +590,24 @@ For example:
455590
All of {{Section 5.2 of RFC7521}} applies, in addition to the following processing rules:
456591

457592
* Validate the JWT `typ` is `oauth-id-jag+jwt` (per {{Section 3.11 of RFC8725}})
458-
* The `aud` claim MUST identify the Issuer URL of the Resource Authorization Server as the intended audience of the JWT.
459-
* The `client_id` claim MUST identify the same client as the client authentication in the request.
460-
* The Resource Authorization Server MUST follow {{Section 3.3 of RFC6749}} when processing the `scope` claim.
593+
594+
* The Resource Authorization Server MUST validate the `aud` (audience) claim of the ID-JAG. The `aud` claim MUST contain the issuer identifier of the Resource Authorization Server as defined in {{RFC8414}}. The `aud` claim MAY be a string containing a single issuer identifier, or an array containing a single issuer identifier. If the `aud` claim is an array, it MUST contain exactly one element, and that element MUST be the issuer identifier of the Resource Authorization Server. If the `aud` claim does not match the Resource Authorization Server's issuer identifier, the Resource Authorization Server MUST reject the JWT with an `invalid_grant` error as defined in {{Section 5.2 of RFC6749}}. This validation prevents audience injection attacks and ensures the ID-JAG was intended for this specific Resource Authorization Server.
595+
596+
* The `client_id` claim MUST identify the same client as the client authentication in the request. The Resource Authorization Server MUST validate that the `client_id` claim in the ID-JAG matches the authenticated client making the request. If they do not match, the Resource Authorization Server MUST reject the request with an `invalid_grant` error.
597+
598+
When processing authorization information from the ID-JAG:
599+
600+
* If the `resource` claim is present, the Resource Authorization Server MUST process it according to {{Section 2 of RFC8707}}. The Resource Authorization Server evaluates the resource identifiers and determines which resources to grant access to based on policy. The granted resources MAY be a subset of the resources in the ID-JAG issued by the IdP Authorization Server.
601+
602+
* If the `scope` claim is present, the Resource Authorization Server MUST process it according to {{Section 3.3 of RFC6749}}. The Resource Authorization Server evaluates the scopes and determines which scopes to grant in the access token based on policy. The granted scopes MAY be a subset of the scopes in the ID-JAG issued by the IdP Authorization Server.
603+
604+
* If the `authorization_details` claim is present, the Resource Authorization Server MUST parse it as a JSON array and process each authorization detail object according to {{RFC9396}}. The Resource Authorization Server evaluates policy for each authorization detail and determines which authorization details to grant. The Resource Authorization Server MAY modify, filter, or omit authorization details based on policy.
605+
606+
* If both `resource` and `authorization_details` claims are present, the Resource Authorization Server MUST process both. The Resource Authorization Server SHOULD ensure consistency between the resource identifiers and authorization details when issuing the access token. The Resource Authorization Server MAY derive resource identifiers from authorization details or vice versa, or process them independently based on policy.
607+
608+
* If both `scope` and `authorization_details` claims are present, the Resource Authorization Server MUST process both. The Resource Authorization Server SHOULD ensure consistency between the scopes and authorization details when issuing the access token. The Resource Authorization Server MAY derive scopes from authorization details or vice versa, or process them independently based on policy.
609+
610+
* The Resource Authorization Server MUST include the granted `resource` (if any), `scope` (if any), and `authorization_details` (if any) in the access token response. The response format follows {{Section 2 of RFC8707}} for resource, {{Section 5.1 of RFC6749}} for scope, and {{Section 2.2 of RFC9396}} for authorization_details.
461611

462612
### Response
463613

0 commit comments

Comments
 (0)