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

Operate your tenant as an authorization server for a day

Review the client registry and suspend a client, watch stored approvals drive consent, plan a key rotation, read the audit trail for secrets, and end access through account events.

Partly readyUses your lab tenant

The lesson

Builds on: Token formats and validation, Client credentials.

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. Suspend lab-print-orders

    Recorded as tenant.oauth.clients.update succeeded.

  2. See the suspended client refused

    Recorded as oauth.token rejected (client_disabled) for lab-print-orders.

  3. Publish the next signing key ahead of use

    Recorded as tenant.oauth.keys.generate succeeded.

  4. Move signing to the new key

    Recorded as tenant.oauth.managers.update succeeded.

  5. End Ava's grants with a password change

    Recorded as tenant.users.credentials.set succeeded.

  6. See the printer's refresh refused afterwards

    Recorded as oauth.token rejected (refresh_revoked) for lab-printer.

Setup

  1. Choose Lab Photos as the lab tenant and press Start.

  2. Load CLIENT_ID and CLIENT_SECRET for lab-printer, ORDERS_ID and ORDERS_SECRET for lab-print-orders, and the helpers from Rotate a refresh token family.

  3. Start a review table with one row per client in Clients: type, redirect URIs, assigned scopes, consent setting, access token manager, and when you last used it.

Walkthrough

  1. Review the registry. For each client, check that every redirect URI is on a host you control or loopback, that its scopes match its job, and that its name on the consent screen is accurate. Fill in "last used" from Audit, filtered by client.

Note: the tenant does not record a last token issuance time per client (G52), so "last used" comes from memory or from Audit's 30-day window. A client unused for a year cannot be found this way.

  1. Suspend a client and see it take effect at once. In Clients, set lab-print-orders to disabled and save. Then:

curl -s -u "$ORDERS_ID:$ORDERS_SECRET" "$ISSUER/oauth/token" -d grant_type=client_credentials -d scope=prints.create | jq .

Returns 401 invalid_client, Audit reason client_disabled.

Why it matters: the registry is how the provider suspends a misbehaving client within minutes rather than days.

Restore: set lab-print-orders back to enabled and save.

  1. Watch the stored approval drive consent. Confirm lab-printer's Consent interaction asks once per set of scopes. Then, with btl-lab callback running:

    • authorize "photos.read", sign in as Ava: the consent screen asks once. Approve.

    • authorize "photos.read" again: no consent screen, because the decision was already made.

    • authorize "photos.read photos.share": the consent screen appears again, for the new scope.

    • Add &prompt=consent to a photos.read request: the screen appears even though the approval is remembered.

Why it matters: the stored approval decides when the server may skip the screen, and a new scope needs a new decision rather than being covered by an old one.

  1. Write down your lifetime decisions with a one-line reason each: the authorization code lifetime (Flow policy), session lifetime, and for each access token manager the access token lifetime, refresh idle lifetime, sign-in limit and reuse grace.

Why it matters: these are policy choices a provider makes per client and scope, and reviews when a client's needs change.

  1. Run a planned key rotation.

    • In Key Management, Generate key (ES256) and leave it unused. Fetch $ISSUER/oauth/jwks: it is published beside the current key.

    • Edit Default access tokens and choose the new key as its signing key. New tokens carry the new kid.

    • Try to retire the new key, which a manager now uses: the change is refused.

    • Move the old key to Retiring. Disable it only after its longest-lived token has expired, an hour with the default lifetime.

Why it matters: the new key appears before it signs anything, and the old one stays published while tokens it signed are still alive, so verifiers the provider does not control keep up.

  1. Read the audit trail as an investigator would. In Audit, look through the last day. Every entry has a time, operation, client, subject where there is one, outcome and reason. None contains a code, token, secret or password.

  1. End access through an account event. Get a refresh token for Ava (authorize "photos.read offline_access", exchange). In User Management, set a new password for Ava. Then refresh "$REFRESH": invalid_grant, Audit reason refresh_revoked.

Why it matters: events that should end grants must actually reach the grant records. The printer learns at its next refresh and asks Ava to reconnect.

Note: Ava has no connected applications page where she could see and remove the printer's grant herself (G40), so this lab ends the grant through a password change.

Break it

Present a wrong secret for lab-printer five times:

for i in 1 2 3 4 5; do curl -s -o /dev/null -w '%{http_code} ' -u "$CLIENT_ID:wrong-secret-wrong-secret-wrong-secret-0$i" "$ISSUER/oauth/token" -d grant_type=client_credentials; done; echo

Each is 401, and each appears in Audit as oauth.token rejected with invalid_client against the claimed client, so a known client ID being paired with guessed secrets is visible. If a protocol limit is reached, the response becomes 429 with Retry-After.

Check your work

Press Check my progress. The checks look for, in order: the suspension of lab-print-orders, its refused token request with client_disabled, the new signing key, the manager switching to it, the password change for Ava, and the printer's refused refresh.

Cleanup

  1. Confirm lab-print-orders is enabled.

  2. Keep the new key active on Default access tokens. After an hour, disable the old key in Key Management.

  3. Store Ava's new password. Run unset REFRESH TOKEN RESP ORDERS_SECRET.

Missing infrastructure

  • G40 Connected applications. A per-user and per-client grant view showing what was approved, when, and when it was last used, with removal that ends the grant and every family under it. Step 7 would then remove the printer's grant from Ava's account page instead of changing her password.

  • G52 Client last-used report. A last token issuance time per client, so step 1 can find clients unused for a year and disable them with a message to their contacts, instead of relying on memory or the 30-day Audit window.

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