Skip to main content

Audit log events

The audit log captures a structured record of every state-modifying administrative action in Tetrate Agent Router. Entries are immutable and support compliance frameworks such as SOC 2 and ISO 27001. The wire schema returned by the management API and shown in Admin Console exports is documented here: the fields on every entry, the action and resource vocabulary, and how related rows join.


Event envelope​

Every audit entry mirrors a row of the audit_logs table. The management API exposes that row as AuditLogEntry (JSON field names are camelCase; OpenAPI also documents snake_case titles such as action_type).

FieldTypeDescription
idstringServer-generated audit entry UUID (primary key)
timestampstring (RFC 3339, UTC)When the audited action occurred
createdAtstring (RFC 3339, UTC)When the audit row was persisted (defaults to the event time)
userIdstringId of the user that performed the action; empty for system actions. From 0.9.0, a change made through a console names the signed-in person here, not the console's key (see Who an entry names)
userEmailstringEmail of the acting user, captured at write time. From 0.9.0, set for user and management-key callers
actorTypestringActor category (for example USER, SERVICE, or SYSTEM)
actionTypestringAction performed (for example CREATE, UPDATE, DELETE, CREATE_SECRET, or SET_GUARDRAIL_STATUS)
resourceTypestringType of the affected resource (for example secret, provider, guardrail, or api_key)
resourceIdstringId of the affected resource
successbooleanWhether the action succeeded
statusCodeintegerHTTP status code of the response
errorMessagestringError detail when the action failed; empty on success
sourceIpstringClient IP the request originated from. For a Developer Console call, the address of the console
userAgentstringUser-Agent header of the originating request. From 0.9.0, a Developer Console call carries the browser's User-Agent
httpMethodstringHTTP method of the originating request (for example POST)
endpointstringRequest path or RPC endpoint that triggered the action
correlationIdstringCorrelation id grouping the audit entries that one administrative call produced; distinct from the request X-Request-ID used by data-plane telemetry
metadataobjectAdditional structured context attached to the entry
requestParamsobjectRequest path or query parameters captured for the action
requestBodyobjectRequest body captured for the action (sensitive values may be redacted)
responseDataobjectResponse payload captured for the action

userId, userEmail, and actorType answer who. actionType, resourceType, and resourceId answer what and to which thing. metadata, requestBody, requestParams, and responseData carry operation-specific context. correlationId joins the audit rows produced by one administrative call. It is an audit-scoped identifier, not the request X-Request-ID, so it does not join audit entries to data-plane telemetry such as traces or request logs.

The Admin Console Audit Logs table projects a subset of these fields (timestamp, actor, action, resource, source, and result). The UI may show a human-readable resource label next to resourceId; that label is a presentation detail, not a separate wire field on AuditLogEntry.

Who an entry names​

Both consoles call the management API with a service key. From 0.9.0, an entry names the signed-in person behind such a call rather than the key. The actor is chosen in this order:

  1. The user of the X-Acting-Session-Token header. This header also narrows what the call is allowed to do.
  2. The user of the X-Audit-Session-Token header. This header changes attribution only and grants no access.
  3. Neither header: the caller itself, as before 0.9.0. A call made with a bare management key names the same actor as before, now with its email.

When either header names a person, userId and userEmail name that person and the key ID moves to metadata.via_key. The Developer Console sends X-Audit-Session-Token on its calls from 0.9.0. Admin Console calls that already send X-Acting-Session-Token change the same way: userId changes from the key to the person, and metadata.via_key is added. A data plane report (actor SYSTEM) keeps its actor.

X-Audit-Session-Token is read only on a call made with an admin key; a session or a management key is its own actor, and the header is ignored on those credentials. The token must be a live sign-in session. A token that is not one fails the call with Unauthenticated, and a session of a user from another organization fails it with PermissionDenied.

Developer Console request context​

From 0.9.0, entries for Developer Console calls carry the browser's userAgent, and the X-Forwarded-For chain that the console received in metadata.forwarded_for. sourceIp stays the address of the console. Client addresses are read from metadata.forwarded_for, which is only as trustworthy as the ingress in front of the console.

Metadata keys​

KeyPresent when
metadata.via_keySince 0.9.0. The entry names a person who acted through a key; the value is the key ID
metadata.forwarded_forSince 0.9.0. The call came through the Developer Console; the value is the X-Forwarded-For chain the console received
metadata.phaseOn FINISH_DATAPLANE_UPGRADE: the final phase of the upgrade (Completed, Failed, RolledBack, or Cancelled)

