Retrieving and validating distributed claims
All domains, identifiers, and tokens in these examples are fictional.
At 09:20 you reach the checkout with a photo book and choose the student discount. The printer sends you back through the photo service with its request for the enrolled claim, you agree to share your enrollment, and a few seconds later the printer's UserInfo response carries a reference to Northfield's claims endpoint. The printer now needs to know whether you are enrolled, and it has an address and a token to ask with.
Before calling the endpoint
The address came out of a response. The printer validated that response, so it knows the photo service wrote it, but the photo service is still asking the printer to send a request, with a credential, to a server the printer did not choose. Two things can go wrong.
The first is server-side request forgery, where an attacker gets a server to send requests on the attacker's behalf. If the printer called whatever address arrived, a mistaken or compromised provider could point it at http://10.0.0.12/claims on the printer's internal network, or at a slow server that ties up the printer's workers while you wait. The second is the token. Sending demo-northfield-token-4 to any address other than Northfield's would hand a credential for your enrollment status to whoever runs that address.
So the printer checks the endpoint against its own configuration before calling it. The claims provider configuration from Reading and validating aggregated claims gains one more entry: the endpoints the printer has agreed to call for each claims provider, here exactly https://id.northfield.example/claims. The endpoint must use HTTPS and must match exactly. An address the printer has not agreed to call is treated as though the claim were missing. The call itself gets a short timeout and a limit on the size of the response, because checkout should not hang on another organization's server.
Fetching the claim
The printer sends the token as a bearer token, and Northfield answers with a JWT, shortened here for display:
GET /claims HTTP/1.1
Host: id.northfield.example
Authorization: Bearer demo-northfield-token-4
HTTP/1.1 200 OK
Content-Type: application/jwt
eyJhbGciOiJFUzI1NiIsImtpZCI6Im5vcnRoZmllbGQtMjAyNi0wOCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lkLm5vcnRoZmllbGQuZXhhbXBsZSIs...
The specification requires the endpoint to return the claim as a JWT, so a plain JSON body is refused, however reasonable it looks. Decoded, the JWT's claims read:
{
"iss": "https://id.northfield.example",
"iat": 1790846405,
"exp": 1790846705,
"https://id.northfield.example/enrolled": true
}
This statement is five seconds old. iat is 09:20:05 UTC and exp is five minutes later, because Northfield expects each application to ask again when it next needs to know.
The printer validates it exactly as it validated the aggregated statement. The issuer must be a configured claims provider that may vouch for this claim. The signature must verify with a key from Northfield's own key set and the algorithm configured for Northfield. The times must be current, any audience must be one the arrangement expects, and the JWT must contain the claim that _claim_names pointed to. Fetching from Northfield's own address over HTTPS does not replace those checks. The connection shows which server answered while it lasts. The signature shows what Northfield stated, and keeps showing it after the connection closes, for example when the checkout service that applies the discount is not the one that made the request.
The statement still names no one. It describes whoever the access token stands for, and the printer relies on the photo service to have provided a token for your enrollment record, just as it relied on the photo service to attach the right aggregated statement. The account the discount applies to is still the one the ID token identified.
When the claim cannot be retrieved
A claims provider may decline to return a claim, and the specification says a relying party should treat a claim missing from the endpoint's answer the same as any other requested claim that was not returned. More can go wrong with a fetch than with an aggregated claim, because more parties must be working at the moment you check out:
| Situation | Likely cause | What the printer does |
|---|---|---|
401 with WWW-Authenticate: Bearer error="invalid_token" | The token has expired. Northfield's endpoint was down at 09:20, and the printer's retry came after the token's 09:50 expiry. | No refresh is possible, because the printer holds no refresh token for Northfield. Offer to confirm your student status again through the photo service, which issues a new reference. |
| Timeout or server error | Northfield's endpoint is down or slow. | No discount for now. Let you finish the order without it, or try again shortly. |
| Endpoint not in the configuration | A change at the provider, or something worse. | Do not call it. Treat the claim as missing and record the event. |
| A valid JWT without the claim | Northfield declined to release it. | No discount, as with any claim that was not returned. |
| Bad signature, unexpected issuer, or JSON instead of a JWT | Misconfiguration or tampering. | Reject the statement and record a security event. |
None of these rows signs you out or changes your account, because the sign-in was complete and valid before the fetch began. The discount waits for a statement that passes every check. The printer's log records the stage, the endpoint's host, the HTTP status or failed check, and a correlation ID. It never records the access token or the JWT.
Asking as little as possible
Every fetch tells Northfield that the printer asked about you, and when. Over many orders, those requests would build a record at the university of where you shop and how often, which you never meant to share. The printer keeps that record small by asking only when the answer matters: once, when you choose the discount, rather than at every sign-in or on every page.
It keeps what it learns small too. The verified result, that Northfield confirmed your enrollment at 09:20 UTC, is enough to price this order. A later order means a new question rather than a reused answer. The access token is discarded once it has been used, or when it expires, whichever comes first. If the printing company needs evidence for a later dispute about the discount, it keeps the signed JWT with the order. Otherwise it has no reason to keep it.
The photo service has a part to play as well. It includes a reference only when you have agreed to share the claim with this relying party, and it asks Northfield for a token that works only briefly and only for this claim. Northfield, for its part, can return no more than the claim the token allows.