On this page

Audit Log

Every outbound call from your sandbox is recorded automatically. No setup. The Audit Log tab on each sandbox/computer is the source of truth for “what did my workload actually do on the network?”

What’s in each row

ColumnDescription
timestampWhen the request happened (microsecond precision)
hostUpstream hostname
methodGET, POST, PUT, …
pathURL path (query string redacted)
actionallow, reject, stub, error, client_cancel
status_codeUpstream response code (or 0 if no response)
duration_msWall-clock time
bytes_in / bytes_outVolume
request_transformsWhich transforms fired (secrets, allowlist, header allowlist, …)
mcpMCP message trace, when the call was an MCP JSON-RPC request

Live tail

The Audit Log tab streams new events in real time over WebSocket. New rows appear at the top as your sandbox makes calls.

Filtering

In the UI, use the filter bar to scope by:

  • Time range - last hour, 24h, 7d, 30d, custom
  • Host - exact or wildcard
  • HTTP method
  • Action - show only blocked, only allowed, only errors
  • Transform - show only requests that swapped a particular secret, or only MCP tool calls
  • Status code - show only 4xx, only 5xx, etc.

All filters are URL-shareable.

From the SDK

Common queries

“Why did this fail?”

Filter by action=reject for the last hour. Each row tells you which rule blocked it (rejected_by column).

“Which secret did this request use?”

Each row’s request_transforms JSON includes a secrets entry listing the secret names swapped. UI surfaces this in the detail drawer; SDK exposes it as event.request_transforms.secrets.swapped.

“What did our AI agent do last quarter?”

Tenant-admin filter by date range and resource type. Export CSV.

“Show me all calls by Dr. Smith”

For white-label deployments, filter by external_user_id. See White-label Credentials.

Export

Every filtered view can be exported as CSV or JSON via the “Export” button (UI) or the SDK:

sandbox.audit.export(since="30d", format="csv", path="audit-30d.csv")

Retention

PlanRetention
All plans (default)90 days
Custom retention (longer)available on enterprise plans

Beyond the retention window, rows are deleted from egress_audit. Export your data if you need a longer record.

Programmatic alerting (Phase 5)

You’ll be able to wire saved queries into alerting:

“Notify me if any sandbox makes more than 100 requests to a never-before-seen host in 5 minutes.”

This ships in Phase 5 of the Security rollout.

Real-world example - compliance dashboard for a multi-tenant healthcare app

You’re building a healthcare SaaS where each clinician uses a sandbox. Compliance requires you to surface all outbound calls per clinician in your own dashboard, with the ability to export a 30-day report.

Troubleshooting

Audit log is empty even though the sandbox is running. The audit log only records outbound calls from the sandbox. If the sandbox is just waiting for input or doing in-process computation with no network calls, no rows appear. Trigger an outbound call and re-query.

audit.tail() disconnects after a few seconds. Tail connections are kept alive with WebSocket pings. If your network has a short idle-connection timeout, the connection can drop. Reconnect in your retry loop:

while True:
    try:
        for event in sandbox.audit.tail():
            process(event)
    except ConnectionError:
        time.sleep(1)  # reconnect

request_transforms.secrets.swapped is empty - but I have secrets bound. If the sandbox’s env var contains the real key (e.g., from a .env file that overrode the placeholder), the proxy has nothing to swap. Run sandbox.exec("echo $OPENAI_API_KEY") - if it prints the real sk-proj-... instead of miosa-tok-..., the .env file is winning.

Tenant-wide client.audit.list() returns too many rows. Narrow with external_user_id, external_workspace_id, host, or action filters. Maximum limit per call is 1000. For larger exports, use audit.export().

I need audit rows older than 90 days. Default retention is 90 days. For longer retention, contact support to enable custom retention on your tenant. Export regularly if you need a permanent archive.

For more issues, see the Security troubleshooting hub.

Frequently asked

Does the audit log capture request bodies? Not by default - only headers (redacted) and metadata. You can opt in to body capture per-resource if you need it for compliance, with a “may contain sensitive data” warning.

Are response bodies captured? No. Audit is request-side only.

Can I disable the audit log entirely? No - audit is the platform baseline. You can shorten retention but not disable it.

Will live-tail consume my plan’s API quota? No. Audit streaming is over a WebSocket and doesn’t count against REST API rate limits.

Was this helpful?