Audit log CSV export

The workspace audit log can be exported as CSV for archival, external review, or ingestion into a SIEM. The endpoint streams rows directly from Postgres, so an export of millions of rows completes in constant memory on both the server and the client.

Requires the Enterprise plan and workspace admin role.

Endpoint

GET /api/workspaces/{slug}/audit-logs/export.csv

Filters (all optional, all the same as the JSON list endpoint):

Query parameterMeaning
actionExact match on the dotted action code (e.g. workspace.member.invited)
entity_typeExact match on the target entity type (e.g. workspace, project, integration)
actor_idUUID of the actor user
fromLower bound on created_at, inclusive. RFC 3339, date-only (YYYY-MM-DD), or Unix seconds
toUpper bound on created_at, inclusive. Same formats

Response

Content-Type: text/csv; charset=utf-8 with Content-Disposition: attachment; filename="audit-<workspace-slug>-<utc-timestamp>.csv".

Columns

#ColumnFormat
1idUUID
2created_atRFC 3339 with nanoseconds, UTC
3actionDotted-string action code (e.g. member.role.changed)
4entity_typeTarget entity type
5entity_idUUID or empty
6actor_user_idUUID or empty (empty for system actions)
7actor_token_idUUID or empty (present when the actor used an API token)
8actor_labelFallback label (e.g. system, <deleted user>)
9actor_display_nameDisplay name at the time of query
10actor_emailEmail at the time of query
11ip_addressText form of the request IP or empty
12user_agentRaw User-Agent header
13metadata_jsonThe full metadata object as a JSON string

Rows are ordered newest first (created_at DESC, id DESC) so a trailing tail of the file is always the oldest data in the export window. Newlines and quotes inside string columns follow standard CSV escaping.

Examples

Full workspace export (largest, slowest):

curl -o audit.csv \
  -H "Authorization: Bearer $ITHURA_API_TOKEN" \
  "https://api.ithura.com/api/workspaces/acme/audit-logs/export.csv"

Last 30 days of role changes only:

FROM=$(date -u -d '30 days ago' +%Y-%m-%d)
curl -o audit-role-changes.csv \
  -H "Authorization: Bearer $ITHURA_API_TOKEN" \
  "https://api.ithura.com/api/workspaces/acme/audit-logs/export.csv?action=member.role.changed&from=$FROM"

Everything a single admin did last quarter, for an internal review:

curl -o audit-alice-q3.csv \
  -H "Authorization: Bearer $ITHURA_API_TOKEN" \
  "https://api.ithura.com/api/workspaces/acme/audit-logs/export.csv?actor_id=$ALICE_UUID&from=2026-07-01&to=2026-10-01"

SIEM ingestion

Point your SIEM at the CSV directly, or schedule a job that downloads a daily incremental export (from=<yesterday>) and ships the file to your SIEM's bucket. The file is stable-schema and stable-order; a diff-based ingest is safe.

A native SIEM streaming push (fire-and-forget webhook on every audit event, HMAC-signed) is on the sovereign roadmap as a follow-up to this export. Track it in the Ithura project under the Sovereign module.

Retention

Today Ithura retains every audit row indefinitely (no automated pruning). Configurable per-workspace retention is on the sovereign roadmap; until it ships, the export gives you the primitives you need to archive and then manually purge if your policy requires it.

Permissions

Only workspace admins (role 20) can call the export endpoint. The call is itself audited under the action workspace.audit.exported with the requested filters in the metadata column, so a reviewer can always answer "who pulled the log, when, with what filters."