Audit log and retention
What every audit row captures
Every action in Citadel writes one row to public.audit_log. Each row carries:
- id: stable integer row identifier.
- ts: UTC timestamp (RFC 3339, nanosecond precision).
- actor_id: UUID of the user or agent that acted.
- actor_type: user, agent, or system.
- action: dot-separated action string (e.g. git.push, mcp.tools.call, org.member.invited).
- namespace_id: org or repo scope the action touched.
- session_id: groups all rows from one authenticated session.
- payload: JSON object with action-specific fields (repo path, SHA, tool name, etc.).
Example: a push event
A developer pushes commits to acme/backend. The row written to the audit log looks like:
{
"id": 98241,
"ts": "2026-06-13T17:42:05.381Z",
"actor_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"actor_type": "user",
"action": "git.push",
"namespace_path": "acme/backend",
"session_id": "01j2k9m3p4q5r6s7t8u9v0w1x2",
"payload": {
"namespace": "acme",
"repo": "backend",
"ref": "refs/heads/main",
"sha": "c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2"
},
"humanised": "Pushed to acme/backend"
}Example: an agent tool call
An MCP agent reads a file using the read_file tool. The row written:
{
"id": 98302,
"ts": "2026-06-13T17:43:11.042Z",
"actor_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"actor_type": "agent",
"action": "mcp.tools.call",
"namespace_path": "acme/backend",
"session_id": "01j2k9m3p4q5r6s7t8u9v0w1x2",
"payload": {
"tool_name": "read_file",
"agent_name": "code-review-bot"
},
"humanised": "Agent code-review-bot called read_file"
}Retention windows
Citadel keeps audit log entries for a window determined by your billing tier:
- Free. 90 days.
- Pro. 365 days (SOC 2 baseline).
- Enterprise. 2,555 days (7-year legal hold).
The effective retention for each org is stored in the audit_retention_days column on the namespace record and is refreshed by the purge job on each run.
Purge behavior
A background job periodically removes audit log rows older than the org's effective retention window. The timestamp of the last successful purge for each org is tracked in last_audit_purge_at. Entries within the retention window are never purged early.
Viewing the audit log
Org owners can browse recent audit events from the org dashboard. Each session groups the events that happened under one authenticated connection, with actor identity, timestamps, and action targets. The full log is accessible to admin-scoped agent tokens for programmatic export.