Skip to main content
Every call to POST /v1/authorize creates an immutable audit log entry. The audit log gives you a complete record of what your agents tried to do, what was allowed or denied, and why.

Audit log entries

interface AuditLogEntry {
  id: string;
  agentId: string;
  action: string;
  toolName: string;
  parameters: Record<string, unknown>;
  result: "allowed" | "denied";
  policyId: string | null;
  reason: string;
  latencyMs: number;
  timestamp: string;
}
Each entry captures:
FieldDescription
agentIdThe agent that made the request
toolNameThe tool the agent attempted to call
parametersThe parameters passed with the call (sensitive values redacted)
resultThe authorization outcome: allowed or denied
policyIdThe policy that produced the decision, or null if default deny
reasonA human-readable explanation of the decision
latencyMsTime taken to evaluate the request, in milliseconds
timestampWhen the authorization request was received (ISO 8601)

Sensitive parameter redaction

Before parameters are written to the audit log, Veto automatically redacts values whose keys match any of the following patterns: password, secret, token, key, credential, authorization, api_key, apiKey, access_token, refresh_token Matched values are replaced with "[REDACTED]". This applies to both top-level keys and nested object keys.

Example log entry

{
  "id": "log_01j9xkqp4c8tz6wm3r7nvs5b",
  "agentId": "agt_01j9xkqp4c8tz6wm3r7nvs5a",
  "action": "authorize",
  "toolName": "file.write",
  "parameters": {
    "path": "/tmp/output.txt",
    "content": "Hello, world!",
    "api_key": "[REDACTED]"
  },
  "result": "denied",
  "policyId": "pol_01j9xkqp4c8tz6wm3r7nvs5c",
  "reason": "Parameter \"path\" value \"/tmp/output.txt\" does not match pattern /^\\/home\\//",
  "latencyMs": 12,
  "timestamp": "2026-04-08T14:32:01.000Z"
}

Append-only

The audit log is append-only. Entries cannot be deleted or modified via the API. This ensures your audit trail is tamper-evident and suitable for compliance purposes.

Querying the audit log

Use the Node.js SDK or the API to filter and page through audit log entries.
import { VetoClient } from "@useveto/node";

const veto = new VetoClient({ apiKey: process.env.VETO_API_KEY! });

const logs = await veto.queryAuditLog({
  agentId: "agt_01j9xkqp4c8tz6wm3r7nvs5a",
  result: "denied",
  limit: 50,
});

console.log(logs.data);          // array of AuditLogEntry
console.log(logs.pagination);    // { limit, offset, count, total }
Available filters:
FilterTypeDescription
agentIdstringOnly entries for this agent
toolNamestringOnly entries for this tool name (exact match)
result"allowed" | "denied"Filter by outcome
fromISO date stringEntries at or after this timestamp
toISO date stringEntries at or before this timestamp
limitnumberNumber of entries to return
offsetnumberPagination offset
Results are always returned in reverse chronological order (newest first).

Exporting to CSV

You can export audit log entries as a CSV file via GET /v1/audit-logs/export. The export supports the same filters as the query endpoint and returns up to 5,000 rows per request. The CSV includes the following columns: Timestamp, Agent ID, Tool, Result, Reason, Latency (ms), Parameters.
If the export is truncated because there are more than 5,000 matching entries, the response includes an X-Veto-Export-Truncated: true header. Narrow your filters (for example, reduce the date range) to export the full dataset in multiple requests.

Dashboard

The Veto dashboard provides a searchable, filterable view of your audit log. You can filter by agent, tool name, result, and date range without writing any code.