IDENTITY SECURITY · LAB
Rotate, retire and disable a signing key as an exposure response
Validate tokens with an explicit issuer and audience, then run an emergency key rotation: generate a key, move signing to it, retire and disable the old one, and confirm what it signed stops being trusted.
Partly readyUses both lab tenants
The lesson
Builds on: How sessions and tokens are stolen.
New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.
Partly ready. Most of this lab runs today. Steps that wait on platform features are marked, and Missing infrastructure says what they need.
- G66 Second lab tenant for every learner: additional tenants need a paid subscription or a BTL grant, so labs that use Lab Mail cannot be completed by an ordinary learner yet
Needs a second tenant. This lab also uses Lab Mail, a second tenant. Additional tenants currently need a paid subscription or a BTL grant, so you may not be able to do the Lab Mail steps yet (gap G66).
Your progress
Press Start before you begin. Only events your tenant records after that count, in the order below. Checking reads your tenant's Audit, so you need Audit read access in it.
Sign in to start this lab and check your progress. Log in or create an account.
Generate a new access token signing key
Recorded as
tenant.oauth.keys.generatesucceeded.Move the access token manager to the new key
Recorded as
tenant.oauth.managers.updatesucceeded.Retire the old key
Recorded as
tenant.oauth.keys.retiresucceeded.Disable the old key
Recorded as
tenant.oauth.keys.disablesucceeded.The photo API sees the old token is no longer active
Recorded as
oauth.introspectsucceeded (other_client_token_found) forlab-photo-apiabout[email protected].Retiring a key a manager still uses is refused
Recorded as
tenant.oauth.keys.retirerejected.
Setup
Press Start on this page.
You need
lab-photo-apiwith its credentials inAPI_IDandAPI_SECRET(from the sessions lab) and the lab toolkit.In Key Management, note the
kidand algorithm of the active key your default access token manager signs with, and separately the key your ID token manager uses.
Walkthrough
Sign in as Ava at
$ISSUER/token-decoderand copy the access token into your shell. Decode it and note the header'skidand the payload'sissandaud.
read -rs TOKEN
btl-lab decode "$TOKEN"
Why it matters: decoding only reads the token. The header's kid is a hint for which key to try; it is not proof of anything until a validator you configured checks it.
Validate the token with explicit settings: the issuer you expect, the audience it was issued for, and the access token type. Then fetch the issuer's published keys.
btl-lab verify "$TOKEN" --issuer "$ISSUER" --audience "<aud from decode>" --type at+jwt
btl-lab discover "$ISSUER"
Why it matters: the lesson's fix for every validation mistake is the same. The validator decides the issuer, audience, algorithms and key source for itself and treats the header as a hint. btl-lab verify prints each of those checks.
Sign in at
$ISSUER2/token-decoder, the Lab Mail tenant, with a test user there (create one in Lab Mail's Users if it has none), and copy that access token intoTOKEN2. Validate it with the Lab Photos settings.
read -rs TOKEN2
btl-lab verify "$TOKEN2" --issuer "$ISSUER" --audience "<aud from decode>" --type at+jwt
Why it matters: this is the lesson's "accepting another tenant's issuer." The Lab Mail token is genuine and correctly signed by its own tenant, and it is still refused, because its issuer and keys are not the ones this validator was configured to trust.
In Key Management, generate a new key with the same algorithm. Then edit the default access token manager to sign with the new key and save.
Why it matters: in an exposure you cannot wait for a planned overlap. The new key must be in use before the old one leaves, so genuine new tokens keep working.
Retire the old key. Fetch the published keys again: both keys are listed. Sign in through the Decoder again and decode the new token: its
kidis the new key's.
btl-lab discover "$ISSUER"
Why it matters: a retiring key is still published so cached verifiers can check tokens it already signed. In a planned rotation you would wait here; in an exposure you go straight on.
Disable the old key. Fetch the published keys once more: the old key is gone. Introspect the first token and validate it again.
btl-lab introspect "$TOKEN" --client-env API
btl-lab verify "$TOKEN" --issuer "$ISSUER" --audience "<aud from decode>" --type at+jwt
Why it matters: removing the key ends trust in everything it ever signed, genuine or not, because a signature cannot tell them apart. Introspection reports active: false, and local validation fails to find the key once a verifier refreshes its copy of the key set.
Write down every verifier that would still hold the old key in a cached key set, and how each would be told to refresh. Note that the ID token key is separate: disabling the access token key does not touch ID tokens, so a real exposure rotates every key that may have leaked.
Why it matters: cached keys keep the old trust alive until they are fetched again, and separate keys per purpose limit what one leak exposes.
Break it
Try to retire the new key, which the access token manager still uses. The portal refuses it while a manager signs with it. Nothing changed, so there is nothing to restore; to rotate it later, move the manager to another key first, as in step 4.
Check your work
Check my progress confirms the key generation, the manager change, the retirement and disabling, the photo API's introspection afterwards, and the refused retirement.
In Audit, source OAuth management, the refused retirement shows reason
key_in_use.Your notes record the old and new
kidvalues and the result of each validation.
Cleanup
Keep the new key active. Leave the disabled key as it is; it stays out of the published set.
Clear the tokens:
unset TOKEN TOKEN2.Delete the Lab Mail test user if you created one for this lab.
Missing infrastructure
G66 Second lab tenant: this lab uses Lab Mail, a second tenant. Additional tenants currently need a paid subscription or a BTL grant, so an ordinary learner can do only the Lab Photos steps until every learner can have a second lab tenant.