You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2cf565a
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: apps/docs/content/docs/platform/enterprise/audit-logs.mdx
+16-8Lines changed: 16 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
title: Audit Logs
3
-
description: Track every action taken across your organization's workspaces
3
+
description: Track configuration and security events across your organization's workspaces
4
4
---
5
5
6
6
import { FAQ } from'@/components/ui/faq'
@@ -44,7 +44,7 @@ X-API-Key: <api-key>
44
44
|`resourceType`| string | Filter by resource type (e.g. `workflow`) |
45
45
|`resourceId`| string | Filter by a specific resource ID |
46
46
|`workspaceId`| string | Filter by workspace |
47
-
|`actorId`| string | Filter by user ID. For organization-wide filters, the actor must be a current or former org member; workspace-scoped logs can also include external workspace members. |
47
+
|`actorId`| string | Filter by a current organization member’s user ID. For a departed-actor filter, use the CSV export with `includeDeparted=true`. |
48
48
|`startDate`| string | ISO 8601 date — return logs on or after this date |
49
49
|`endDate`| string | ISO 8601 date — return logs on or before this date |
50
50
|`includeDeparted`| boolean | Include logs from members who have since left the organization (default `false`) |
@@ -84,7 +84,7 @@ X-API-Key: <api-key>
84
84
85
85
Paginate by passing the `nextCursor` value as the `cursor` parameter in the next request. When `nextCursor` is absent, you have reached the last page. Each entry also includes `actorName`; `metadata` is an arbitrary per-action JSON object. The `limits` object reports your current rate-limit and usage status.
86
86
87
-
The API accepts both personal and workspace-scoped API keys. Rate limits apply — the response includes `X-RateLimit-*` headers with your current limit and remaining quota.
87
+
The organization audit API requires a personal API key belonging to an organization owner or admin. Workspace API keys are refused. Rate limits apply — the response includes `X-RateLimit-*` headers with your current limit and remaining quota.
88
88
89
89
---
90
90
@@ -94,6 +94,7 @@ Audit log events follow a `resource.action` naming pattern. The table below list
|**Exports and drains**|`audit_logs.exported`, `data_drain.created`, `data_drain.updated`, `data_drain.ran`, `data_drain.tested`|
109
+
110
+
Authentication failures and password-reset requests use an anonymous actor and identify the target account separately. Impersonation and administrative session revocations identify the operator and the target organization. Table-row mutations record operation summaries and counts without copying row contents.
111
+
112
+
Most audit writes are best effort: a database outage or process loss can prevent persistence even when the underlying action succeeds. Deployment activation uses an awaited, idempotent audit insert before its outbox checkpoint. Audit logs are not a complete tool-invocation stream or a transactionally guaranteed ledger for every operation.
113
+
114
+
Organization visibility depends on current workspace ownership or stored organization attribution. Older workspace events without organization metadata may no longer appear in organization queries after the workspace is physically deleted.
107
115
108
116
Workspace invitation events include whether the invite is for an internal organization member or an external workspace member in their metadata. External workspace members can appear as actors on workspace-scoped events, and appear in the roster with an External label without becoming organization members.
109
117
@@ -116,23 +124,23 @@ Workspace invitation events include whether the invite is for an internal organi
116
124
},
117
125
{
118
126
question: "Are audit logs tamper-proof?",
119
-
answer: "Audit log entries are append-only and cannot be modified or deleted through the Sim interface or API. They represent a reliable record of actions taken in your organization."
127
+
answer: "The Sim interface and API do not provide audit-entry edits or deletion. Database administrators can still alter stored records, and entries are not cryptographically sealed. Use a data drain to archive them under your own storage and retention controls."
120
128
},
121
129
{
122
130
question: "Can I export audit logs?",
123
-
answer: "Yes. Use the API to export logs programmatically. Paginate through all records using the cursor parameter and store them in your own data warehouse or SIEM."
131
+
answer: "Yes. Download CSV from the audit viewer or paginate the API for your SIEM. CSV includes event, workspace, resource and actor IDs, IP address, user agent, surface and metadata. Organization administrators can include departed actors for historical investigations. CSV downloads are recorded in the audit trail and capped at 10,000 rows or 64 MB; the X-Export-Truncated header indicates a partial export. For continuous delivery, use an audit-log data drain."
124
132
},
125
133
{
126
134
question: "Are logs scoped to a single workspace or the whole organization?",
127
135
answer: "Audit logs are scoped to your organization and include activity across all workspaces within it. You can filter by workspaceId to narrow results to a specific workspace."
128
136
},
129
137
{
130
138
question: "What information is included in each log entry?",
131
-
answer: "Each entry includes the event type, a description, the actor's name and email, the affected resource, the workspace, and a timestamp. IP addresses and user agents are not exposed through the API."
139
+
answer: "Each entry includes the event type, a description, the actor's name and email, the affected resource, the workspace, and a timestamp. The JSON API omits IP addresses and user agents; authorized CSV exports and audit-log drains include them."
132
140
},
133
141
{
134
142
question: "Can I filter logs by a specific user?",
135
-
answer: "Yes. Pass the actorId query parameter to filter logs by a specific user. Organization-wide actor filters require the actor to be a current or former member of your organization. Workspace-scoped logs may also include external workspace members who acted inside a workspace without joining the organization."
143
+
answer: "Yes. The JSON API accepts actorId for current organization members. CSV exports also support departed actors when includeDeparted=true. Workspace-scoped logs may include external workspace members who acted inside a workspace without joining the organization."
Copy file name to clipboardExpand all lines: apps/docs/content/docs/platform/enterprise/data-drains.mdx
+13-11Lines changed: 13 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ description: Continuously export workflow logs, audit logs, and Chat data to you
6
6
import { FAQ } from'@/components/ui/faq'
7
7
import { Image } from'@/components/ui/image'
8
8
9
-
Data Drains let organization owners and admins on Enterprise plans continuously export Sim data to a destination they control — a customer-owned S3 bucket, Google Cloud Storage bucket, Azure Blob container, BigQuery table, Snowflake table, Datadog logs intake, or an HTTPS webhook. A drain runs on a schedule, picks up only new rows since its last successful run, and writes them to the destination. Viewing drain configuration and run history is restricted to owners and admins as well, since destinations expose internal bucket names, table identifiers, and webhook URLs.
9
+
Data Drains let organization owners and admins on Enterprise plans continuously export Sim data to a destination they control — a customer-owned S3 bucket, Google Cloud Storage bucket, Azure Blob container, BigQuery table, Snowflake table, Datadog logs intake, or an HTTPS webhook. A drain runs on a schedule, picks up rows after its last acknowledged delivery, and writes them to the destination. Viewing drain configuration and run history is restricted to owners and admins as well, since destinations expose internal bucket names, table identifiers, and webhook URLs.
10
10
11
11
Drains are independent of [Data Retention](/platform/enterprise/data-retention) but designed to compose with it — see [Pairing with Data Retention](#pairing-with-data-retention) below.
12
12
@@ -38,12 +38,12 @@ A drain exports exactly one source. To export multiple sources, create multiple
38
38
|**Workflow logs**| Workflow execution records (one row per execution, only after the run reaches a terminal state). |
39
39
|**Job logs**| Background job records (deployed APIs, schedules, webhooks). Only terminal-state rows are exported. |
|**Chat runs**| Chat run records (terminal state only). |
41
+
|**Chats**| Chat snapshots, including organization-owned chats outside a workspace. |
42
+
|**Chat runs**| Chat run records (terminal state only), with safe correlation context. Internal controller tokens and billing recovery receipts are excluded. |
43
43
44
44
Each row is delivered as a single line of NDJSON. The shape of each row is part of the public schema and stable across versions; every row carries an `id` field that downstream consumers can use to dedupe.
45
45
46
-
Drains select new rows by their creation cursor and deliver them at least once. A failed run can deliver a row again, so consumers should deduplicate by its `id`. Mutable fields on **Chats** (messages, title, `lastSeenAt`) are a point-in-time snapshot and won't be re-emitted if the chat is later updated. Treat the export as append-only and reconstitute current state from your own system of record if you need it.
46
+
Workflow, job, and Chat run drains advance by their terminal timestamp; audit and Chat drains advance by creation time. A new drain exports all retained history. Reads use the primary database and leave a five-minute stability window before selecting new records. This reduces late-commit gaps but is not a change-data-capture guarantee. Drains deliver rows at least once. A failed run can deliver a row again, so consumers should deduplicate by its `id`. Mutable fields on **Chats** (messages, title, `lastSeenAt`) are a point-in-time snapshot and won't be re-emitted if the chat is later updated. Treat the export as append-only and reconstitute current state from your own system of record if you need it.
47
47
48
48
---
49
49
@@ -111,7 +111,7 @@ Inserts each row into a target VARIANT column via the Snowflake SQL API v2 with
111
111
-**Role***(optional)* — Snowflake role to assume.
112
112
-**Private key (PEM)** — PKCS8-encoded RSA private key. Register the matching public key on the Snowflake user via `ALTER USER ... SET RSA_PUBLIC_KEY = '...'`.
113
113
114
-
Each chunk becomes a single `INSERT INTO "DB"."SCHEMA"."TABLE" ("col") VALUES (PARSE_JSON(?)), ...` with one TEXT binding per row. Identifiers are quoted to preserve case. The destination handles Snowflake's async 202-then-poll pattern transparently. Per-row JSON payloads are capped at 16 MB to match Snowflake's VARIANT limit.
114
+
Each chunk becomes a single `INSERT INTO "DB"."SCHEMA"."TABLE" ("col") SELECT PARSE_JSON(column1) FROM VALUES (?), ...` with one TEXT binding per row. Identifiers are quoted to preserve case. The destination handles Snowflake's async 202-then-poll pattern transparently. Per-row JSON payloads are capped at 16 MB to match Snowflake's VARIANT limit.
115
115
116
116
### Datadog Logs
117
117
@@ -122,7 +122,7 @@ POSTs each row as a log entry to Datadog's v2 logs intake.
122
122
-**Tags***(optional)* — comma-separated `ddtags` appended to every entry alongside auto-injected `sim_drain_id:`, `sim_run_id:`, and `sim_source:` tags.
123
123
-**API key** — a Datadog API key (not an Application key) with logs-write permission.
124
124
125
-
Top-level row fields are auto-indexed as Datadog log attributes. The reserved fields `ddsource`, `service`, `ddtags`, and `message` are always set by Sim and override anything in the row. Payloads above 1 KB are gzip-compressed. Enforced limits match Datadog's intake: 5 MB per request (post-compression), 1000 entries per request, 1 MB per entry.
125
+
Top-level row fields are auto-indexed as Datadog log attributes. The reserved fields `ddsource`, `service`, `ddtags`, and `message` are always set by Sim and override anything in the row. Payloads above 1 KB are gzip-compressed. Enforced limits match Datadog's intake: 5 MB of uncompressed JSON per request, 1000 entries per request, and 1 MB per entry. Expanded log entries are split into bounded requests before compression.
126
126
127
127
### HTTPS Webhook
128
128
@@ -168,9 +168,11 @@ You can also disable a drain with the **Enabled** toggle (it stops running but i
168
168
169
169
## Delivery semantics
170
170
171
-
Drains use an **opaque cursor** that advances only on full success. If a delivery fails partway through a run, the cursor is unchanged and the next run replays from the last successful position.
171
+
Drains use an **opaque cursor** that checkpoints each acknowledged chunk. If a later chunk fails, the next run resumes after the last acknowledged checkpoint. A crash between remote delivery and checkpointing can replay a chunk.
172
172
173
-
This is **at-least-once delivery**. Combined with the `id` field on every row and the `Idempotency-Key` header on every webhook chunk, downstream systems can dedupe deterministically.
173
+
A database claim prevents overlapping runs for the same drain and fences stale workers. Each run is bounded to 10,000 rows, 100 chunks, 100 MB of NDJSON, and a 20-minute work window, with a 25-minute hard deadline. A queued run that reaches a window limit schedules a continuation. Chunks are capped at 4 MB; individual database records, chat transcripts, and execution archives are capped at 1 MB before materialization. Oversized records fail visibly without advancing past them. Missing execution archives also fail rather than reporting an incomplete record as delivered.
174
+
175
+
This is **at-least-once delivery**. Deduplicate by the source row’s `id`. The webhook `Idempotency-Key` protects retries of a chunk within one run; a replay in a later run has a new run ID. A destination that partially accepts a request may also repeat previously accepted rows on retry.
174
176
175
177
The **last 10 runs** for each drain are visible by expanding its row in the settings page, with status, row count, bytes written, destination locator (`s3://...` or webhook URL), and the error message if it failed.
176
178
@@ -180,7 +182,7 @@ The **last 10 runs** for each drain are visible by expanding its row in the sett
180
182
181
183
- Destination credentials are encrypted at rest using the same key-rotation–aware encryption that protects OAuth tokens.
182
184
- Credentials are **never** returned by the Sim API after creation. Updates accept new credentials; omitting them leaves the existing encrypted blob in place.
183
-
- Webhook URLs are SSRF-validated: HTTPS-only, no private/loopback/metadata IPs, with the resolved IP pinned to defeat DNS rebinding.
185
+
- Webhook URLs and the final S3 SDK hostname are SSRF-validated with the resolved IP pinned to the connection. Private, loopback, and metadata IPs are rejected. S3 signed request paths are preserved without following redirects. A configured outbound gateway that cannot preserve signed request targets fails closed.
184
186
- Every create, update, delete, manual run, and test-connection call is recorded in the [Audit Log](/platform/enterprise/audit-logs).
185
187
186
188
---
@@ -218,7 +220,7 @@ After data lands in your bucket or webhook system, archive lifecycle (transition
218
220
},
219
221
{
220
222
question: "What happens if my credentials stop working mid-run?",
221
-
answer: "The run fails, the drain cursor does not advance, and the failed run is recorded with the error. Once you fix the credentials with an Update or by re-creating the drain, the next run replays from where the last successful run left off."
223
+
answer: "The run failsand is recorded with the error. Already acknowledged chunks retain their checkpoints. Once you update the credentials, the next run resumes from the last acknowledged position; an uncheckpointed delivery may be repeated."
Each due drain is then fanned out as a `run-data-drain` background job, so the deployment also needs `TRIGGER_DEV_ENABLED` and a configured Trigger.dev project. Without it the dispatcher still claims the work and enqueues it to the database, but nothing drains that queue for this job type, so the runs stay pending and never execute. See [background jobs](/platform/self-hosting/background-jobs).
269
+
Each due drain is dispatched as a `run-data-drain` background job. With Trigger.dev enabled, it runs in the configured Trigger.dev project. Otherwise the database queue executes the registered drain runner. Per-drain database claims apply in both modes. The database fallback limits active drain jobs to two per app process; Trigger.dev workers use serialized per-drain jobs. See [background jobs](/platform/self-hosting/background-jobs).
0 commit comments