OAUTH 2.0 · LAB
Map the OAuth roles and endpoints onto your tenant
Find each endpoint in your tenant's metadata, move the token endpoint and watch a discovery-driven client follow it, then trace one authorization through the endpoints in Audit.
ReadyUses your lab tenant
The lesson
Builds on: The problem OAuth solves.
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.
Sign in to start this lab and check your progress. Log in or create an account.
Move the token endpoint to a new path
Recorded as
tenant.oauth.metadata.updatesucceeded.Ava approves at the authorization endpoint
Recorded as
oauth.authorizesucceeded (code_issued) about[email protected].The code is presented at the moved token endpoint
Recorded as
oauth.tokensucceeded about[email protected].The resource server answers with the token
Recorded as
oidc.userinfosucceeded (userinfo_served).Put the token endpoint back
Recorded as
tenant.oauth.metadata.updatesucceeded.Reusing the authorization endpoint path is refused
Recorded as
tenant.oauth.metadata.updaterejected.
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
You need the Metadata Management permission in the lab tenant. The built-in Tenant Admin role includes it.
Set
ISSUERin your shell (see the previous lab) and press Start on this page.
Walkthrough
Read the authorization server's published addresses.
GET$ISSUER/.well-known/openid-configuration
Open in console
GET $ISSUER/.well-known/openid-configuration HTTP/1.1From a shell, the same request narrowed to the fields this lab uses:
curl -s "$ISSUER/.well-known/openid-configuration" | jq '{issuer, authorization_endpoint, token_endpoint, jwks_uri, userinfo_endpoint, grant_types_supported}'
The answer lists your issuer with /oauth/authorize, /oauth/token, /oauth/jwks and /oidc/userinfo under it.
Why it matters: the authorization endpoint and the token endpoint belong to the authorization server, so they are published here. The redirect URI is not in this document, because it belongs to the client.
Fill in the lesson's role table for your tenant.
| Role | In your tenant |
|---|---|
| Resource owner | Ava |
| Client | Token Decoder (its client ID) |
| Authorization server | your issuer |
| Resource server | the UserInfo endpoint, standing in for the photo API |
Then open OAuth > Clients > Token Decoder > View and find its redirect URI.
Why it matters: one tenant host plays both the authorization server and a resource server here, as the lesson's photo service might. Roles are responsibilities, not separate machines.
In OAuth > Metadata Management, change the token endpoint path from
/oauth/tokento/oauth/v2/tokenand save. Fetch discovery again:token_endpointnow ends in/oauth/v2/token.
Check both paths from your shell.
curl -s -i -X POST "$ISSUER/oauth/token" # 404, {"error":"not_found"}
curl -s -i -X POST -d grant_type=client_credentials "$ISSUER/oauth/v2/token" # 401, {"error":"invalid_client",...}
The old address no longer exists. The new one answers like a token endpoint: it refuses this request because no client authenticated.
Why it matters: the lesson's path names are not required spellings. A client that hard-coded the old address now fails, while the endpoint's responsibility is unchanged.
Run the Token Decoder again with Scopes
openid photos.readand tick Ask me to sign in again. Sign in as Ava. It works without any change, because the decoder reads the token endpoint from discovery.
In Metadata Management, restore the token endpoint path to
/oauth/tokenand save. Confirm discovery shows it again.
Open Audit and read the run from step 5 in time order.
| Event | Endpoint | Who sent it |
|---|---|---|
oauth.authorize request_started | authorization endpoint | Ava's browser, no actor yet |
oauth.authorize user_signed_in | authorization endpoint | Ava's browser |
oauth.authorize code_issued | authorization endpoint, answered to the redirect URI | Ava's browser carries the code back |
oauth.token succeeded | token endpoint | the client, directly |
oidc.userinfo userinfo_served | resource server | the client, with the access token |
Why it matters: the authorization code appears between the authorization endpoint and the token endpoint, and never at the resource server. The access token is what reaches the API.
Break it
In Metadata Management, try to set the token endpoint path to
/oauth/authorize. Saving is refused withinvalid_metadata: each endpoint keeps a distinct path and a distinct responsibility. Nothing changes.
Check your work
Press Check my progress. In tenant Audit you can also find two tenant.oauth.metadata.update succeeded events, one rejected, and the protocol chain from step 7. Logs has a summary row with reason not_found and status 404 for the old path in step 4.
Cleanup
Confirm that discovery's
token_endpointends in/oauth/token. Every later lab assumes it.