In OpenID Connect, what does an ID token tell a relying party that an access token never does?
answer
- two artefacts, two different readers
- who signed in, not what may be done
- the client is the addressee
- iss, sub, aud, exp, iat are REQUIRED
- consumed at login, never sent to an API
basics
~20 sAn OpenID Connect ID token is a signed statement, addressed to the client that asked, that a named user just authenticated at a named issuer. An access token authorises an API call and says nothing about who signed in.
solid answer
~50 sThe ID token is the one artefact the identity layer adds on top of delegated authorization: a signed JSON Web Token in which a provider states that a particular end user authenticated, for a particular client, at a particular moment. Its `iss`, `sub`, `aud`, `exp` and `iat` claims are REQUIRED here, and the relying party is the addressee — it validates the token, reads who signed in, establishes its own application session, and is done with it. An access token is the opposite artefact: a credential addressed to a resource server, saying what the bearer may do and carrying no promise that the user is present now. Forwarding an ID token to an API as `Authorization: Bearer` is the classic error, because the API is not named in `aud` and the ID token encodes no delegated scope at all.
code
json · 6 lines{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzcyI6..."
}go deeper
Recall that there are two different artefacts and two different readers: the ID token goes to the application that started the login, the access token goes to the API.
Explain the five required claims and what each one lets the client decide, and be able to say why an API rejecting an ID token is behaving correctly rather than being awkward.
Show that you have seen the forwarding mistake in production, can describe what the API was actually checking when it accepted one, and can state what breaks in the audit trail afterwards.
Frame it as an addressing discipline across an estate: every credential has one intended reader, and the cost of blurring that is authorisation decisions made on statements nobody addressed to the decider.
## The one artefact the identity layer adds OpenID Connect is a thin identity layer laid over a delegated-authorization framework. The redirect out to a provider and the back-channel exchange that follows belong to the framework underneath; what the identity layer adds is a single extra artefact, the **ID token**. It is a signed JSON Web Token — the container is defined by **RFC 7519** — in which an OpenID Provider states that a particular end user authenticated, at a particular issuer, for a particular client, at a particular moment. It is returned when the authentication request asked for the `openid` scope. The load-bearing word is *addressed*. Every artefact in this family is addressed to someone, and nearly every serious mistake here is an artefact being read by a party it was never addressed to. ## Who reads which artefact | Artefact | Addressed to | Answers | Validated by | |---|---|---|---| | ID token | the client (relying party) | who just signed in, at which issuer | the client, against the issuer's published key | | Access token | the resource server | what the bearer may do | the resource server | | Refresh token | the authorization server | may this client obtain a new access token | the authorization server that issued it | An access token is a **bearer credential**: whoever holds it may exercise the grant it stands for, and it carries no promise that a user is at a browser right now — only that a grant existed when it was issued. An ID token is an **assertion about an authentication event**, consumed once, at login, by the client that asked for it. ## What the ID token carries Five claims are REQUIRED in an ID token, and "required" here is a stronger statement than the container format makes about the same names: - `iss` — the issuer identifier, which must exactly match the issuer the relying party has configured for this provider; - `sub` — the provider-local identifier for the user: locally unique, never reassigned within that issuer, case-sensitive, at most 255 ASCII characters; - `aud` — the audience, which MUST contain the relying party's own `client_id`; - `exp` — the instant after which the token must not be accepted; - `iat` — when the provider issued it. Optional members sit on top of those: `nonce`, which the provider MUST include when the request carried one; `azp`; `at_hash`; and assurance claims defined elsewhere in the specification. ## What the relying party does with it 1. Validate it — the issuer match, an audience containing its own `client_id`, the signature against the issuer's published key, and the expiry. 2. Read `sub` together with `iss` as the account key, plus whatever profile claims the requested scopes unlocked. 3. Establish its own application session. 4. Stop using the ID token as a credential. Step 4 is the one candidates miss. The ID token is consumed at the door. If the application later needs to call an API on the user's behalf it presents the **access token**, in an `Authorization: Bearer` header. The one place an ID token legitimately travels again is back to the provider itself, as a request parameter defined in another part of this specification — never to an API. ## The classic failure: forwarding the ID token to an API A team wires up sign-in, finds itself holding a signed token that contains the user's identity, and sends that token to its own API as the credential. It often appears to work, because a verification routine at the API checks a signature and an expiry and is satisfied. It is wrong in two separate ways. First, the audience. The API is not in `aud`; the client is. A resource server that accepts a token naming somebody else as its audience has discarded the only check that says the token was meant for it. Second, the semantics. The ID token records that someone *authenticated*. It says nothing about which permissions were delegated, and it has no scope of delegation at all. The access token is the artefact that encodes the grant. An API authorising on an ID token is authorising on "this person signed in somewhere", which is not a permission. ## What a good answer sounds like Name which party each artefact is addressed to, say that the relying party validates the ID token and then runs its own session, and give the audience check as the reason an API must refuse one. Candidates who have only copied an integration can list the claims; candidates who understand it can say who each claim is a statement *to*.
- Which ID token claim ties it to one particular access token, and what does that let the client detect?`at_hash`. Its value is the base64url encoding of the left-most half of the hash of the access token's ASCII octets, using the hash algorithm that matches the ID token's signature algorithm. It is REQUIRED when an ID token and an access token are issued together from the authorization endpoint, and it lets the client notice that the access token beside the ID token has been swapped for another one.
- A resource server is configured to accept ID tokens as bearer credentials. What is the concrete defect?It is validating a statement that was never addressed to it: `aud` names the client, not the API. It has also lost the grant boundary, because an ID token carries no delegated scope — so "this person logged in" becomes the whole authorization decision. The fix is to accept only access tokens whose audience is the API itself.
- Does a valid signature on an ID token mean the relying party may trust its claims?No. A signature only says which key signed the bytes. The relying party must also confirm the issuer is the one it configured, that `aud` contains its own `client_id`, and that the token has not expired. Signature verification is a step in the routine, not the end of it.
A signed letter of introduction tells the person who opens it who you are; the numbered pass clipped to it opens certain doors and never says your name. Handing the letter to the door staff proves nothing to them, because it was not written to them.
saying these in an interview costs you the question
- An ID token is just an access token that also carries the user's name.
- Send the ID token to the API; it is signed, so it is safe.
- A valid signature means the ID token was issued for you.
- An access token tells the API which user is signed in right now.
- The ID token replaces the application's own session.