Search the Token Exchange Audit Log API

On this page

Enterprise plan To use Token Exchange, you'll need an Enterprise plan.

Available since 1.70.0

FusionAuth writes a Token Exchange audit log entry for every token exchange attempt, successful or not. This API searches and paginates through those entries. To retrieve the chain of exchanges behind a single issued token, use the Retrieve a Token Exchange Chain API.

FusionAuth deletes entries after the number of days set in systemConfiguration.tokenExchangeAuditLogConfiguration.numberOfDaysToRetain in the System Configuration. The default is 7 days.

Request#

API Key Authentication
Searches the Token Exchange audit log using the given search criteria
GET/api/system/token-exchange-audit-log/search?exchangerClientId={exchangerClientId}&outcome={outcome}&start={start}&end={end}

When calling the API using a GET request, send the search criteria as query parameters. The example URL doesn't show every parameter, but any of the documented query parameters can be added to the URL.

Use a POST request to send the search criteria in a JSON request body instead.

API Key Authentication
Searches the Token Exchange audit log using the given search criteria
POST/api/system/token-exchange-audit-log/search

Query Parameters#

end
  • Type: Long
  • Optional

The end instant of the date/time range to search within.

exchangerClientId
  • Type: UUID
  • Optional

The Id of the exchanger Entity. Despite the name, this value is the Entity's Id, not its OAuth client Id.

numberOfResults
  • Type: Integer
  • Optional
  • Defaults to 25

The number of results to return from the search.

orderBy
  • Type: String
  • Optional
  • Defaults to insertInstant DESC, eventId DESC

The column to order the search results on plus the order direction. The possible columns are eventId and insertInstant. For example, insertInstant ASC returns the oldest entries first.

outcome
  • Type: String
  • Optional

The outcome of the exchange attempt. See tokenExchangeAuditLogs[x].outcome in the response body for the possible values.

start
  • Type: Long
  • Optional

The start instant of the date/time range to search within.

startRow
  • Type: Integer
  • Optional
  • Defaults to 0

The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.

tenantId
  • Type: UUID
  • Optional

Restricts the results to entries belonging to the given Tenant. This parameter is overridden if the request contains an X-FusionAuth-TenantId header, or if the API key is scoped to a specific Tenant.

Request Body#

The request body accepts the same fields as the query parameters, nested in a search object. For example, search.outcome corresponds to the outcome query parameter.

Example JSON Request
{
  "search": {
    "exchangerClientId": "4b8f3b1a-6c2d-4f0e-9a7b-2d1c3e4f5a6b",
    "outcome": "POLICY_DENIED",
    "start": 1792592000000,
    "end": 1792678400000,
    "numberOfResults": 50
  }
}

Response#

The response for this API contains the entries matching the search criteria in reverse chronological order.

Response Codes
CodeDescription
200The request was successful. The response will contain a JSON body.
400The request was invalid and/or malformed. The response will contain an Errors JSON Object with the specific errors. This status will also be returned if a paid FusionAuth license is required and is not present.
401You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See Authentication.
500There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty.
503The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body.

Response Body#

tokenExchangeAuditLogs
  • Type: Array

The entries matching the search criteria.

tokenExchangeAuditLogs[x].actChain
  • Type: String

The act claim of the issued token, serialized as a JSON string. Only present when FusionAuth issued a token.

tokenExchangeAuditLogs[x].delegationSemantics
  • Type: String

The kind of exchange. This value is always DELEGATION. Only present when FusionAuth issued a token.

tokenExchangeAuditLogs[x].eventId
  • Type: UUID

The unique Id of the entry.

tokenExchangeAuditLogs[x].exchangerClientId
  • Type: UUID

The Id of the exchanger Entity. Absent when client authentication failed for an unknown client.

tokenExchangeAuditLogs[x].grantedAudience
  • Type: String

The space-delimited audiences of the issued token.

tokenExchangeAuditLogs[x].grantedScope
  • Type: String

The space-delimited scopes of the issued token.

tokenExchangeAuditLogs[x].insertInstant
  • Type: Long

The instant when FusionAuth recorded the attempt.

tokenExchangeAuditLogs[x].intent
  • Type: String

The value of the intent request parameter.

