OAUTH 2.0 · LAB
See who the downstream token says is acting, by delegation and by impersonation
Exchange Ava's token under a delegation policy and under a narrow impersonation policy, and compare what the storage service can see and log. Today, find where your tenant already separates actor and subject.
PlannedUses your lab tenant
The lesson
Builds on: The problem token exchange solves.
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.
- G6 Token exchange (RFC 8693)
Setup
These steps are real today. You need lab-printer, lab-photo-api with lab-tmp-at-storage, the credentials in the shell, and Ava's printer token AT from Try three ways to call the storage service. Get a fresh AT if it has expired.
Planned walkthrough
This walkthrough runs once your tenant supports token exchange with a configurable actor mode (G6), using the planned setup from the previous lab.
Delegation. With
lab-photo-api's exchange policy set to record the client as actor, exchangeATfor storage as in the previous lab and decode the result:
{"sub": "<Ava's ID>", "aud": "https://storage.lab.example", "client_id": "<lab-photo-api ID>", "scope": "storage.read", "act": {"sub": "<lab-photo-api ID>"}}
The storage service (btl-lab resource --port 8767 --mode introspect --audience https://storage.lab.example --read-scope storage.read) logs Ava as the subject and the photo API as the current actor.
Why it matters: sub is still Ava. client_id says which registered client asked for the token, and act says who is acting for its subject; here they are the same party. Claims inside act only identify the actor and never decide validity.
Impersonation, kept narrow. Switch the policy's actor mode to Impersonation (planned) with the restrictions the lesson lists: scope
storage.readonly, lifetime 60 seconds, this client only, and a required reason recorded with each exchange. Exchange again. The new token has noactclaim, and storage logs only Ava. Audit recordsoauth.tokensucceededtoken_exchangednaming both the client and Ava, with the reason.
Why it matters: at storage an impersonation token cannot be told apart from Ava. The authorization server's record is the only place the real actor appears, which is why impersonation needs a narrow scope, a short life, named clients and a reason.
The recipient decides what it accepts. Restart storage with
--actor <lab-photo-api ID>(planned option): it accepts a token about a user only when the current actor is the photo API. The impersonation token is refused with403; the delegation token from step 1 is allowed.
Restore: switch lab-photo-api's actor mode back to Delegation. Audit records tenant.oauth.clients.update for each change.
Why it matters: delegation is the better default wherever the recipient can understand it. It costs one claim and keeps the actor visible to the API making the decision.
Do today
Your tenant's own records already keep actor and subject apart. In Lab Photos, open Users > [email protected], choose Lock, then Unlock.
Restore: confirm Ava is unlocked before continuing.
Open Audit and find tenant.users.lock and tenant.users.unlock: you are the actor and Ava is the subject. That separation is what an impersonation token loses at the recipient.
Compare the two tokens from the previous lab. In
btl-lab decode "$AT",client_idis the printer (who asked) andsubis Ava (whom it is about). In the photo API's own client credentials token, both are the photo API. These answer two of the lesson's questions; the third, who is acting now, needsact.No configuration can fake an actor. In OAuth > Access token managers > lab-tmp-at-storage, try to add a claim mapping named
act. The name is reserved, so the change is refused. Once token exchange exists, only the exchange itself will setact.
Check your work
There are no automated checks while this lab is planned. For Do today, look in Lab Photos' Audit for tenant.users.lock and tenant.users.unlock with Ava as subject, and for the refused manager update.
Cleanup
Confirm Ava is unlocked. Keep the token exchange setup for the next lab.
Missing infrastructure
G6 Token exchange, with an actor mode per client and target (delegation or impersonation), impersonation restrictions with a recorded reason, and
actset only by the exchange. The--actoroption in step 3 is a planned addition tobtl-lab resource.