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

Subject tokens and actor tokens

A token exchange request can carry two tokens. One says whom the new token will be about. The other, when present, says who will act. Each travels with a label naming its type, because an authorization server that accepts several kinds of token needs to know how to read and validate the one in front of it.

The subject token

Two parameters appear in every exchange. subject_token carries a token representing the party on whose behalf the request is made, and that party is usually the subject of the token issued in response. subject_token_type says what kind of token it is.

All domains, identifiers, and tokens in these examples are fictional. For the photo API, the subject token is the printer's access token, exactly as it arrived in the Authorization header. Shortened, and with the type shown before form encoding:

subject_token=eyJhbGciOiJFUzI1NiIsImtpZCI6InBob3Rvcy0yMDI2LTA5IiwidHlwIjoiYXQrand0In0.eyJpc3Mi...
subject_token_type=urn:ietf:params:oauth:token-type:access_token

The photo API labels it an access token because that is what it is: an access token issued by this authorization server. The label would be the same if the token were an opaque string. The photo API happens to validate it as a JWT when it serves the printer's request, but the exchange does not depend on that.

Token type identifiers

Token types are named with URIs. Token exchange defines five and uses a sixth from the JWT specification:

IdentifierThe token is
urn:ietf:params:oauth:token-type:access_tokenAn OAuth access token issued by this authorization server.
urn:ietf:params:oauth:token-type:refresh_tokenAn OAuth refresh token issued by this authorization server.
urn:ietf:params:oauth:token-type:id_tokenAn OpenID Connect ID token.
urn:ietf:params:oauth:token-type:jwtA JWT, whatever its purpose.
urn:ietf:params:oauth:token-type:saml2A SAML 2.0 assertion, base64url-encoded.
urn:ietf:params:oauth:token-type:saml1A SAML 1.1 assertion, base64url-encoded.

The list mixes two kinds of description. For tokens this authorization server issued, the identifier says what the token was issued for: an access token or a refresh token. For tokens from elsewhere, it says the format, so the server knows how to parse what it receives. The same bytes can therefore be described in two ways. access_token means "an access token you issued, whatever its format." jwt means "a JWT, whatever it is for," the label a client would use for an assertion from another issuer, like the one Lantern's identity provider signed in JWT and SAML assertion grants. Other URIs can name other types.

A client can also ask for a particular type in return with requested_token_type, using the same identifiers. It is optional. Without it, the server chooses, often from what the target service needs.

Saying who may act

The support console from Delegation and impersonation needs a subject token too, and it has none of yours. You never signed in to the console. The token has to come from you, at the moment you agree to the help.

When you start a support chat on the printer website and choose Let the agent view my order, the website asks the printer's authorization server for a short-lived token that represents you and names the agent. Decoded, its claims read:

{
  "iss": "https://auth.printer.example",
  "sub": "customer-881",
  "aud": "https://auth.printer.example",
  "scope": "orders.read",
  "iat": 1790845200,
  "exp": 1790847000,
  "jti": "demo-support-grant-5",
  "may_act": {
    "sub": "staff-17"
  }
}

The may_act claim states that a party is authorized to become the actor and act for the token's subject. Like act, its members only identify that party. Here it says that staff-17 may act for customer-881 within orders.read, for the half hour from 09:00 to 09:30 UTC. The token's audience is the authorization server itself, because nothing else needs to read it, and it reaches the console attached to your support request.

When the token arrives as a subject token, the authorization server compares may_act with the party asking to act. The claim is a statement in a token, not an instruction the server must obey. The server still applies its own policy, such as whether staff-17 holds a support role right now.

The actor token

The actor has two parameters of its own. actor_token carries a token representing the acting party, typically the one that will use the new token. actor_token_type labels it. The type is required whenever an actor token is present and must not be sent when there is none.

The console is a registered client, support-console, but the actor is a person. Several agents share the console, so its client authentication cannot say which of them is asking. For that, it sends the ID token it received when staff-17 signed in, the signed statement about a sign-in that OpenID Connect defines:

POST /token HTTP/1.1
Host: auth.printer.example
Authorization: Basic c3VwcG9ydC1jb25zb2xlOmRlbW8tb25seS1ub3QtYS1yZWFsLXNlY3JldA==
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&subject_token=eyJhbGciOiJFUzI1NiIs...
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt
&actor_token=eyJhbGciOiJFUzI1NiIs...
&actor_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token
&resource=https%3A%2F%2Forders.printer.example
&scope=orders.read

Both tokens are shortened here for display, and the Basic header represents support-console:demo-only-not-a-real-secret. The subject token is labeled jwt because it is neither an access token nor a refresh token, just a JWT written for the authorization server.

One request now identifies three parties. The client authentication speaks for the console, the actor token for the agent, and the subject token for you. The server checks that the actor token's subject is the party named in may_act, and returns the delegation token shown in Delegation and impersonation, whose client_id is support-console and whose act names staff-17.

The photo API sends no actor token, and that rests on a policy choice rather than a protocol rule. The specification's own examples express delegation by sending an actor token, and describe a request with only a subject token as impersonation. Its rules leave the decision to the server, though: whether a new token names an actor is a matter of policy, and client authentication lets the server decide which clients may receive delegations. The photo service uses that freedom for its internal services. The photo API is both the client and the actor, and its client authentication already proves who it is, so the photo service records the authenticated client as the actor. That policy is why the storage token's act named photo-api. Another server could require the photo API to send an actor token of its own, and an actor who is not the client making the request, like the agent at the console, can be identified only through one.

Try it in the Lab

PUT IT INTO PRACTICE

Check your understanding

Try these questions before moving on. If an answer isn't right, use the feedback and try again.

0 of 2 answered correctly

Enable JavaScript to answer these questions and save progress in this browser.

QUESTION 1 OF 2The photo API exchanges the printer's access token, which happens to be a JWT. Which subject_token_type fits?

QUESTION 2 OF 2Why does the support console send an actor token when the photo API does not?

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

Learn identity