Skip to content

Add guidance on RAS-specific and private claims in the ID-JAG#108

Open
mcguinness wants to merge 1 commit into
mainfrom
private_claims
Open

Add guidance on RAS-specific and private claims in the ID-JAG#108
mcguinness wants to merge 1 commit into
mainfrom
private_claims

Conversation

@mcguinness

Copy link
Copy Markdown
Collaborator

Closes #107.

Summary

Addresses @meghnadubey's request in #107 for explicit spec text and an example covering custom/private claims an IdP Authorization Server can include in the ID-JAG to convey Resource Authorization Server-specific context (for example RBAC roles, tenant context, or other audience-scoped authorization information) that is not part of an ID Token released to a Client during SSO.

What changed

Three additions to the ID-JAG Claims section, placed after the existing "may contain additional claims valid for an ID Token" paragraph and before the email/aud_sub recommendation:

  1. RAS-specific claims paragraph. Makes it explicit that the IdP Authorization Server MAY include claims that are specific to the Resource Authorization Server identified by aud and that would not appear in an ID Token released to a Client during SSO. Names the categories: audience-scoped authorization context (roles or entitlements at the target application), Resource Authorization Server-specific identifiers, and other claims agreed out-of-band between the IdP and the RAS. Ties the addition to the design that SSO claim release and ID-JAG claim release can differ.

  2. Claim naming guidance paragraph. Adopts the OpenID Connect Core 1.0 Additional Claims naming guidance for ID-JAG, referencing Section 4.2 of RFC 7519: collision-resistant names RECOMMENDED, Private Claim Names acceptable when the IdP and RAS have an out-of-band agreement and naming conflicts are unlikely, and Registered Claim Names appropriate for claims with broad and general applicability.

  3. Non-normative example payload. A single JSON example showing all three naming conventions in one ID-JAG:

    • https://acme.idp.example/claims/employee_id — collision-resistant Claim Name using a URI under the IdP's namespace.
    • authorization_details (RFC 9396) — Registered Claim Name carrying a RAS-specific RAR type (acme-chat-roles) with role values.
    • chat_workspace_id — Private Claim Name shared between the IdP and this specific RAS by out-of-band agreement.

A short prose explanation follows the example, mapping each Claim Name back to its naming convention.

How this responds to #107

@meghnadubey asked for "text in the spec and an example for custom_claim... allowing for an optional custom claim in id-jag JWT [to] go a long way to address this gap" for conveying RAS-specific context beyond aud_tenant.

The PR responds by:

  • Explicitly permitting RAS-specific custom claims in the spec (the first new paragraph).
  • Providing the naming conventions an IdP should use when defining such claims (the second new paragraph).
  • Demonstrating a concrete example with multiple custom-claim shapes side by side (the non-normative example).

The flexible (key, value) and (format_specifier, key, value) patterns the issue requested are accommodated by the three naming conventions plus the existing authorization_details (RFC 9396) carrier, which already supports structured type-discriminated objects. No new claim or registry is required.

Test plan

  • Render with kramdown-rfc / xml2rfc and confirm the new paragraphs and JSON example render correctly
  • Confirm cross-references ({{Section 4.2 of RFC7519}}, {{IANA.jwt}}, {{RFC9396}}, {{OpenID.Core}}, {{OpenID.Enterprise}}) all resolve
  • Confirm no existing anchors changed

Closes #107.

Adds two new paragraphs after the existing "may contain additional
claims valid for an ID Token" paragraph, plus a non-normative example.

The first new paragraph makes it explicit that the IdP Authorization
Server MAY include claims that are specific to the Resource
Authorization Server identified by aud and that would not appear in
an ID Token released to a Client during SSO. Examples include
audience-scoped authorization context (roles or entitlements at the
target application), Resource Authorization Server-specific
identifiers, and other claims that the IdP and the Resource
Authorization Server have agreed to convey through the ID-JAG. Ties
this to the design that SSO claim release and ID-JAG claim release
can differ.

The second new paragraph adopts the OpenID Connect Core 1.0 Additional
Claims naming guidance for ID-JAG, referencing Section 4.2 of RFC 7519:
collision-resistant names are RECOMMENDED, Private Claim Names are
acceptable when the IdP and Resource Authorization Server have an
out-of-band agreement and naming conflicts are unlikely, and Registered
Claim Names are appropriate for claims with broad and general
applicability.

Adds a non-normative example payload that illustrates all three
naming conventions in use: a URI-prefixed collision-resistant Claim
Name (employee_id), the Registered Claim Name authorization_details
(RFC 9396) carrying a Resource Authorization Server-specific RAR
type, and a Private Claim Name (chat_workspace_id) shared between
the IdP and a specific Resource Authorization Server by out-of-band
agreement.
"exp": 1311281970,
"iat": 1311280970,
"scope": "chat.read chat.history",
"https://acme.idp.example/claims/employee_id": "E-019488227",

@aaronpk aaronpk Jul 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"https://acme.idp.example/claims/employee_id": "E-019488227",
"https://acme.chat.example/claims/workspace_id": "W-019488227",

}
```

In this example, `https://acme.idp.example/claims/employee_id` is a collision-resistant Claim Name using a URI under the IdP Authorization Server's namespace, `authorization_details` ({{RFC9396}}) is a Registered Claim Name carrying Resource Authorization Server-specific authorization context, and `chat_workspace_id` is a Private Claim Name shared between this IdP Authorization Server and this Resource Authorization Server by out-of-band agreement.

@aaronpk aaronpk Jul 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this example, `https://acme.idp.example/claims/employee_id` is a collision-resistant Claim Name using a URI under the IdP Authorization Server's namespace, `authorization_details` ({{RFC9396}}) is a Registered Claim Name carrying Resource Authorization Server-specific authorization context, and `chat_workspace_id` is a Private Claim Name shared between this IdP Authorization Server and this Resource Authorization Server by out-of-band agreement.
In this example, `https://acme.chat.example/claims/workspace_id` is a collision-resistant Claim Name using a URI under the Resource Authorization Server's namespace, `authorization_details` ({{RFC9396}}) is a Registered Claim Name carrying Resource Authorization Server-specific authorization context, and `employee_id` is a Private Claim Name shared between this IdP Authorization Server and this Resource Authorization Server by out-of-band agreement.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

employee_id might not be a good fit for the switch to a RAS namespace. I'm OK with the switch as this is non-normative and not excluded the IdP from issuing the claim but a more realistic claim name would be preferred

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough. I switched them around.

@aaronpk

aaronpk commented Jul 1, 2026

Copy link
Copy Markdown
Member

Using IDP-namespaced claims will lead to a Resource AS relying on IDP-specific claims in the ID-JAG, which means the RAS will have to have IDP-specific processing which hurts interoperability.

I changed these to RAS-namespaced claims instead which would help, since that would encourage IDPs to allow custom configuration for claim names, and then an admin could configure any IDP based on what the RAS needs.

"roles": ["member", "channel_admin"]
}
],
"chat_workspace_id": "ws_8a3f2b1c"

@aaronpk aaronpk Jul 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"chat_workspace_id": "ws_8a3f2b1c"
"employee_id": "e_8a3f2b1c"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom claim

2 participants