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

Trace your tenant's metadata to the documents that define it

Map discovery fields and tenant behavior to the specifications and requirement keywords behind them, and see the tenant refuse to advertise a capability it does not have.

ReadyUses your lab tenant

The lesson

Builds on: Migrating older integrations.

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. Publish custom metadata fields

    Recorded as tenant.oauth.metadata.update succeeded.

  2. Advertising a capability the server lacks is refused

    Recorded as tenant.oauth.metadata.update rejected.

  3. Remove the custom fields again

    Recorded as tenant.oauth.metadata.update succeeded.

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

  1. You need the Metadata Management permission. Set ISSUER and press Start on this page.

Walkthrough

  1. Read your tenant's discovery document and note, for each field, the document that defines it.

GET$ISSUER/.well-known/openid-configuration Open in console
GET $ISSUER/.well-known/openid-configuration HTTP/1.1
FieldDefined by
issuer, authorization_endpoint, token_endpointRFC 8414 and OpenID Connect Discovery 1.0
code_challenge_methods_supportedRFC 8414, for PKCE from RFC 7636
authorization_response_iss_parameter_supportedRFC 9207
revocation_endpointRFC 8414, for revocation from RFC 7009
introspection_endpointRFC 8414, for introspection from RFC 7662
userinfo_endpointOpenID Connect Discovery 1.0, an OpenID Foundation Final Specification

Why it matters: no single document describes this server. RFCs from the IETF and final specifications from the OpenID Foundation each contribute fields, and later documents update earlier ones without replacing them.

  1. Read btl_service_status ("partial") and btl_endpoint_status. List the catalogued endpoints that are not implemented and the specification each comes from: device authorization (RFC 8628), pushed authorization requests (RFC 9126), dynamic client registration (RFC 7591) and logout (OpenID Connect). The btl_ prefix marks fields this provider defines for itself.

  1. Registered names. Send the device authorization grant's registered URN to the token endpoint.

curl -s -d grant_type=urn:ietf:params:oauth:grant-type:device_code -d device_code=none -d client_id=x "$ISSUER/oauth/token" | jq

The answer is unsupported_grant_type. Look up both the URN and the error code in the IANA OAuth Parameters registry at https://www.iana.org/assignments/oauth-parameters/, and note which RFC registered each.

  1. Private and informational metadata. In Metadata Management, under Custom metadata fields, add {"op_policy_uri": "https://example.com/policy", "x_lab_note": "oauth core labs"} and save. Fetch discovery again: both appear.

  1. A capability the server lacks cannot be advertised. Try adding {"dpop_signing_alg_values_supported": ["ES256"]}. Saving is refused with invalid_metadata. Registered names describe real behavior; private names use the x_ prefix.

Why it matters: a client trusts discovery to tell it what the server does. A registered field that claims DPoP support the server lacks would send clients down a path that fails.

  1. Follow PKCE through the documents, with your tenant's evidence beside each step.

DocumentWhat it said about PKCEEvidence in your tenant
RFC 7636 (2015)defined it, mainly for public clientscode_challenge_methods_supported: ["S256"]
RFC 8252, BCP 212 (2017)required it for public native appslab-printer-app refused without a challenge (Public and confidential clients lab)
RFC 9700, BCP 240 (2025)public clients MUST use it; RECOMMENDED for confidential clientsper-client PKCE policy: Required by default, Optional possible
OAuth 2.1 (Internet-Draft)part of the authorization code grant itselfRequired is the default for every new client here
  1. Requirement keywords, with tenant evidence for each.

RequirementKeywordYour evidence
RFC 9700: the password grantMUST NOTunsupported_grant_type (password grant lab)
RFC 9700: public clients use PKCEMUSTpkce_required for lab-printer-app
RFC 9700: PKCE for confidential clientsRECOMMENDEDRequired by default, Optional only by an explicit choice (migration lab)
RFC 9700: implicit and other token responsesSHOULD NOToff by default, with a warning when enabled (implicit grant lab)
RFC 10017: browser-based clients and the implicit grantMUST NOTthe tenant still offers implicit as an explicit choice; record this as a deliberate difference

Why it matters: capitalized keywords carry precise force, and a server's defaults show how it reads them. A MUST NOT leaves nothing to decide; a SHOULD NOT leaves a narrow path that needs a reason.

Break it

Step 5 is the refusal. Nothing is saved.

Check your work

Press Check my progress. Logs also has oauth.token rejected unsupported_grant_type for step 3.

Cleanup

  1. In Metadata Management, remove the custom fields from step 4 and save. Confirm discovery no longer lists them.

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