Skip to content
Ashish.
All posts
Diagram illustrating token exchange between microservices with actor claims.
6 min readDevelopmentBackend Developers, Identity EngineersFeatured#oauth 2.0#rfc 8693#token exchange#delegation#impersonation#security#identity management

RFC 8693: Token Exchange, Delegation, and Impersonation

RFC 8693 defines token exchange, delegation, and impersonation mechanisms for OAuth 2.0, enabling secure identity propagation across service boundaries.

By Ashish SrivastavaPart 4 of OAuth 2.0 RFCs Every Engineer Should Read

In microservices architectures, identity propagation is non-trivial. A user authenticates with an Identity Provider (IdP), receives an access token, and uses it to call Service A. Service A then needs to call Service B, which respects a different IdP or requires specific scopes that the original token does not possess. Without RFC 8693, Service A would either have to store the user’s credentials to re-authenticate (a security anti-pattern) or fail entirely. RFC 8693 defines a standardized mechanism for OAuth 2.0 Token Exchange, allowing an Authorization Server (AS) to issue a new access token based on an existing one, preserving the identity context across service boundaries.

The Identity Silo Problem

Standard OAuth 2.0 (RFC 6749) assumes a single trust domain. If Client C holds a token issued by AS-A, it can only use that token to call resources protected by AS-A. If Client C needs to call a resource protected by AS-B, the resource owner (the user) must explicitly authorize Client C with AS-B, usually via a redirect flow. This breaks automation and complicates identity management in distributed systems.

Consider a scenario where a backend service (Service A) acts on behalf of a user to update their profile in a separate system (Service B). Service B only accepts tokens from its own IdP. Under traditional OAuth, Service A cannot simply "pass along" the token it received from the user, because Service B will reject it as unknown. Service A would need the user’s password to log in to Service B’s IdP, violating the principle of least privilege and introducing credential storage risks.

RFC 8693 introduces a server-to-server handshake. Instead of re-authenticating the user, Service A sends its existing token to AS-B (or a common IdP that both trust) and requests a new token specifically scoped for Service B. This new token is cryptographically linked to the original, allowing AS-B to verify that the request originated from a valid, user-authorized context.

The Token Exchange Mechanism

The core of RFC 8693 is a new grant type: urn:ietf:params:oauth:grant-type:token-exchange. This is not a user-facing flow; it is an HTTP POST request between servers.

When a client (or service) requests a token exchange, it provides:

  1. client_id and client_secret: To authenticate the requesting party.
  2. grant_type=urn:ietf:params:oauth:grant-type:token-exchange.
  3. subject_token: The subject_token being exchanged (the "input" token).
  4. subject_token_type: Usually urn:ietf:params:oauth:token-type:access_token.
  5. requested_token_type: The desired output token type.
  6. scope: The desired permissions for the new token.

The Authorization Server validates the subject_token. If valid, it issues a new access_token (the issued_token_type). Crucially, the response may include an actor parameter if the exchange involved an intermediate actor, linking the new token to the requester.

POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
 
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&client_id=service-a
&client_secret=secret
&subject_token=eyJhbGciOiJSUzI1NiIs...
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&scope=read:profile write:profile

This mechanism allows the AS to transform the token’s context. For example, it can narrow down scopes (principle of least privilege) or convert a JWT to a SAML assertion, depending on the receiving service’s requirements.

Delegation vs. Impersonation: The act Claim

RFC 8693 distinguishes between two primary use cases: impersonation and delegation. The distinction is encoded in the actor claim within the resulting access token. The act claim is essential for maintaining the chain of authority in complex flows.

Impersonation

Impersonation occurs when a service acts directly on behalf of a user. The service presents its own token (or the user’s token) and asks for a new token that still represents the user. In this case, the actor claim is typically not present, or the subject is the user. The receiving service sees a token that appears to be issued for the user directly, though it can trace back to the impersonating service via the token’s issuer and audience.

Delegation

Delegation occurs when a service acts on behalf of another service, which in turn acts on behalf of a user. This is common in federated architectures. Here, the actor claim is critical.

The actor claim contains a serialized token (e.g., a JWT string) that represents the immediate requester. If Service A calls Service B, and Service B calls Service C, the token Service B presents to Service C will contain:

  • sub: The original user.
  • act: A string representing the serialized token of Service A.

This creates a chain of trust. Service C can inspect the act claim to see that the request was authorized by Service A, which was authorized by the user. This prevents a compromised Service B from forging requests that appear to come directly from the user, as the act claim proves the request came through Service A.

{
  "sub": "user-123",
  "aud": "service-c",
  "iss": "auth.example.com",
  "act": "eyJhbGciOiJSUzI1NiIs..."
}

Security Considerations and Scope Negotiation

Token exchange is not a free pass. RFC 8693 mandates that the Authorization Server must validate the subject_token before issuing a new one. This prevents attackers from injecting arbitrary tokens to gain access.

Furthermore, the scope parameter is key. The client can request broader scopes, but the AS is not required to grant them. The AS may return a narrower scope than requested, enforcing policy. For example, if Service A holds a token with read:profile and requests write:profile for Service B, the AS might deny the write scope if Service A is not trusted to perform writes.

A critical risk in oauth 2.0 security is "token substitution." An attacker might try to use a valid token from a different context to gain access. By using the actor claim, the receiving service can verify the full chain. If the act claim is present, the receiving service must validate the actor’s token as well. This adds a layer of validation but ensures that the delegation path is authentic.

Conclusion

RFC 8693 provides the missing link for OAuth 2.0 in multi-service environments. By formalizing token exchange, it allows services to propagate identity securely without storing user credentials or breaking the user experience. The actor claim enables sophisticated delegation models, ensuring that every step in the chain is verifiable. For identity engineers, understanding this mechanism is essential for building secure, interoperable systems where identity flows securely across trust boundaries.

Related posts