Token Exchange Event

On this page

Token Exchange

Enterprise plan required

This feature requires an Enterprise plan.

Available since 1.70.0

This event is generated for every token exchange attempt, successful or not. FusionAuth sends it before returning a token. If a webhook fails to accept this event, FusionAuth rejects the exchange with a server_error and records the attempt with the WEBHOOK_FAILURE outcome.

Event type

token.exchange

Event Scope

This is a tenant-scoped event.

It can be sent to all tenants or to one or more specified tenants. However, those tenants will not be sent events for other tenants, but only events related to themselves.

Transaction Compatibility

This event is transactional. The final state of the operation which caused the webhook is not persisted to FusionAuth until after the webhook finishes; learn more

See OAuth Token Exchange for how FusionAuth processes an exchange. The event carries the same information as the Token Exchange audit log entry for the attempt.

Event Body

event.actChain
  • Type: Object

The act claim of the issued token. Only present when FusionAuth issued a token.

event.createInstant
  • Type: Long

The instant that the event was generated.

event.exchangerClientId
  • Type: UUID

The Id of the exchanger Entity. Despite the name, this value is the Entity's Id, not its OAuth client Id. Absent when client authentication failed for an unknown client.

event.id
  • Type: UUID

The unique Id of the event. Depending on transaction settings, a webhook can receive the same event more than once. Use this Id to detect duplicates.

event.info.data
  • Type: Object

An object that can hold any information about the event that should be persisted.

event.info.deviceDescription
  • Type: String

The description of the device associated with the event.

event.info.deviceName
  • Type: String

The device name associated with the event.

event.info.deviceType
  • Type: String

The type of device associated with the event.

event.info.ipAddress
  • Type: String

The source IP address of the event.

event.info.location.city
  • Type: String

The city where the event originated.

Enterprise plan To use event location data, you'll need an Enterprise plan.

event.info.location.country
  • Type: String

The country where the event originated.

Enterprise plan To use event location data, you'll need an Enterprise plan.

event.info.location.latitude
  • Type: Double

The latitude where the event originated.

Enterprise plan To use event location data, you'll need an Enterprise plan.

event.info.location.longitude
  • Type: Double

The longitude where the event originated.

Enterprise plan To use event location data, you'll need an Enterprise plan.

event.info.location.region
  • Type: String

The geographic location where the event originated.

Enterprise plan To use event location data, you'll need an Enterprise plan.

event.info.location.zipcode
  • Type: String

The zip code where the event originated.

Enterprise plan To use event location data, you'll need an Enterprise plan.

event.info.os
  • Type: String

The operating system associated with the event.

event.info.userAgent
  • Type: String

The user agent associated with the event.

event.intent
  • Type: String

The value of the intent request parameter.

event.issuedToken
  • Type: Object

Information about the issued token. Only present when FusionAuth issued a token.

event.issuedToken.delegationSemantics
  • Type: String

The kind of exchange. This value is always DELEGATION.

event.issuedToken.grantedAudience
  • Type: Array<String>

The audiences of the issued token.

event.issuedToken.grantedScope
  • Type: String

The space-delimited scopes of the issued token.

event.issuedToken.jti
  • Type: String

The jti claim of the issued token.

event.outcome
  • Type: String

The outcome of the attempt. See the Token Exchange audit log for the possible values.

event.policy
  • Type: Object

Information about the policy engine's decision. Only present when the policy engine ran.

event.policy.decision
  • Type: String

The decision of the policy engine. The possible values are ALLOW, DENY, and ERROR.

event.policy.decisionDurationMs
  • Type: Integer

The time in milliseconds the policy engine took to decide.

event.policy.engine
  • Type: String

The policy engine that evaluated the exchange. The possible values are ENTITY and LAMBDA.

event.requestedAudience
  • Type: Array<String>

The values of the audience and resource request parameters.

event.subjectToken
  • Type: Object

Information about the subject token. When an attempt fails before FusionAuth validates the subject token, this object only contains type and, for some failures, validationStatus.

event.subjectToken.iss
  • Type: String

The iss claim of the subject token.

event.subjectToken.jti
  • Type: String

The jti claim of the subject token.

event.subjectToken.sub
  • Type: String

The sub claim of the subject token.

event.subjectToken.type
  • Type: String

The value of the subject_token_type request parameter.

event.subjectToken.validationStatus
  • Type: String

How FusionAuth validated the subject token. The possible values are AUTHORITATIVE, BEST_EFFORT, and FAILED.

event.tenantId
  • Type: UUID

The unique Id of the Tenant that processed the exchange.

event.type
  • Type: String

The event type. This value is always token.exchange.

Example Event JSON
{
  "event": {
    "actChain": {
      "sub": "todo-service",
      "sub_profile": "fusionauth:API Service"
    },
    "createInstant": 1792680000123,
    "exchangerClientId": "4b8f3b1a-6c2d-4f0e-9a7b-2d1c3e4f5a6b",
    "id": "2ed2a35c-eff5-41b4-822d-ba1b85d814c4",
    "info": {
      "ipAddress": "10.0.0.12",
      "userAgent": "Java HttpClient"
    },
    "intent": "send-reminder-email",
    "issuedToken": {
      "delegationSemantics": "DELEGATION",
      "grantedAudience": [
        "email-service"
      ],
      "grantedScope": "openid offline_access",
      "jti": "6b3a7d1e-4c8f-4b2a-9e55-0f1c2d3e4a5b"
    },
    "outcome": "SUCCESS",
    "policy": {
      "decision": "ALLOW",
      "decisionDurationMs": 4,
      "engine": "ENTITY"
    },
    "requestedAudience": [
      "email-service"
    ],
    "subjectToken": {
      "iss": "https://piedpiper.fusionauth.io",
      "jti": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
      "sub": "c0a6ae6c-6d38-4bb5-a7c2-4d2b4e3a1f2d",
      "type": "urn:ietf:params:oauth:token-type:access_token",
      "validationStatus": "AUTHORITATIVE"
    },
    "tenantId": "30663132-6464-6665-3032-326466613934",
    "type": "token.exchange"
  }
}