tokenExchangeAuditLogs[x].issuedTokenJti
  • Type: String

The jti claim of the issued token.

tokenExchangeAuditLogs[x].outcome
  • Type: String

The outcome of the attempt. The possible values are:

  • CLIENT_AUTHENTICATION_FAILED: the exchanger's client credentials were invalid.
  • CLIENT_DISALLOWED: the exchanger Entity doesn't have actAsTokenExchangeClient enabled.
  • CLIENT_REQUEST_FAILURE: the request parameters were invalid.
  • DEPTH_EXCEEDED: the subject token's actor chain already reached the Tenant's maximum depth.
  • POLICY_DENIED: the policy engine denied the exchange.
  • POLICY_LAMBDA_ERROR: the Token Exchange Policy lambda failed or returned an invalid result.
  • POPULATE_LAMBDA_ERROR: the Token Exchange Populate lambda failed.
  • SUBJECT_TOKEN_INVALID: the subject token failed validation.
  • SUCCESS: FusionAuth issued a token.
  • TENANT_DISALLOWED: the Tenant doesn't have token exchange enabled.
  • WEBHOOK_FAILURE: a webhook failed to accept the token.exchange event, so FusionAuth didn't return the token.
tokenExchangeAuditLogs[x].policyDecision
  • Type: String

The decision of the policy engine. The possible values are ALLOW, DENY, and ERROR. Only present when the policy engine ran.

tokenExchangeAuditLogs[x].policyDecisionDurationMs
  • Type: Integer

The time in milliseconds the policy engine took to decide. Only present when the policy engine ran.

tokenExchangeAuditLogs[x].policyEngine
  • Type: String

The policy engine that evaluated the exchange. The possible values are ENTITY and LAMBDA. Only present when the policy engine ran.

tokenExchangeAuditLogs[x].requestedAudience
  • Type: String

The space-delimited values of the audience and resource request parameters.

tokenExchangeAuditLogs[x].subjectTokenIss
  • Type: String

The iss claim of the subject token.

tokenExchangeAuditLogs[x].subjectTokenJti
  • Type: String

The jti claim of the subject token.

tokenExchangeAuditLogs[x].subjectTokenSub
  • Type: String

The sub claim of the subject token.

tokenExchangeAuditLogs[x].subjectTokenType
  • Type: String

The value of the subject_token_type request parameter.

tokenExchangeAuditLogs[x].subjectTokenValidationStatus
  • Type: String

How FusionAuth validated the subject token. The possible values are AUTHORITATIVE, BEST_EFFORT, and FAILED. Absent when the attempt failed before FusionAuth validated the subject token.

tokenExchangeAuditLogs[x].tenantId
  • Type: UUID

The Id of the Tenant that processed the exchange.

total
  • Type: Long

The total number of entries matching the search criteria. Use this value with numberOfResults and startRow to paginate.

Example JSON Response
{
  "tokenExchangeAuditLogs": [
    {
      "actChain": "{\"sub\":\"todo-service\",\"sub_profile\":\"fusionauth:API Service\"}",
      "delegationSemantics": "DELEGATION",
      "eventId": "e7d9b3f0-8c2a-4d1b-9e6f-1a2b3c4d5e6f",
      "exchangerClientId": "4b8f3b1a-6c2d-4f0e-9a7b-2d1c3e4f5a6b",
      "grantedAudience": "email-service",
      "grantedScope": "openid offline_access",
      "insertInstant": 1792680000000,
      "issuedTokenJti": "6b3a7d1e-4c8f-4b2a-9e55-0f1c2d3e4a5b",
      "outcome": "SUCCESS",
      "policyDecision": "ALLOW",
      "policyDecisionDurationMs": 4,
      "policyEngine": "ENTITY",
      "requestedAudience": "email-service",
      "subjectTokenIss": "https://piedpiper.fusionauth.io",
      "subjectTokenJti": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
      "subjectTokenSub": "c0a6ae6c-6d38-4bb5-a7c2-4d2b4e3a1f2d",
      "subjectTokenType": "urn:ietf:params:oauth:token-type:access_token",
      "subjectTokenValidationStatus": "AUTHORITATIVE",
      "tenantId": "30663132-6464-6665-3032-326466613934"
    }
  ],
  "total": 1
}