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

Refuse near-miss issuers, another client's token and an extra audience

Give lab-collage its own ID token manager, reject near-match issuers and a genuine token issued to the printer, then add a second audience and decide deliberately whether to trust it.

ReadyUses your lab tenant

The lesson

Builds on: Validating an ID token.

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

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 the lab-collage ID token manager

    Recorded as tenant.oauth.id_token_managers.create succeeded.

  2. Assign it to lab-collage only

    Recorded as tenant.oauth.id_token_managers.assign succeeded.

  3. Obtain a genuine ID token issued to the printer

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

  4. Add a second audience to lab-collage's ID tokens

    Recorded as tenant.oauth.id_token_managers.update succeeded.

  5. Receive an ID token with two audiences

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

  6. Remove the extra audience again

    Recorded as tenant.oauth.id_token_managers.update succeeded.

Setup

  1. You need lab-collage, lab-printer, Ava, the helpers from the authentication request lab, and EXPECTED_ISSUER, EXPECTED_AUD and ID_ALGS from the previous lab. Keep btl-lab callback running.

  2. Press Start.

  3. In OAuth > ID Token Management, create a manager named lab-collage as a copy of the defaults: the tenant's RS256 key, a 300-second lifetime and the default claim mappings. Assign it to lab-collage only. The rest of the track changes this manager and never the tenant default, so no other client is affected.

Walkthrough

  1. Run a fresh lab-collage sign-in (signin_url 'openid', then exchange) and keep ATTEMPT_NONCE=$NONCE. Confirm it verifies with your normal settings.

  1. Exact issuer. Run the verifier against four near matches:

for i in "$ISSUER/" "${ISSUER^^}" "${ISSUER/https/http}" "$ISSUER/test"; do
  btl-lab verify "$ID_TOKEN" --issuer "$i" --audience "$EXPECTED_AUD" --algs "$ID_ALGS" --type id --nonce "$ATTEMPT_NONCE"; done

Each run passes the signature and stops at the issuer check.

Why it matters: an issuer is a name compared as text, never an address to be tidied up. It is also the namespace for every sub the provider issues.

  1. Where the expected value comes from. Show the wrong design once: copy the iss value from btl-lab decode "$ID_TOKEN" and pass that as --issuer. It passes, but it only compared the token with itself, and would pass a token from any provider whose keys you happened to use. Always pass --issuer "$EXPECTED_ISSUER", the value stored with the attempt.

  1. A genuine token for another client. Run a lab-printer sign-in with scope=openid in the same browser. Ava's session is still valid, so the tenant asks nothing, just as in the lesson. Keep PRINTER_IDT and PRINTER_NONCE, then verify it as the collage app with the printer's own nonce:

btl-lab verify "$PRINTER_IDT" --issuer "$EXPECTED_ISSUER" --audience "$EXPECTED_AUD" --algs "$ID_ALGS" --type id --nonce "$PRINTER_NONCE"

The signature and issuer pass, then the audience check refuses it.

Why it matters: everything about this token is genuine, signed by the same key. Only aud shows that it was issued to someone else.

  1. Two audiences. Open the lab-collage ID token manager, set the standard claim aud to a list of two values, your lab-collage client ID and your lab-printer client ID, and save. The tenant requires the requesting client's ID to stay in the list. Sign in again through lab-collage and verify the new token with your normal settings. It stops at the audience check, although your client ID is in the list.

Why it matters: every party named in aud was meant to receive the same token, and any of them could present it elsewhere. A token addressed to the printer too could arrive from the printer as easily as from your own exchange.

  1. Trust the extra audience on purpose:

btl-lab verify "$ID_TOKEN" --issuer "$EXPECTED_ISSUER" --audience "$EXPECTED_AUD" --trusted-audience "$PRINTER_ID" --algs "$ID_ALGS" --type id --nonce "$NONCE"

It now ends in ACCEPT. Trusting another audience is legitimate only for a registration you control and have decided to accept, and the value comes from your configuration.

Restore: in the lab-collage ID token manager, set aud back to the default (the client ID only) and save.

  1. The authorized party. Decode your token and the printer's: each carries azp equal to its own client ID. On this tenant azp is a protected claim that always names the requesting client, so a token that named a different client as its authorized party would not be one you asked for. Keep the rule on: if azp is present, it must equal your client ID.

Break it

  1. Client IDs compare exactly. Run step 1's verification with --audience "${EXPECTED_AUD^^}". It stops at the audience check: an uppercase client ID is a different client.

  1. A prefix rule. Imagine accepting any issuer that starts with your tenant's host. Write down which of the near matches in step 2 such a rule would let through, and why a multi-tenant service that signs every organization's tokens with the same keys makes that rule dangerous.

Check your work

Press Check my progress. It looks for, in order: tenant.oauth.id_token_managers.create and .assign, oauth.token succeeded for lab-printer, tenant.oauth.id_token_managers.update (the second audience), oauth.token succeeded for lab-collage, and a second tenant.oauth.id_token_managers.update (the restore).

None of your issuer or audience refusals reach the tenant. They exist only in your verifier's output.

Cleanup

  1. Confirm that the lab-collage ID token manager issues aud with the client ID only.

  2. Keep the manager assigned to lab-collage. Run unset PRINTER_IDT PRINTER_NONCE.

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