Write guarantees​

From 0.9.0, an entry is written in the same database transaction as the change it records:

  • A failed or refused change leaves one entry with success set to false.
  • An entry that cannot be written is counted in the management plane's audit_write_failures_total metric, labelled by action. The change itself still commits, so an alert on this metric is the way to learn that an entry is missing.
  • Granting or revoking Super Admin is the exception: when its entry cannot be written, the call fails with Internal and changes nothing. Retrying the call is safe.

Action and resource vocabulary​

actionType and resourceType are stable strings that dashboard filters and SIEM consumers use. They are not dotted <resource>.<verb> names.

Action types​

Many mutations use a verb-plus-resource form such as CREATE_SECRET, UPDATE_GUARDRAIL, or DELETE_DATAPLANE. Shorter verbs such as CREATE, UPDATE, DELETE, and UPGRADE also appear. Representative values include:

actionTypeTypical when
CREATE_SECRET / DELETE_SECRET / ROTATE_SECRETSecret lifecycle
CREATE_GUARDRAIL / UPDATE_GUARDRAIL / DELETE_GUARDRAIL / SET_GUARDRAIL_STATUSGuardrail lifecycle and enablement
CREATE_GUARDRAIL_RULE / UPDATE_GUARDRAIL_RULE / DELETE_GUARDRAIL_RULEGuardrail rule changes
CREATE_GUARDRAIL_PROVIDER / UPDATE_GUARDRAIL_PROVIDER / DELETE_GUARDRAIL_PROVIDERGuardrail provider changes
ADD_PROJECT_MODEL / REMOVE_PROJECT_MODELProject model catalog changes
ADD_PROJECT_PROVIDER / REMOVE_PROJECT_PROVIDERProject provider attachment
CREATE_CLIENT_KEY / ADD_CLIENT_KEY / ROTATE_CLIENT_KEY / DISABLE_CLIENT_KEY / ENABLE_CLIENT_KEY / DESTROY_CLIENT_KEYAPI key and client-key lifecycle. From 0.9.0, ROTATE_CLIENT_KEY has resourceType client_key and the client ID as resourceId (before: api_key and the key ID). A legacy key with no client keeps api_key and the key ID until a later release
ISSUE_MY_KEY / REVOKE_MY_KEYA management key issued or revoked by its owner. From 0.9.0, these replace the record the Developer Console wrote itself
CREATE_PROJECT / UPDATE_PROJECT / DELETE_PROJECTProject lifecycle
ADD_PROJECT_MEMBER / UPDATE_PROJECT_MEMBER / REMOVE_PROJECT_MEMBERProject membership
CREATE_DATAPLANE / UPDATE_DATAPLANE / SET_DATAPLANE_PROJECT / DELETE_DATAPLANEData plane lifecycle. From 0.9.0, changes made through the workspace API are recorded too
FINISH_DATAPLANE_UPGRADESince 0.9.0. A data plane upgrade ended. One entry per upgrade, with actor SYSTEM, resourceType dataplane_upgrade, and the final phase in metadata.phase. Only Completed has success set to true
SET_DATAPLANE_URLAn address stored for a data plane through the admin API. Deprecated in 0.7.0, when a data plane declares its hostnames in its own Helm values, so the action becomes rare and stops once no supported data plane predates 0.7.0
QUEUE_DATAPLANE_ZEROIZESince 0.7.0. Deleting a data plane left a zeroize directive for the data plane to collect on its next configuration poll, beside the DELETE_DATAPLANE entry
PROJECT_SERVED_NOWHERESince 0.7.0. The last data plane serving a project stopped serving it: a detach or label removal took the project off its last data plane, or a change landing during a data plane delete left the project unserved. The entry names the project and the data plane. Alert on it, because the project's API keys are accepted nowhere until a data plane serves the project again
SET_DATAPLANE_CONFIG_OVERRIDE / CLEAR_DATAPLANE_CONFIG_OVERRIDESince 0.7.0. A provider address or key set or cleared for one data plane
ACKNOWLEDGE_CONFIG_DIFFERENCESince 0.7.0. An administrator or project owner acknowledged a configuration difference a data plane reported
RESOLVE_DATAPLANE_CREDENTIALSince 0.7.0. A data plane asked for a key override's credential and was refused. Successful resolutions are not recorded
CREATE_PROJECT_GATEWAY / UPDATE_PROJECT_GATEWAY / DELETE_PROJECT_GATEWAYProject gateway lifecycle
SET_PROJECT_GATEWAY_URLA project gateway URL set through the admin API. Deprecated in 0.7.0 together with SET_DATAPLANE_URL
ATTACH_PROJECT_GATEWAY_PROJECT / DETACH_PROJECT_GATEWAY_PROJECTGateway-to-project binding. From 0.9.0, a refused attach leaves an ATTACH_PROJECT_GATEWAY_PROJECT entry with success set to false
CREATE_TELEMETRY_CONFIG / UPDATE_TELEMETRY_CONFIG / DELETE_TELEMETRY_CONFIGTelemetry and SIEM forward configuration. From 0.9.0, project telemetry changes made in the Developer Console are recorded as CREATE_TELEMETRY_CONFIG and UPDATE_TELEMETRY_CONFIG with the configuration ID as resourceId, replacing the console's telemetry.project_config.set and telemetry.project_config.disable entries (which had the project ID)
CREATE_PATTERN / UPDATE_PATTERN / DELETE_PATTERNSince 0.9.0. Guardrail pattern changes
CREATE_FALLBACK_CHAIN_POLICY / UPDATE_FALLBACK_CHAIN_POLICY / DELETE_FALLBACK_CHAIN_POLICY / SET_FALLBACK_CHAIN_POLICY_STATUSFallback policy changes. From 0.9.0, a fallback policy saved through UpsertFallbackPolicy is recorded too
REVOKE_USER_TOKEN / UPSERT_MCP_CATALOG_SERVERToken revocations and MCP catalog entries. From 0.9.0, those a data plane writes are recorded too, as is the data plane URL it sets (SET_DATAPLANE_URL)
UPSERT_SYSTEM_SETTING / UPSERT_PROJECT_SETTING / DELETE_PROJECT_SETTINGSettings changes
AUTHORIZATION_DENIEDSince 0.9.0. A management API call refused for missing permissions on the identity, tenancy, API key, AI key, model catalog, MCP, RBAC, and Developer Console request-log APIs. resourceType is rpc, resourceId is the operation called, and success is false; metadata.customer_id and metadata.project_id hold the customer and project the call named. Refusals on other management API endpoints are not recorded yet

