OPENID CONNECT · LAB
Reassign an email address and see why only issuer and subject identify a person
Move [email protected] from Ava to Ben, watch an email-keyed lookup hand over the wrong account, see the tenant refuse to reuse a subject, and trim lab-collage to the claims it needs.
Partly readyUses your lab tenant
The lesson
Builds on: Public and pairwise subject identifiers.
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.
- G21 Group and custom-attribute token claims; directory roles fixed to `member`
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.
Give Ava a new email address
Recorded as
tenant.users.updatesucceeded.Give Ben the address Ava gave up
Recorded as
tenant.users.updatesucceeded.Let lab-collage's manager use email as the subject, in a contained step
Recorded as
tenant.oauth.id_token_managers.updatesucceeded.The tenant refuses to give an email-shaped subject to a second person
Recorded as
oauth.tokenfailed (subject_in_use) forlab-collage.Restore the default subject
Recorded as
tenant.oauth.id_token_managers.updatesucceeded.
Setup
You need
lab-collagewith itslab-collageID token manager issuing the defaultsub, Ava and Ben in Lab Photos,rp_discoverand the redefined helpers,links.jsonandaccount.json. Runrp_discover "$ISSUER"and keepbtl-lab callbackrunning.Sign Ava in once with
signin_url 'openid%20email'andexchange. Make surelinks.jsonholds her(iss, sub)pair andaccount.jsonholds her email address.Press Start.
Walkthrough
Reassign an address. In Users, change Ava's email to
[email protected], then change Ben's email to[email protected]. Each change ends that user's sessions and revokes their tokens.
Sign in through
lab-collageas the new owner of[email protected], using Ben's password, and validate the token. It saysemail: [email protected]with Ben'ssub. Look the person up both ways:By email in
account.json: it finds Ava's account and would hand it to Ben.By
(iss, sub)inlinks.json: it finds nothing, so this is a new customer.
Why it matters: every value in that token was true. Only the issuer and subject pair stayed tied to the right person.
Read
email_verifiedfor both users:false. An administrator's change clears verification. The claim describes a moment of verification, not current ownership, and only the JSON valuetruecounts as verified.
A contained step: let the provider use email as the subject. On the
lab-collageID token manager, assigned only tolab-collage, set the standard claimsubto the attribute Email. Change Ben's email back to[email protected], then Ava's back to[email protected], sign in as Ava, and the token sayssub: [email protected].
Reassign again, as in step 1, and sign in as Ben (now
[email protected]). The code is issued, but the token request fails with500andserver_error.
Why it matters: the tenant never gives a sub to a second person, as OpenID Connect requires, so an email-based subject turns reassignment into an outage instead of an account takeover. Sign in as Ava (now [email protected]): her sub has changed, so the collage app no longer finds her account either. Email is unstable whichever side uses it.
Restore: set sub on the lab-collage ID token manager back to the default (the user ID), then change Ben's email back to [email protected] and Ava's back to [email protected], in that order. The email-shaped subjects stay bound to the users that first received them and are never issued to anyone else.
Collect less. Change the collage app's sign-in to
openid%20email, addingprofileonly where a greeting needs it. Keep the account record to an allowlist, and write the sign-in log line with only what happened:
curl -s "$USERINFO_ENDPOINT" -H "Authorization: Bearer $TOKEN" | jq '{given_name, email, email_verified}' > account.json
jq -cn --arg i "$ISSUER" --arg s '<sub>' --arg c "$(openssl rand -hex 8)" '{event: "sign_in.completed", message: "Sign-in completed", issuer: $i, subject: $s, stage: "session", outcome: "succeeded", correlation_id: $c}'
Read the provider's records the same way. Open a few
oauth.authorize,oauth.tokenandoidc.userinfoentries in Lab Photos Audit. They carry user and client IDs, outcomes and request IDs, and no names, email addresses or token values.
Planned walkthrough
This step runs once directory claims include updated_at (G21).
Change Ava's last name in Users, sign in again, and compare
updated_atwith the value stored inaccount.json. The new value is larger, so the collage app refreshes its copies only then. Sign in once more without a change:updated_atis unchanged, and the copies stay as they are.
Break it
Steps 2 and 5 are the deliberate failures: an email-keyed lookup that hands over an account, and an email-shaped subject that turns reassignment into an outage. Before you continue, make sure the Restore in step 5 is done: lab-collage issues the default sub, and Ava is [email protected] again.
Check your work
Press Check my progress. It looks for, in order: two tenant.users.update records for the email reassignment, the lab-collage ID token manager switched to an email subject, oauth.token failed with subject_in_use for lab-collage, and the manager restored to the default subject.
links.json should still map Ava's original (iss, sub) to her account.
Cleanup
Confirm that Ava is
[email protected], Ben is[email protected], and thelab-collageID token manager issues the defaultsub.Delete any copies of
account.jsonyou no longer need.
Missing infrastructure
G21 (group and custom-attribute claims): there is no
updated_atclaim. Directory users record a last-change time, but it is not a claim attribute. The planned step will refresh the collage app's copies only whenupdated_atgrows, as the lesson's "Collecting less" section describes. Today a relying party can only refresh its copies on every sign-in.