OAuth Actor Profile — Service-to-Service Delegation
Same-domain service-to-service delegation (Appendix A of draft-mcguinness-oauth-actor-profile-00). A payroll batch processor acts on behalf of payroll administrator 'Pat' to call the Payroll API. The Payroll API then exchanges its inbound access token for a Transaction Token at the Audit TTS to write an audit record — preserving the inbound delegation chain by nesting the prior actor beneath a new outermost `act` claim. This is the cleanest demonstration of how the actor profile transforms a single-hop `act` object into a multi-hop nested delegation chain across one Token Exchange hop.
The Payroll Batch Processor presents an access token issued earlier by the Enterprise AS. The token's `sub` identifies the payroll administrator (Pat) — the human whose authorization is being exercised — while the single-hop `act` object identifies the batch processor as the service exercising that authorization. The top-level `cnf.jkt` binds the token to the batch processor's key (SvcJKT), demonstrated via the DPoP proof on this request.
• This is a single-hop actor object: `act` is present but contains no nested `act`. There has been exactly one delegation hop so far.
• `client_id` (`payroll-batch-client`) identifies the OAuth client registration. `act.sub` identifies the acting service via its workload URI. These can be different and serve different purposes — the spec says `act.sub` is the authoritative delegated-actor identifier.
• `sub_profile: "user"` and `act.sub_profile: "service"` tell the resource server what kind of entity each principal is. The Payroll API must check both the (sub, act.sub) pair to authorize the operation.
• Appendix A §A.2 — `sub` identifies the payroll administrator while `act.sub` identifies the service exercising that administrator's authorization.
• The token is sender-constrained via `cnf.jkt` (RFC 9449 DPoP). The Payroll API verifies the DPoP proof presented on this request matches `SvcJKT-123`.
Step 1: POST /payroll/run + AT
Bearer <payroll-access-token>
<SvcJKT-proof>
application/json
services.example.com
{
"period": "2026-03",
"employees": "all-active"
}{"alg":"RS256","typ"?:"at+jwt","kid":"as-ent-2026"}{"iss"?:"https://as.example.com","sub"?:"https://idp.example.com/users/pat","sub_profile":"user","client_id":"payroll-batch-client","aud"?:"https://services.example.com/payroll-api","scope"?:"payroll:run","cnf"?:{"jkt":"SvcJKT-123"},"act"?:{"sub"?:"https://services.example.com/payroll-batch","iss"?:"https://as.example.com","sub_profile":"service"}}