Token introspection
The photo service has decided that its access tokens should be references, not JWTs. demo-access-token-7 is now exactly what it looks like: a random string that means nothing outside the authorization server's records. The service can revoke one and know it stops working, and nothing about your account travels inside the token.
That leaves the photo API with nothing to verify. There is no signature to check and no claim to read. To decide whether the printer may see album 42, the API has to ask the authorization server what the token stands for.
Reading the answer
For the printer's token, the authorization server answers:
HTTP/1.1 200 OK
Content-Type: application/json
{
"active": true,
"iss": "https://auth.photos.example",
"sub": "user-2048",
"aud": "https://api.photos.example",
"client_id": "photo-printer",
"scope": "photos.read",
"token_type": "Bearer",
"iat": 1790845200,
"exp": 1790845800
}
The fields carry the same meanings as the claims in a JWT access token. Only active is required. Which of the others appear is up to the authorization server.
For every token that should not be accepted, the answer is the same:
HTTP/1.1 200 OK
Content-Type: application/json
{
"active": false
}
Expired, revoked, never issued, or one this API is not allowed to ask about, which can include a token meant for another API: all of them produce "active": false, and the specification says the server should not attach a reason. That is deliberate. A caller told "revoked" rather than "never existed" learns something about the server's records. The photo API passes the same uniformity on, answering the printer with invalid_token whatever the cause.
"active": true means the token is genuine and current. It does not mean this request is allowed. The API still checks that aud names it, when the response includes an audience. A server that tailors its answers to each caller may already have answered false for a token meant elsewhere, but the API does not depend on that. It then checks the scope against the operation and the album against the subject, exactly as in Enforcing access at an API. Introspection replaces the signature and claim checks, not the authorization decision.
Some deployments need a record of the answer that can be verified later, not just one received over a protected connection. A separate standard lets the authorization server return the same information as a JWT it has signed.
Caching and freshness
An introspection call on every API request adds a network round trip to each one, and it makes the authorization server part of every request path. The API can cache answers, at a price.
A cached "active": true keeps working even if the token is revoked a moment later. The cache lifetime is exactly the window in which a revoked token still works at this API. The specification leaves the balance to each deployment, with one firm rule: an answer that includes exp must not be cached past that time. Within that limit, the photo API might keep answers for a minute when photos are being read, and introspect afresh before every deletion, so a revoked token could at most read for another minute and never delete anything. The cache is keyed by a hash of the token rather than the token itself, so a memory dump or a debugging tool does not reveal working tokens.
The harder question is what to do when the authorization server does not answer. A timeout, a server error, or a refused connection says nothing about the token. Accepting the request anyway, failing open, would let any string through during an outage, including tokens revoked minutes before. The photo API fails closed: it refuses requests it cannot verify.
The introspection standard leaves the API's answer in this case to the API. The photo API's choice is 503 Service Unavailable, which describes the refusal better than a 401. The token may be perfectly good, and telling the printer it is invalid would send the printer off to replace a token that was never the problem. Answers already in the cache can still be used until their normal expiry, but not stretched beyond it to ride out the outage.
What the response reveals
An introspection response can describe a person: an account identifier, sometimes a username, which client they connected, and what they allowed it to do. Every API that can introspect learns this about every token presented to it. The specification requires measures against disclosure to unintended parties, and the simplest measure is to send less.
The photo service tailors each answer to the caller. The photo API receives the scopes that mean something at the photo API, and nothing about your other connections. A service that wants to stop its APIs from correlating activity can go further and give each API a different subject identifier for the same person, so the identifier the sharing API sees for you has no visible connection to user-2048. A field that is never sent never needs protecting.
The API handles what it receives with matching care. The response, like the token in the request, does not belong in ordinary logs. A record that a token was active, for which client and subject, and what the API decided, answers the questions a later investigation will ask.
Introspection makes a revocation visible to an API within one cache period. The revocation itself starts elsewhere, often with the client that holds the token.