skip to content

In an RFC 8693 token exchange, what do `subject_token` and `actor_token` each identify?

level: middleimportance: must knowfreq 50%

answer

  1. two parties, two token parameters
  2. who it is about, who wields it
  3. subject is the one being acted for
  4. actor is optional, its type is not
  5. both present means delegation requested

basics

~20 s

subject_token carries the party the new token is to be about, and that identity lands in the issued token's sub claim. The optional actor_token carries the party that will act for that subject. Sending both asks for delegation.

solid answer

~40 s

`subject_token` is the token representing the party the issued token is **about** — the subject — and it is REQUIRED, always paired with a `subject_token_type` URI. `actor_token` is OPTIONAL and represents the party that will **wield** the issued token on that subject's behalf; when it is sent, `actor_token_type` must be sent with it. Sending only a subject asks for a token that simply speaks as the subject; sending both asks for one that names the subject and records the actor beside it. Neither parameter says where the token will be used — that is `audience` or `resource` — and holding a subject's token is not by itself permission to exchange it.

code

http · 11 lines
http
POST /token HTTP/1.1
Host: authorization-server.example
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&subject_token=accVkjcJyb4BWCxGsndESCJQbdFMogUC
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
&actor_token=7c5e2a0f9d1b4a3e8f60c2d4b7a91e35
&actor_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
&audience=messaging-provider
&scope=reminders%3Asend

go deeper

for a junior

Recall which is which: the subject is the party the token is about, the actor is the party doing the acting. Each arrives as a token, and each has its own type parameter.

for a middle

Explain that actor_token is optional while actor_token_type is required whenever it is present, and that naming both parties is how a caller asks for delegation rather than impersonation.

for a senior

Demonstrate that these parameters are inputs to a policy decision, not instructions: the server validates both tokens and then decides whether this client may act for that subject.

for a principal

The judgment is where the may-act decision is recorded — in the subject's own token, in authorization-server configuration, or in a policy service — and what each choice costs to change later.

## Two parties, and the request names both Every token exchange under `RFC 8693` concerns at most two identities, and the request has a separate parameter for each. - **`subject_token`** — the token representing the party the issued token is to be **about**. Whatever identity it carries is the identity that ends up in the issued token's `sub` claim. It is REQUIRED, and it must be accompanied by **`subject_token_type`**, a URI naming what kind of token it is. - **`actor_token`** — a token representing the party that will **wield** the issued token on the subject's behalf. It is OPTIONAL; when it is present, **`actor_token_type`** is REQUIRED beside it. The short form: the subject is who the new token speaks for, the actor is who is doing the speaking. ## A worked request A reminder service for a blood-donation programme holds an access token for a donor and must call a messaging provider to send an appointment reminder. Two different questions are on the table: 1. Should the messaging provider see a token that simply says *the donor*? 2. Or a token that says *the reminder service, acting for the donor*? The first is asked by sending only `subject_token` — the donor's token. The second is asked by sending `subject_token` for the donor **and** `actor_token` for the reminder service. The parameters are how the caller expresses which of the two it wants; the difference then shows up in the issued token as the presence or absence of an `act` claim. | the request contains | who the token is about | who is recorded as acting | |---|---|---| | `subject_token` only | the subject | not stated in the token | | `subject_token` and `actor_token` | the subject | the actor | ## What the authorization server does with them On receiving the request the server works through, in order: 1. Authenticate the client making the call, exactly as for any other grant. 2. Validate `subject_token` according to the type its `subject_token_type` declares, and decide whether it trusts that token's issuer at all. 3. Validate `actor_token` the same way if one was sent. 4. Apply policy — may **this** client obtain a token for **that** subject, for the target and scope asked for? 5. Mint a token, and state in the response what was minted. Step 4 carries the weight, and it is entirely the server's. Nothing in the parameter pair authorises anything by itself: `subject_token` and `actor_token` are inputs to a decision, not instructions. The value of naming both parties explicitly is that the decision, and the token that comes out of it, can be about both — the subject whose data is at stake and the actor who will be holding the credential. ## The mistakes this parameter pair invites - **Putting the caller's own token in `subject_token`.** The caller is usually the actor, not the subject. A service exchanging its own token for a narrower one is doing something legitimate, but it is a different exchange with a different meaning. - **Naming the downstream target with a token parameter.** Neither parameter says where the issued token will be used; that is what `audience` and `resource` are for. - **Assuming `actor_token` is mandatory.** It is optional. An authorization server may instead take the client it has just authenticated at the token endpoint as the acting party, which is why plenty of working deployments never send one. - **Treating possession as permission.** Holding a subject's token does not entitle a caller to exchange it. A `may_act` claim inside the subject's token is one way that permission is written down in advance, but the decision remains the server's. ## Does the subject have to be a person? No. The subject is simply the party the new token is about, and that may be a service's own identity. The parameters carry no assumption that a human is behind them, and a chain in which one service exchanges a token for a narrower one aimed at a single callee is a perfectly ordinary exchange with no resource owner anywhere in it. What stays constant is the grammar: one parameter for the party the token speaks for, one optional parameter for the party that will speak, and a type URI attached to each so the server knows what it has been handed.

  • If no `actor_token` is sent, can the issued token still record an acting party?
    It can. The acting party does not have to be identified by a token: an authorization server may take the client it authenticated at the token endpoint as the actor and record it. What the specification fixes is narrower — `actor_token` is optional, and when it is present `actor_token_type` must accompany it.
  • What stops a service putting any token it happens to hold into `subject_token`?
    The authorization server's policy. It validates the subject token as its own or a trusted issuer's, then decides whether this authenticated client may exchange that subject's token at all. A `may_act` claim in the subject's token is one way that permission is expressed in advance. Possession is not authorisation.
  • Which parameter tells the server what kind of token `subject_token` is, and why does it need telling?
    `subject_token_type`, a registered URI such as `urn:ietf:params:oauth:token-type:access_token` or `urn:ietf:params:oauth:token-type:id_token`. The server cannot safely guess: the validation rules and the trust decision differ per type, and a token that is acceptable as one kind of input may be unacceptable as another.

saying these in an interview costs you the question

  • Puts the calling service's own token in subject_token.
  • Thinks actor_token is required for every token exchange.
  • Reads subject_token as the token being requested rather than supplied.
  • Assumes the server derives the subject from client authentication.
  • Names the downstream target with actor_token instead of audience or resource.