Ongoing note dump of oauth things, like I was student in highschool all over again. Some of this might make no sense, and some might be regurgitation from the specs...
Authorization Server Metadata#
An authorization server's means of advertising its configuration and supported features to clients.
Two valid forms:
- https://clerk.thekevinwang.com/.well-known/openid-configuration.
- https://clerk.thekevinwang.com/.well-known/oauth-authorization-server.
Various RFC's define additional metadata fields
grant_types_supported
ID-JAG §7 introduces even more:
- JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants defines
urn:ietf:params:oauth:grant-type:jwt-bearer, but doesn't define anything regarding metadata or advertisement.
AI Era#
How the pieces ladder up:
Token exchange:
"Give me a different token."
Identity chaining:
"Give me a token in another trust domain, while preserving the relevant identity + authorization provenance."
XAA / ID-JAG:
"Let a shared enterprise IdP authorize App A to access App B on the user's behalf, without making the user approve again at App B."
CIMD:
"Enable clients with stable public web ID's to identify them selves"
MCP & Token exchange#
A sequence diagram for OAuth powered MCP auth flow, commonly seen nowadays.
Token exchange in this scenario is one option for complying with acceess token privilege restriction, as documented in the MCP 2026-07-28 spec.
If the MCP server makes requests to upstream APIs, it may act as an OAuth client to them. The access token used at the upstream API is a separate token, issued by the upstream authorization server. The MCP server MUST NOT pass through the token it received from the MCP client.
All of this could take place with a single trust domain.
Identity Chaining#
OAuth Identity and Authorization Chaining
What problem does it solve?
describes how a request carries user identity and authorization context between two trust domains — eg. domain A & domain B.
Notes
- AS B SHOULD NOT issue refresh tokens — it's a redundant credential, requires additional security, and allows access token issuance to occur only within Domain B.
Steps 2 & 3, token exchange in Domain A
Claims transcription#
One novel flow described is claims transcription.
Transcribing the subject identifier#
Identify chaining is unopinionated about subject identifier mapping. ID-JAG brings more opinions to the flow.
-
GIVEN: client in Domain A is requesting access token in Domain B
-
WHEN: subject ID can differ in trust domain A & B, e.g "johndoe@a.example" vs. "doe.john@b.example".
-
THEN: mapping can happen in either of:
- token exchange step in domain A
- auth grant assertion — the front door to domain B
AS B MUST deny the request if it can't identify the subject.
Controlling scope
- check that requested scopes are not higher than the subject_token
Not in scope
The representation of transcribed claims and their format is not defined in the spec.
Needs mutual agreement
When transcribing claims, it's important that both the place where the claims are given and where they are interpreted agree on the semantics and that the access controls are consistent.
New AS metadata#
identity_chaining_requested_token_types_supported
- Optional
- JSON array of supported token types, requestable during token exchange (
requested_token_type) - Advertisement !== to actual support.
ID-JAG and XAA#
What does this solve?
Parties involved; Example with three independent registrations.
Main flow#
Changes:
- XAA extends the IdP's role from single sign-on to brokering cross-domain API access
- XAA built on
The ID-JAG#
Header typ MUST be oauth-id-jag+jwt. Highlighted payload claims are required.
Use case 1. Enterprise deployment#
Preconditions
- Client has a registered OAuth 2.0 Client with the IdP AS
- Client has a registered OAuth 2.0 Client with the Resource AS
- Enterprise trusts relationship between IdP and Client for SSO and ID-JAG
- Enterprise trusts relationship between IdP and Resource Authorization Server for SSO and ID-JAG.
- Enterprise grants the Client permission to act on behalf of users for the Resource AS with a set of scopes
Use case 2. Customer identity for developer SaaS components#
Use case 3. Email and calendaring applications#
Use case 4. AI agent using external tools#
Other#
Registry of parameters#
This is a super helpful all-up view of the exact parameter names from various OAuth RFCs.
https://www.iana.org/assignments/oauth-parameters
The main RFC's#
- RFC 6749: The OAuth 2.0 Authorization Framework
- RFC 9700 BCP 240: Best Current Practice for OAuth 2.0 Security
OAuth 2.1#
Most important changes:
| Change | Practical effect |
|---|---|
| Authorization code + PKCE required | PKCE is required for both public and confidential clients. Only the S256 method is supported. |
| Implicit grant removed | Use authorization code + PKCE instead of returning access tokens directly in the authorization response. |
| Password grant removed | Applications must not collect user passwords to exchange them for tokens. |
| Exact redirect URI matching | Prevents loose matching from sending authorization responses to attacker-controlled locations. |
| Stronger refresh-token protection for public clients | Refresh tokens must be sender-constrained or rotated after each use. |
| No bearer tokens in URL query strings | Reduces exposure through logs and other URL storage. |
Source: Draft §10 — Differences from OAuth 2.0.
PKCE#
Proof key for code exchange (PKCE) prevents intercepted authorization codes from being exchangeable for access tokens.
PKCE adds:
code_verifier: high-entropy, per-request secret.code_challenge: one-way derived verifier value.code_challenge_method:S256. OAuth 2.1 removesplain.- Challenge binding: authorization server stores the challenge with the authorization code.
- Proof at redemption: client sends the verifier to
POST /token. - Server validation: derive and compare; reject mismatch.
- One-time, short-lived authorization code: required container for that binding.
Device Authorization Grant#
RFC: Device Authorization Grant 8628
Requirements
- The device is already connected to the Internet.
- The device is able to make outbound HTTPS requests.
- The device is able to display or otherwise communicate a URI and code sequence to the user.
- The user has a secondary device (e.g., personal computer or smartphone) from which they can process the request.
Example from amp CLI that uses the verification_uri_complete repsonse field.
And to constrast, here's amp CLI taking the user through the usual authorization_code flow,