OPENID CONNECT · LAB
Read your tenant's standard claims and add a custom membership claim
Check the standard claims Lab Photos issues and their JSON types, add a custom claim behind its own scope, and make lab-collage keep only the claims it decided to use.
Partly readyUses your lab tenant
The lesson
Builds on: Provider discovery.
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`
- G59 URI-form custom claim names
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.
Create a scope for the membership claim
Recorded as
tenant.oauth.scopes.createsucceeded.Add the custom claim to lab-collage's ID token manager
Recorded as
tenant.oauth.id_token_managers.updatesucceeded.Run the manager's test before relying on it
Recorded as
tenant.oauth.id_token_managers.testsucceeded.Sign in with the membership scope granted
Recorded as
oauth.tokensucceeded forlab-collageabout[email protected].The test catches a claim expression that fails
Recorded as
tenant.oauth.id_token_managers.testrejected (policy_failed).
Setup
You need
lab-collagewith itslab-collageID token manager, Ava,rp_discoverand the redefined helpers from the provider discovery lab. Runrp_discover "$ISSUER"and keepbtl-lab callbackrunning.Press Start.
In OAuth > Scopes, create a common scope
lab-tmp-membershipwith the description "Photo plan membership". It is temporary and is deleted in Cleanup.
Walkthrough
Read the provider's statements and where they come from. Open the
lab-collageID token manager and read its claim mappings:name,given_nameandfamily_namecome from directory attributes and are released with theprofilescope,emailandemail_verifiedwith theemailscope, and all five go to both the ID token and UserInfo.
Why it matters: each value is the provider's statement about Ava, and the mapping shows what stands behind it: a name an administrator typed, an address, and whether that address was ever verified.
Sign in with
signin_url 'openid%20profile%20email'andexchange, then look at the claims and their JSON types:
curl -s "$USERINFO_ENDPOINT" -H "Authorization: Bearer $TOKEN" | jq '., map_values(type)'
Everything is a string except email_verified, which is a boolean. For Ava, created by an administrator, it is false.
Why it matters: types matter, and false means only that this provider has not verified the address, not that the address is wrong.
Weigh each claim against a use. Write one line per claim saying what the collage app may use it for:
given_namein a greeting,emailfor receipts only whenemail_verifiedis exactlytrue, and nothing of these for finding the account. Only the pairissandsubfinds the account.
Look for the claims this provider cannot supply.
claims_supportedin the discovery document lists the names above, and none ofpicture,locale,preferred_username,phone_numberorupdated_at. The directory holds a first name, a last name and an email address only.
Add a custom claim. On the
lab-collageID token manager, add a mapping namedexample.photos.membershipwith the text valueplus, limited to the scopelab-tmp-membership, with destinations ID token and UserInfo. Run the manager's Test, then save. Sign in once withsignin_url 'openid%20lab-tmp-membership'and once withsignin_url 'openid'. Decode both ID tokens: the claim appears only when the scope was granted.
Why it matters: this provider ties its custom claim to a scope of its own, one of the two ways the lesson describes for requesting custom claims.
Try the collision-resistant name the lesson recommends,
https://photos.example/claims/membership. The tenant refuses it, because mapping names may contain only letters, digits,_,.and-. A domain-style dotted name is the closest form available here.
Write the claim's documentation, as the agreement between the two companies would: the possible values, what it means when the claim is absent, and how current it is (as of issuance; a membership can lapse the next morning).
Fetch the discovery document again:
claims_supportednow listsexample.photos.membership. It lists what the provider may supply, not what it holds for Ava.
Ignore what you did not decide to use. Copy only an allowlist from the claims into your account record:
curl -s "$USERINFO_ENDPOINT" -H "Authorization: Bearer $TOKEN" | jq '{given_name, email, email_verified}' > account.json
Add a second mapping lab_extra (text surprise, both destinations, no scope limit), sign in again, and run the line above. lab_extra never reaches account.json. Delete the lab_extra mapping.
Why it matters: ignoring unrecognized claims keeps the relying party working when a provider adds claims, and keeps information it never asked for out of its records.
Break it
A claim expression that fails. On the
lab-collageID token manager, add a mappinglab_brokenof type expression with the valuecontext.subject.nonexistent.valueand no scope limit, then run Test without saving. The tenant reports that the mappings did not run successfully with the sample context, before any token is affected. Discard the change.
Restore: make sure lab_broken is not saved. If it was, sign-ins through lab-collage fail with server_error and a reference_id you can find in Logs, so delete the mapping at once.
Check your work
Press Check my progress. It looks for, in order: the lab-tmp-membership scope created, an update to the lab-collage ID token manager, a successful manager test, a lab-collage token request, and the rejected test of the failing expression.
The URI-form name in step 6 appears as a rejected tenant.oauth.id_token_managers.update unless the portal stopped it before sending. The ID token carries example.photos.membership only with the scope.
Cleanup
Remove the
example.photos.membershipmapping from thelab-collageID token manager, and make surelab_extraandlab_brokenare gone.Delete the
lab-tmp-membershipscope.Keep
account.jsonfor the claim stability lab.
Missing infrastructure
G21 (group and custom-attribute claims): directory users have a first name, a last name and an email address only, so there is no source for
picture,locale,zoneinfo,preferred_username,phone_number,address,birthdateorupdated_at, and custom SCIM attributes cannot become claims. Step 4 will then find these claims available, and step 5 will map a membership attribute set by the HR simulator instead of fixed text, withupdated_atfrom the directory's last change.G59 (URI-form custom claim names): mapping names must match
^[A-Za-z][A-Za-z0-9_.-]{0,63}$, which excludes the collision-resistant URI names OpenID Connect recommends. Step 6 will then createhttps://photos.example/claims/membershipand compare it with a short private name from Lab Mail.