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

Carry a second issuer's statement in UserInfo

Plan Lab Photos carrying a statement signed by Lab Mail inside its UserInfo response, and today see the authority problem with a normal claim and get a real signed statement from a second issuer.

PlannedUses both lab tenants

The lesson

Builds on: Connecting a sign-in to an account.

New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.

Planned. The core of this lab waits on platform features that are not built yet. The planned walkthrough shows exactly how it will run; Do today is a real exercise you can do now.

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

Request console

Requests in this lab can be sent from this page to your tenant: open one and choose Send. Fill in the values below first. They stay in this page's memory and are gone when you leave; secrets are never stored or sent anywhere except the request you send.

Setup

Tenants issue normal claims only today: no _claim_names or _claim_sources, no claim_types_supported, no trusted claims provider configuration (G63), and no claims parameter to ask for one claim at checkout (G19). In this lab Lab Mail plays the lesson's university, the party that knows whether Ava is enrolled.

  1. source ~/btl-oidc.sh and run btl-lab callback before each sign-in.

  2. Once G63 exists: in Lab Mail, add a claim mapping lab_enrolled for its users and a statement profile that issues it as a JWT with no aud and no sub. In Lab Photos, add Lab Mail as a claims provider: its issuer, its JWKS, RS256, and the claim names it may vouch for. Then link Ava's Lab Photos account to her stored Lab Mail statement.

Planned walkthrough

  1. Read Lab Photos' discovery document: claim_types_supported lists normal and aggregated.

  2. Ask for the claim only at checkout, with the claims parameter for UserInfo:

signin "claims=$(enc '{"userinfo":{"lab_enrolled":null}}')"

Lab Photos asks Ava whether to share her Lab Mail enrollment with lab-collage. She agrees.

  1. Read UserInfo:

curl -s -H "Authorization: Bearer $TOKEN" "$ISSUER/oidc/userinfo" | jq '{sub, _claim_names, sources: (._claim_sources | map_values(keys))}'

_claim_names maps lab_enrolled to src1, and _claim_sources.src1 has a JWT member.

Why it matters: the claim is not among the normal claims. Two special members say where to find it, and the label says nothing about who signed it.

  1. Decode the embedded JWT with btl-lab decode: Lab Mail's iss, iat, exp and the claim, with no sub and no aud. Lab Photos' response is what ties it to Ava.

  2. Run the checkout again and decline sharing: the claim is simply absent, and nothing errors.

Do today

  1. The authority problem. In Lab Photos, create the scope lab-tmp-enrollment and add it to lab-collage's allowed scopes. In the ID token manager assigned to lab-collage, add a claim mapping lab_enrolled with the expression true, limited to that scope and to UserInfo. Sign in with it and read UserInfo:

SCOPE="openid lab-tmp-enrollment"
signin
redeem '<code>'
curl -s -H "Authorization: Bearer $TOKEN" "$ISSUER/oidc/userinfo" | jq '{sub, lab_enrolled}'

"lab_enrolled": true, asserted by Lab Photos, which holds no enrollment records at all.

Why it matters: a provider can only repeat a fact it does not own. The lesson wants each fact from the party that knows it.

  1. A statement from the party that knows. In Lab Mail, add the same mapping (lab_enrolled, expression true) to the ID token manager assigned to lab-mail-collage, for ID tokens. Sign in to lab-mail-collage as Ava Lin and keep the ID token:

ISSUER_A=$ISSUER CLIENT_A=$CLIENT_ID SECRET_A=$CLIENT_SECRET
ISSUER=$ISSUER2 CLIENT_ID=$MAIL_CLIENT_ID CLIENT_SECRET=$MAIL_CLIENT_SECRET SCOPE="openid"
signin
redeem '<code>'
MAIL_STATEMENT=$ID_TOKEN
btl-lab decode "$MAIL_STATEMENT"

iss is Lab Mail and the header names Lab Mail's kid. It also carries aud, sub and nonce. Keep MAIL_STATEMENT: Validate an embedded claims-provider JWT uses it.

Why it matters: this is a real signed statement from a second issuer, and also exactly the different kind of JWT the next lesson warns about.

  1. Ask Lab Photos which claim types it supports:

GET$ISSUER/.well-known/openid-configuration Open in console
GET $ISSUER/.well-known/openid-configuration

There is no claim_types_supported member, which means normal claims only.

  1. Switch back to Lab Photos (ISSUER=$ISSUER_A CLIENT_ID=$CLIENT_A CLIENT_SECRET=$SECRET_A SCOPE="openid profile email").

Break it

Planned, once G63 exists: ask Lab Photos for the claim after Ava's stored statement has expired. The claim is absent, not an error, and the relying party offers its other way to prove enrollment.

Check your work

Today: Lab Photos' UserInfo showed lab_enrolled asserted by Lab Photos itself; MAIL_STATEMENT decodes with Lab Mail's issuer and key; Lab Photos' discovery has no claim_types_supported. Audit in each tenant shows tenant.oauth.id_token_managers.update for the mappings.

Once G63 exists, Lab Photos' Audit records UserInfo served with an aggregated source and Ava's decision to share it.

Cleanup

  1. In Lab Photos, remove the lab_enrolled mapping, remove lab-tmp-enrollment from lab-collage, and delete the scope.

  2. Keep the Lab Mail mapping until you finish the next lab, then remove it.

Missing infrastructure

  • G63 (aggregated and distributed claims). A claims provider registry per tenant (issuer, JWKS, algorithms, permitted claim names), stored statements or references per user, _claim_names and _claim_sources in ID tokens and UserInfo, claim_types_supported in discovery, a consent choice for each source, and audit events.

  • G19 (claims request parameter). Asking for the claim only when it is needed, at checkout.

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

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