Beta

Create a tenant

A new tenant starts with its own users, OAuth settings, audit history and logs. You are its first Tenant Admin.

BTL Admin

Expiration and nonce checks

All domains, identifiers, and tokens in these examples are fictional.

The printer finishes checking your ID token at 09:00:02 UTC, two seconds after the photo service issued it. By then it knows who made the statement and whom it was made for. Three times in the token, and one value the printer chose itself, answer the remaining questions: whether the token is current, how recently you proved who you are, and which sign-in attempt the token belongs to.

Checking the clock

Like all JWT times, the three in your token count seconds since 1 January 1970 UTC:

ClaimValueTime on 1 October 2026 (UTC)
iat179084520009:00:00, when the photo service issued the token.
exp179084550009:05:00, from which the token must not be accepted.
auth_time179084518508:59:45, when you last authenticated at the photo service.

The rule for exp is strict: the current time must be before it. At 09:00:02 your token has almost five minutes to spare. Two servers rarely agree to the second, though, so the printer allows a small tolerance for the difference between its clock and the photo service's, usually called leeway. The specification describes it as small, usually no more than a few minutes. For servers that keep accurate time, a minute is plenty.

Five minutes is a generous life for a token the printer checks within seconds of receiving it, and the shortness is deliberate. The token speaks about one moment, and one that stayed acceptable for hours would be worth stealing for hours.

iat gets a check of its own. The specification lets a relying party reject a token issued too far from the current time and leaves the range to the client. The printer refuses an ID token issued more than five minutes before it arrives, whatever its exp says, or one issued further in the future than its leeway allows. A token from the future means a clock is wrong somewhere, or the token is not what it appears to be. The same window also limits how long a relying party has to remember nonces, as the last section explains.

OpenID Connect does not define nbf, "not before", for ID tokens, but it is a standard JWT claim. If a provider includes one, the printer's library checks that the current time is not before it, with the same leeway.

All of this rests on the printer's own clock. Its servers keep time with a network time service, because a server that runs a few minutes fast rejects valid tokens as expired, and one that runs slow keeps accepting tokens after they should have expired. When validation fails returns to how those faults show up.

Issued at and authentication time

ID tokens and access tokens pointed out that iat and auth_time can be far apart. In your token they are fifteen seconds apart, because you signed in at the photo service at 08:59:45 and the token was issued at 09:00:00. The next morning shows the difference.

You select Continue again. The photo service still has your session from yesterday, so it asks you nothing and sends the printer a new ID token straight away. Its times read:

iat        1790931600    2 October 2026, 09:00:00 UTC
auth_time  1790845185    1 October 2026, 08:59:45 UTC

The token is seconds old. The authentication behind it is a day old. That is single sign-on working as intended, and for choosing photos for a calendar it is fine. Before the printer closes your account or changes where your orders are delivered, though, it may want proof that you, and not someone at a computer you left signed in, are there now. That decision has to use auth_time. A printer that read iat as the moment you signed in would believe you had just proved who you are.

auth_time is not always present. The provider must include it when the request set max_age, when the request asked for auth_time as an essential claim, or when the client registered to receive it every time. Otherwise it may leave it out. The printer registered to receive it every time, as Registering a relying party will show, so every ID token the photo service sends it carries the claim. Not every relying party registers that way, so two rules apply. If a relying party asked for auth_time in any of those ways and the claim is missing, it rejects the token. If it did not ask, a missing auth_time means the time is unknown, never that the sign-in was recent.

acr works the same way. When the printer asked for a particular kind of authentication, it checks that the value in the token is one it accepts, and a missing value does not count as a yes. Session age and reauthentication covers how the printer asks for a recent sign-in, and Authentication context and methods covers acr.

Matching the nonce

State and nonce explained why the printer sends demo-nonce-3 and how a nonce exposes an injected code. Here is where the comparison sits. It comes after the signature, because a nonce means something only inside a token the photo service has signed. Then the claim is compared with the value stored in the attempt, as an exact, case-sensitive string:

Token's nonceResultWhy
demo-nonce-3AcceptedThe token answers this attempt.
demo-nonce-2RejectedThe token was issued for your earlier sign-in, not this one.
Demo-Nonce-3RejectedNonces are compared exactly, including case.
MissingRejectedThe request sent a nonce, so the token must carry it.

The demo-nonce-2 row is the replay. A few days earlier you signed in with your photo account for the first time, and the token from that attempt carried demo-nonce-2. Suppose a token carrying another attempt's nonce, like that one, turns up now in place of this attempt's token, whether through a stolen code as in State and nonce, a captured response, or a bug that mixed up two attempts. Every other check can pass. The photo service really did sign it, for the printer, about you, and if it came from a stolen code redeemed just now, even its times are fresh. Only the nonce shows that it answers a different request. The comparison does not need to know how the token arrived.

A nonce is satisfied once. The printer stores it in the pending attempt and claims the attempt as the callback is processed, so a second token carrying demo-nonce-3 finds nothing to match. A relying party that does not keep a record per attempt, such as one that holds the nonce in a protected cookie as State and nonce described, can instead record the nonces it has accepted and refuse any of them a second time. The iat check limits how long that record must last: a token issued before the window fails the time check anyway, so a used nonce needs remembering only for as long as the window.

The rule that a missing nonce fails has one more use. A provider can sign other JWTs that name the printer as their audience. Back-channel logout introduces one, the logout token, and its specification forbids a nonce in it precisely so that a relying party which checks for one will never accept a logout token as an ID token.

ID tokens returned when a refresh token is used are the exception, because no new authentication request, and so no new nonce, stands behind them. Offline access and refresh behavior covers how the printer checks those.

The token now has a provider, an audience, a time, and an attempt. What remains is the key that signed it, and how the printer keeps finding the right key as the provider replaces it.

Try it in the Lab

PUT IT INTO PRACTICE

Check your understanding

Try these questions before moving on. If an answer isn't right, use the feedback and try again.

0 of 2 answered correctly

Enable JavaScript to answer these questions and save progress in this browser.

QUESTION 1 OF 2Before closing your account, the printer wants proof that you authenticated in the last ten minutes. Your new ID token has iat of 09:00 today and auth_time of 08:59:45 yesterday. What should the printer conclude?

QUESTION 2 OF 2An ID token arrives with an iat ten minutes in the future by the printer's clock. Its signature, issuer, audience, and nonce are all correct. What should the printer do?

We value your privacy

We use cookies and similar technologies to enhance your browsing experience, and analytics to understand our traffic. By clicking "Allow All", you consent to optional analytics. Cookie Policy

Learn identity