Skip to main content
Agent Identity

OIDF · Final 2014; errata set 2 current

OpenID Connect Core 1.0 incorporating errata set 2

OpenID.Core

N. Sakimura, J. Bradley, M. Jones, B. de Medeiros, C. Mortimore

OIDF FinalStableIdentityFoundationField guide

OpenID Connect Core 1.0 incorporating errata set 2 (OpenID.Core) is OIDF Final, Final 2014; errata set 2 current. User-delegated agents still need to know which human they serve. OIDC remains the way that human authenticates to the authorization server. XAA even starts from an ID Token as the subject_token.

At a glance

Problem
OAuth 2.0 does not tell the client who authenticated. OpenID Connect adds an ID Token and a UserInfo endpoint so a relying party can obtain an authenticated end-user identity.
Identity / authn / authz
Identity and authentication of the user. Authorization of API access remains OAuth. Mixing them up is the most common design error in agent stacks.

Actors

  • End-user
  • Relying party (client)
  • OpenID provider (authorization server + identity)

How OpenID Connect Core works

Animated sequence · OIDC

OpenID Connect — Which token says who signed in, and which one is the API pass?

Nametag stays home; pass goes to the API

OpenID Connect is the identity layer on OAuth. The client sends a nonce, redeems a code, and the token endpoint can return two tickets. The ID Token authenticates the user to the client (aud = client_id). The access token is the pass for a resource. They are not interchangeable. UserInfo is optional.

Usersends
OpenID provider
RP (client)gets
API / MCP server

Now · 1/14· Discover· OIDC CoreYou are here

User→RP (client)·Asks the relying party to sign in (and maybe later call an API)

The user wants the RP to know who signed in. If an API call is needed later, that will use an access token — not the ID Token.

Why The relying party (RP) is the OAuth client. The OpenID provider (OP) is the AS plus identity. The user is not the API.

Ask the front desk for a nametag. A pass for a back room is a different paper.

  • relying party from the spec
  • OpenID provider from the spec
  • end-user from the spec

Solid = from the spec

Step 1 of 14: user to agent. Asks the relying party to sign in (and maybe later call an API) OIDC Core
Speed
ShareLinkedInX

OpenID Connect is the identity layer on OAuth. An ID Token authenticates the user to the client. It is not an access token. nonce is required for this authentication request.

In one board · OIDC vs OAuth

Nametag stays home; pass goes to the API

Two tickets come back from the token endpoint. They look related. They are not interchangeable. Sending the ID Token to an MCP server is the classic mix-up.

  • User

    Authenticates →

    OpenID provider
  • OP

    ID Token — aud is the client →

    Agent (relying party)
  • Agent

    Access token — aud is this API →

    API / MCP server

Nametag

ID Token

Stays with the agent. aud is the client_id. Answers who signed in — not what the API may do.

Pass

access token

Goes to the resource. Glue it to a key with DPoP if the runtime is untrusted. Still a photocopy until you do.

OpenID Connect is the identity layer on OAuth. An ID Token is not an access token. Side-by-side.

Hop list

Sequence above; this list is the same hops for reading and search. Each row is one message.

  1. 1

    User→RP (client)OIDC CoreAsks the relying party to sign in (and maybe later call an API)

  2. 2

    RP (client)→OpenID providerOIDC DiscoveryGET OpenID Provider configuration

  3. 3

    RP (client)→RP (client)OIDC CoreGenerates PKCE verifier+challenge and a fresh nonce

  4. 4

    RP (client)→OpenID providerOIDC CoreRedirects to the authorization endpoint: scope=openid, nonce, response_type=code, code_challenge

  5. 5

    User→OpenID providerOIDC CoreAuthenticates at the OpenID provider

  6. 6

    User→OpenID providerOIDC CoreConsents to this RP (and to any API scopes)

  7. 7

    OpenID provider→RP (client)OAuth 2.1Redirects back with an authorization code — not the ID Token, not the access token

  8. 8

    RP (client)→OpenID providerRFC 7636POSTs the token endpoint: code + code_verifier

  9. 9

    OpenID provider→RP (client)OIDC CoreIssues an ID Token — aud is the client_id. This nametag stays with the RP

  10. 10

    OpenID provider→RP (client)OAuth 2.1Issues an access token — a different ticket, for a resource

  11. 11

    RP (client)→RP (client)OIDC CoreValidates the ID Token: iss, aud=client_id, nonce, signature, exp

  12. 12

    RP (client)→OpenID providerOIDC CoreOptional UserInfo request with the access token — not with the ID Token as Bearer

  13. 13

    RP (client)→API / MCP serverRFC 6750Calls the API with the access token (aud = this API). The ID Token stays home

  14. 14

    RP (client)→API / MCP serverOIDC CoreSending the ID Token to the API is the mix-up — wrong audience, wrong token type