This table is representative, not exhaustive. New management APIs can introduce additional actionType values; filter on observed values from QueryAuditLogs or the Audit Logs UI when building SIEM rules.

Spellings before 0.5.0​

API key entries written before 0.5.0 use an older vocabulary: dotted action names (apikey.create, apikey.update, apikey.rotate, apikey.delete), the resource_type value apikey, and lowercase actor_type values. Entries written before the change keep their old values, and nothing rewrites them, so a SIEM rule that spans the upgrade has to match both vocabularies: the old spellings for historical entries and the tables above for everything written since.

Two more properties of the 0.5.0 change matter to a SIEM consumer:

  • Before 0.9.0, the envelope's four request columns (sourceIp, userAgent, httpMethod, endpoint) are populated for management-plane services only, and entries the Developer Console wrote itself leave them empty. A blank column on such an entry is not a sign the entry was altered. From 0.9.0, Developer Console calls carry the browser's userAgent and metadata.forwarded_for, as described in Developer Console request context.
  • Entries are append-only either side of the boundary: the spelling change is visible as a discontinuity in the values, never as a modified historical row.

Changes in 0.9.0​

Entries written before the upgrade keep their values. A SIEM rule that spans the upgrade accounts for these changes:

  • Actor. Console calls name the signed-in person in userId and userEmail, and the key ID moves to metadata.via_key. A rule matching a console's key ID on the user field moves to metadata.via_key.
  • Failure entries. A refused or failed change leaves one entry with success set to false, so failure counts rise.
  • Newly recorded changes. Workspace API changes, guardrail pattern changes, UpsertFallbackPolicy, refused gateway attaches, data plane upgrade outcomes, and the data plane URL, token revocations, and MCP catalog entries a data plane writes now leave entries.
  • Developer Console entries. The management plane writes the entries for key rotation, management key issue and revoke, and project telemetry changes (ROTATE_CLIENT_KEY, ISSUE_MY_KEY, REVOKE_MY_KEY, CREATE_TELEMETRY_CONFIG, and UPDATE_TELEMETRY_CONFIG), and the console no longer writes its own. Filters on telemetry.project_config.set and telemetry.project_config.disable move to CREATE_TELEMETRY_CONFIG and UPDATE_TELEMETRY_CONFIG, and the resourceType and resourceId of key rotation and telemetry entries change as described in Action types.
  • Data plane upgrades. An upgrade outcome is one FINISH_DATAPLANE_UPGRADE entry with the final phase in metadata.phase.
  • Refused calls. A call refused for missing permissions on the identity, tenancy, API key, AI key, model catalog, MCP, RBAC, and Developer Console request-log APIs leaves an AUTHORIZATION_DENIED entry, so a rule that counts entries per user sees these too.
