Token exchange (RFC 8693)
const url = 'http://localhost:8693/v1/exchange/token';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"grant_type":"urn:ietf:params:oauth:grant-type:token-exchange","subject_token":"eyJhbGciOiJSUzI1NiIs...","subject_token_type":"urn:ietf:params:oauth:token-type:jwt","audience":"https://api.target.example.com","scope":"read:data"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:8693/v1/exchange/token \ --header 'Content-Type: application/json' \ --data '{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "subject_token": "eyJhbGciOiJSUzI1NiIs...", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "audience": "https://api.target.example.com", "scope": "read:data" }'Validates a source credential, evaluates OPA policy, and mints a WIMSE-compliant JWT. Supports execution scoping (DPoP-style), delegation via actor tokens, and capability narrowing.
Protected by mTLS when TLS is enabled.
Request Body required
Section titled “Request Body required ”object
Must be “urn:ietf:params:oauth:grant-type:token-exchange”
The source credential being exchanged
Token type URI identifying the credential format
Target trust domain or service URL
Requested scope
JWT of the delegating agent (for delegation chains)
DPoP-style execution scoping (RFC 9449). Binds the token to a specific HTTP action.
object
HTTP method (e.g., POST, GET)
Target URI
SHA-256 hash of request body (base64url)
Unique value for replay protection
Examples
Kubernetes ServiceAccount
{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "subject_token": "eyJhbGciOiJSUzI1NiIs...", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "audience": "https://api.target.example.com", "scope": "read:data"}SPIFFE SVID
{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "subject_token": "eyJhbGciOiJSUzI1NiIs...", "subject_token_type": "urn:starfly:token-type:spiffe-svid", "audience": "spiffe://target.example.com"}Execution-scoped token (DPoP-style)
{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "subject_token": "eyJhbGciOiJSUzI1NiIs...", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "audience": "https://api.example.com", "execution_scope": { "htm": "POST", "htu": "https://api.example.com/v1/transfers", "payload_hash": "sha256-abc123", "nonce": "unique-nonce-1" }}Delegation via actor token
{ "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange", "subject_token": "eyJhbGciOiJSUzI1NiIs...", "subject_token_type": "urn:starfly:token-type:agent-a2a", "audience": "https://api.example.com", "actor_token": "eyJhbGciOiJSUzI1NiIs..."}Responses
Section titled “ Responses ”Exchange succeeded
object
WIMSE-compliant JWT
Always “urn:ietf:params:oauth:token-type:jwt”
Always “Bearer”
Token lifetime in seconds (300 standard, 30 execution-scoped)
Example
{ "access_token": "eyJhbGciOiJSUzI1NiIs...", "issued_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_type": "Bearer", "expires_in": 300, "scope": "read:data"}Invalid request or unsupported grant type
object
Error code (RFC 8693 compatible)
Human-readable error detail
Examples
{ "error": "unsupported_grant_type", "error_description": "grant_type must be urn:ietf:params:oauth:grant-type:token-exchange"}{ "error": "invalid_request", "error_description": "unsupported subject_token_type"}Policy denied the exchange
object
Error code (RFC 8693 compatible)
Human-readable error detail
Example
{ "error": "access_denied", "error_description": "policy denied: insufficient blast radius"}Internal server error
object
Error code (RFC 8693 compatible)
Human-readable error detail
Example
{ "error": "invalid_request"}