01

The gap for agents

OAuth 2.0 does not tell the client who authenticated. OpenID Connect adds an ID Token and a UserInfo endpoint so a relying party can obtain an authenticated end-user identity. User-delegated agents still need to know which human they serve; OIDC remains the way that human authenticates to the authorization server.

Mixing the layers is the most common design error in agent stacks: sending the ID Token to an MCP server, treating sub as a SPIFFE ID, or assuming OIDC authorized a specific tool call. XAA even starts from an ID Token as the subject_token — at the IdP, not at the API.

02

Actors and trust boundaries

The end-user authenticates to the OpenID provider (OP). The relying party (the agent host / client) consumes the ID Token; aud is the client_id. The OP is also an OAuth AS. Resource servers are not OIDC relying parties and must not accept ID Tokens as access tokens.

03

Mechanics

Authorization Code flow (with PKCE in modern deployments) adding scope=openid. Token endpoint returns an ID Token (JWT) plus an access token (and optional refresh token). RP validates iss, aud (the client_id), exp, iat, nonce, signature; optional azp, at_hash, c_hash. UserInfo endpoint, authorized by the access token with openid scope, returns additional claims. Implicit and hybrid exist in the 2014 spec; do not use them for new agents.

OpenID Connect Core 1.0 incorporating errata set 2. Authors: N. Sakimura, J. Bradley, M. Jones, B. de Medeiros, C. Mortimore. Final 2014 with ongoing errata.

id_tokenfrom spec
Quoted: JWT authenticating the user to the client. aud is the client, not the API.
subfrom spec
Quoted: stable subject identifier at that issuer. Pair with iss. Pairwise subs are allowed.
nonce / at_hash / c_hashfrom spec
Quoted: replay and token-binding checks between ID Token and the code/access token.
scope=openidfrom spec
Quoted: the switch that makes an OAuth request an OIDC request.

04

Step-by-step flows

Flow 1

Authorization code + ID Token

  1. 1

    RP redirects with scope=openid (plus others), nonce, PKCE, resource if also requesting API access.

  2. 2

    User authenticates at the OP. Consent covers identity and any API scopes.

  3. 3

    Token endpoint returns id_token + access_token. RP validates the ID Token locally.

  4. 4

    RP keeps the ID Token. It uses the access token (audience-restricted) at APIs. Optional UserInfo call.

If a design says 'the agent sends the ID Token to the MCP server', that design is wrong.

05

Identity vs authentication vs authorization

Identity and authentication of the user. Authorization of API access remains OAuth (the access token). Client authentication is still OAuth client auth. AAuth reuses OIDC claim names so identity-aware resources can keep their user model without becoming OIDC RPs.

06

How it composes

  • OAuth 2.0

    OIDC is an identity layer on OAuth 2.0.

  • OAuth 2.1

    Same relationship; use 2.1-shaped code+PKCE to obtain the ID Token.

  • OIDC Discovery

    How the RP finds the OP.

  • Cross-App Access (ID-JAG)

    ID Token (or refresh) is the subject_token for minting an ID-JAG.

  • AAuth

    Reuses sub/email/groups/roles; does not issue ID Tokens.

  • CIBA

    Decoupled OIDC authentication/consent when the user is on another device.

07

What bites agent implementers

  • ID Token as access token

    aud is the client. An API that accepts it is trusting the wrong audience. MCP wants an access token minted for the MCP server.

  • Skipping nonce

    Replay of an ID Token into a different agent session. Always send and check nonce on interactive flows.

  • Pairwise sub surprise

    The same human may have different sub values at different RPs. Do not use sub as a global person identifier across OPs either — always (iss, sub).

08

Stability — what you can ship

OIDF Final, 2014, errata set 2 current. Stable. Implement with RFC 9700/OAuth 2.1 practices (PKCE, no implicit). https://openid.net/specs/openid-connect-core-1_0.html

Catalog claims (short form)

id_token
JWT authenticating the user to the client. aud is the client, not the API.
sub
Stable subject identifier at that issuer. Pair with iss.
nonce / at_hash / c_hash
Replay and token-binding checks.

Implementer notes

An ID Token is not an access token. Do not send it to APIs. AAuth reuses OIDC claim names (sub, email, groups) so identity-aware resources can keep their existing user model.

Related

Primary sources

  • OIDC Corehttps://openid.net/specs/openid-connect-core-1_0.html