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

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.

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.

  1. Create a scope for the membership claim

    Recorded as tenant.oauth.scopes.create succeeded.

  2. Add the custom claim to lab-collage's ID token manager

    Recorded as tenant.oauth.id_token_managers.update succeeded.

  3. Run the manager's test before relying on it

    Recorded as tenant.oauth.id_token_managers.test succeeded.

  4. Sign in with the membership scope granted

    Recorded as oauth.token succeeded for lab-collage about [email protected].

  5. The test catches a claim expression that fails

    Recorded as tenant.oauth.id_token_managers.test rejected (policy_failed).

Setup

  1. You need lab-collage with its lab-collage ID token manager, Ava, rp_discover and the redefined helpers from the provider discovery lab. Run rp_discover "$ISSUER" and keep btl-lab callback running.

  2. Press Start.

  3. In OAuth > Scopes, create a common scope lab-tmp-membership with the description "Photo plan membership". It is temporary and is deleted in Cleanup.

Walkthrough

  1. Read the provider's statements and where they come from. Open the lab-collage ID token manager and read its claim mappings: name, given_name and family_name come from directory attributes and are released with the profile scope, email and email_verified with the email scope, 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.

  1. Sign in with signin_url 'openid%20profile%20email' and exchange, 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.

  1. Weigh each claim against a use. Write one line per claim saying what the collage app may use it for: given_name in a greeting, email for receipts only when email_verified is exactly true, and nothing of these for finding the account. Only the pair iss and sub finds the account.

  1. Look for the claims this provider cannot supply. claims_supported in the discovery document lists the names above, and none of picture, locale, preferred_username, phone_number or updated_at. The directory holds a first name, a last name and an email address only.

  1. Add a custom claim. On the lab-collage ID token manager, add a mapping named example.photos.membership with the text value plus, limited to the scope lab-tmp-membership, with destinations ID token and UserInfo. Run the manager's Test, then save. Sign in once with signin_url 'openid%20lab-tmp-membership' and once with signin_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.

  1. 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.

  1. 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).

  1. Fetch the discovery document again: claims_supported now lists example.photos.membership. It lists what the provider may supply, not what it holds for Ava.

  1. 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

  1. A claim expression that fails. On the lab-collage ID token manager, add a mapping lab_broken of type expression with the value context.subject.nonexistent.value and 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

  1. Remove the example.photos.membership mapping from the lab-collage ID token manager, and make sure lab_extra and lab_broken are gone.

  2. Delete the lab-tmp-membership scope.

  3. Keep account.json for 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, birthdate or updated_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, with updated_at from 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 create https://photos.example/claims/membership and compare it with a short private name from Lab Mail.

Back to all labs

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

The Lab