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

OAUTH 2.0 · LAB

Exchange a trusted assertion for an access token

Planned: configure a narrow trust arrangement and exchange a JWT or SAML assertion for a token. Today, see the tenant refuse both grant types and tell an assertion grant apart from a client assertion.

PlannedUses your lab tenant

The lesson

Builds on: Public and confidential clients.

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.

Setup

  1. Set the lab-printer variables (ISSUER, CLIENT_ID, CLIENT_SECRET) in your shell.

Planned walkthrough

These steps need the JWT bearer and SAML bearer grants and a trusted issuer registry (G7), plus SAML assertion processing for the SAML variant (G25). You never sign an assertion yourself: a lab-hosted demo issuer plays Lantern's identity provider.

  1. Set up the trust arrangement. In OAuth > Trusted assertion issuers, add the lab's demo issuer: its issuer value, its JWKS URL, the audience this tenant accepts (its issuer), the subject mapping (the assertion's sub to a tenant user, here Ava's external ID), the clients allowed to present its assertions, the allowed scopes (photos.read), the maximum assertion lifetime and the jti replay window. Create a temporary confidential client lab-tmp-lantern-portal with the JWT bearer grant, allow the grant in Flow policy, and keep its ID and secret as PORTAL_ID and PORTAL_SECRET.

  1. Ask the lab's demo issuer for a short-lived assertion about Ava, addressed to your tenant. It is returned as ASSERTION. Decode it with btl-lab decode "$ASSERTION" and find iss, sub, aud, iat, exp and jti.

  1. The portal presents it with its own client authentication.

curl -s -u "$PORTAL_ID:$PORTAL_SECRET" -d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
  --data-urlencode "assertion=$ASSERTION" -d scope=photos.read "$ISSUER/oauth/token" | jq

The answer is 200 with an ordinary access token. btl-lab decode shows sub is Ava's user ID and client_id is the portal. No consent screen appeared: the authority comes from the arrangement.

  1. Planned refusals, each invalid_grant with its own Audit reason: the same assertion presented twice (the jti was seen), an expired assertion, an assertion whose audience names another server, an issuer not on the list, and a subject outside the arrangement. Presenting the issuer's assertion as lab-printer, a client not allowed in the arrangement, answers unauthorized_client.

  1. The SAML variant: the demo issuer returns a SAML assertion, sent with grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer. The tenant checks Issuer, the signature, Audience, Recipient and NotOnOrAfter, and an assertion addressed to a different recipient is refused even though its signature is genuine.

Do today

  1. Present a JWT bearer grant. The value is a placeholder, not an assertion.

curl -s -u "$CLIENT_ID:$CLIENT_SECRET" -d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
  -d assertion=placeholder-not-an-assertion -d scope=photos.read "$ISSUER/oauth/token" | jq

The answer is unsupported_grant_type, "This authorization server supports the authorization_code, refresh_token and client_credentials grants."

  1. Send the same request with grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer. The answer is the same.

  1. Now put the placeholder where a client assertion goes instead, without -u.

curl -s -i -d grant_type=client_credentials -d "client_id=$CLIENT_ID" \
  -d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer -d client_assertion=placeholder "$ISSUER/oauth/token"

The answer is 401 invalid_client, and Audit records reason unsupported_auth_method against lab-printer.

Why it matters: assertion speaks for a user and takes the place of the authorization code. client_assertion speaks for the client and takes the place of its secret. The server routes them through different checks, which is why the first two requests failed on the grant type and this one failed on client authentication.

  1. Read your tenant's published keys with btl-lab discover "$ISSUER". Here the tenant is the issuer and others verify its signatures. In the planned arrangement the roles reverse: the tenant holds Lantern's keys and verifies Lantern's signatures.

  1. Write the trust arrangement you would configure for Lantern, using the lesson's checklist: issuer, its key source, accepted audience, which accounts it may speak for, which clients may present its assertions, which scopes, maximum lifetime and replay window. Note which line would stop Lantern's identity provider from vouching for Ava's personal photo account.

Check your work

Today, in tenant Logs: oauth.token rejected unsupported_grant_type with status 400 for steps 1 and 2. They are refused before any client is identified, so they are not in Audit. Audit has oauth.token rejected unsupported_auth_method for lab-printer from step 3.

Once G7 exists, the lab will check accepted and refused assertions in Audit with the issuer and the refusal reason.

Cleanup

None today. The planned walkthrough removes the demo issuer from the trust list and deletes lab-tmp-lantern-portal.

Missing infrastructure

  • G7, JWT and SAML assertion grants. The JWT bearer (RFC 7523) and SAML bearer (RFC 7522) grants; a tenant registry of trusted assertion issuers with key management, accepted audience, subject mapping, allowed clients and scopes, maximum lifetime and jti replay tracking; Audit reasons for each refusal; and a lab-hosted demo issuer so learners never create or sign assertions themselves.

  • G25, SAML. SAML assertion parsing and signature validation, needed for the saml2-bearer variant.

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