Two entries for one Admin Console change

Until a later release removes the Admin Console's own audit writes, an Admin Console change that the management API also audits leaves two entries, and both name the signed-in user. For example, a data plane update writes UPDATE from the console and UPDATE_DATAPLANE with metadata.via_key from the management API. To count each change once, keep the entries that carry metadata.via_key and the management API's action names (such as UPDATE_DATAPLANE), or treat two entries with the same user and resource ID a few seconds apart as one change.

Query by subject​

Since 0.5.0, audit queries also take subject_user_id. The two user filters answer different questions: user_id names the admin who performed the action, and subject_user_id names the identity the action was about. Finding every change made by an administrator filters on user_id; finding every change made to a user (their roles, their team, their keys) filters on subject_user_id, whoever performed it.

Search and sort​

From 0.9.0, QueryAuditLogs and QueryPlatformAuditLogs take two optional fields:

FieldBehavior
searchCase-insensitive substring match over the actor's email, user ID, and type, the action, the resource type and ID, the correlation ID, the endpoint, the source IP, and the error message. At most 200 characters; % and _ match as literal text. The total count and statistics apply the search too
order_bySort key: timestamp, actor, action, resource, source, or outcome. Entries that tie on a key other than timestamp are ordered newest first, so pages stay stable

A search that sets no start_time covers the 30 days before end_time (or before now when end_time is unset), starting at the beginning of that UTC day, so every page of one search shares the same window. An explicit start_time always applies. A sort with no search keeps the full time range. With both fields empty, the queries behave as before 0.9.0.

Resource types​

resourceTypeResource family
secretStored secrets
guardrail / guardrail_rule / guardrail_provider / patternGuardrails and guardrail patterns
fallback_chain_policyFallback policies
project / project_member / project_model / project_provider / project_setting / project_mcp_serverProject-scoped resources
project_gatewayProject gateways
dataplaneData planes
dataplane_upgradeData plane upgrades
client / client_keyClients and API keys
user_tokenUser tokens
service_accountService accounts
customerCustomers
telemetry_configTelemetry forward configs
system_settingDeployment-global settings
mcp_routeMCP route status
mcp_catalog_serverMCP catalog entries
rpcA refused management API operation, on AUTHORIZATION_DENIED entries

Example event​

{
"id": "8f14e45f-ceea-467f-a8f0-6b2a1c3d4e5f",
"timestamp": "2026-07-25T19:11:11Z",
"createdAt": "2026-07-25T19:11:11Z",
"userId": "c631d6d5-afb2-41fe-a284-eaf7be377c14",
"userEmail": "[email protected]",
"actorType": "USER",
"actionType": "CREATE_SECRET",
"resourceType": "secret",
"resourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"success": true,
"statusCode": 200,
"errorMessage": "",
"sourceIp": "203.0.113.10",
"userAgent": "Mozilla/5.0",
"httpMethod": "POST",
"endpoint": "/v1/secrets",
"correlationId": "corr-7c9e6679-7425-40de-944b-e07fc1f90ae7",
"metadata": {
"name": "0-salesforce"
},
"requestParams": {},
"requestBody": {},
"responseData": {}
}

Sensitive values in requestBody, responseData, and metadata may be redacted. Credential material is not written in cleartext to the audit log.


Coverage and immutability​

  • Coverage. Every state-modifying administrative action generates an audit event. There is no path through the Admin Console that changes Agent Router state without leaving a record. From 0.9.0, the event is written in the same transaction as the change, and an event that cannot be written is counted (see Write guarantees).
  • Immutability. Audit entries cannot be edited or deleted by any user, regardless of role. There is no "delete from the log" operation anywhere in Agent Router. Signed Merkle checkpoints support tamper-evidence for sealed windows of the log; see the Admin API's audit checkpoint operations.

Retention is configured per deployment. For long-horizon retention beyond the in-Console window, the audit stream is exported to an external SIEM or log store; see Export audit decisions to SIEM.