StrataDocs

Audit log

The tamper-evident record of administrative and (optionally) member activity in your organization.

The audit log lives in Organization settingsAudit tab. The direct URL /admin/audit still works — it opens Organization settings with the Audit tab active. Viewing the tab requires canViewAudit. Exporting the log as CSV requires canExportAudit.

The activity table

The Audit tab renders your organization's security events as a live, filterable table. The header tells you the coverage window at a glance — "Showing security events for Acme Corp since Jan 18, 2026." — and the footer shows "Viewing 20 of 42 results" with Back / Next paging in the bottom-right.

Each row shows:

ColumnWhat it holds
ActionThe namespaced verb, e.g. user.role_changed. See the action vocabulary below.
CategoryA human grouping derived from the action prefix — User management, Roles & permissions, Sessions, Organization, Database connections, Agents, Billing, Authentication, API keys, Knowledge base, Invitations, Data export, Announcements, Extensions, Oversight, AI engine, SCIM, and more.
UserThe actor's email. SCIM-driven changes show scim:<token-label>.
IP addressThe actor's source IP, shown raw, with the country flag of its approximate location in a circle to its left.
TimeWhen it happened, in your local timezone.

Filter with the search box (matches action, actor email, target email, and IP address), the Category dropdown, and the date-range picker. Filters combine, and the result count updates as you narrow.

Event details

Click any row to open the detail panel from the right. At the top is a map pinpointing the approximate location of the recorded IP address; below it, the full record — action, category, actor, target, IP address, resolved location, timestamp, audit ID, and the action's details payload (before/after values, counts, or whatever the action emitted).

Key

Strata stores only the raw IP address — never a derived location. The country flag, map position, and location strings are resolved at read time from MaxMind GeoLite2 data and are approximate (typically city-level at best). Nothing geographic is ever written to the audit record.

What is logged

Every state-changing admin action passes through a single _audit() helper that writes a row to the audit_log table. The row shape is:

ColumnWhat it holds
audit_idUUID primary key.
org_idThe organization the action targeted.
actor_user_idThe admin who performed the action. SCIM-driven changes use the nil UUID 00000000-0000-0000-0000-000000000000.
actor_emailThe admin's email. For SCIM, scim:<token-label>.
actionA namespaced verb. See the action vocabulary below.
target_user_idThe user the action acted on, if any.
target_emailThe target user's email, if any.
detailsJSON blob of before/after, counts, or whatever the action emits.
ip_addressThe actor's source IP.
created_atUTC timestamp.

Action vocabulary

Action verbs are namespaced (<area>.<verb>). The set logged today includes:

  • User lifecycleuser.role_assigned, user.role_changed, user.enabled, user.disabled, user.deleted, user.memory_wiped, user.conversations_deleted, user.data_exported, user.display_name_changed, user.avatar_changed, user.rate_limit_changed, user.bulk_<action> (plus a .failed variant when a bulk item errors).
  • Per-user governanceuser.model_access_changed, user.python_access_changed, user.jira_write_access_changed, user.confluence_write_access_changed, user.agent_controls_changed, db.access_changed, ext.toggled, ext.tokens_revoked, ext.tokens_revoked_bulk.
  • Rolesrole.created, role.updated, role.deleted.
  • Sessionssession.revoked (a single session or all of one user's sessions), sessions.revoked (sessions killed when a role's permissions narrow), org.sessions_revoked_all (force sign-out of every member of an org).
  • Org settingsorg.updated, org.suspended, org.unsuspended, org.logo_changed.
  • Authenticationauth.sign_in and auth.sign_in_failed (recorded at every tier), auth.sign_out (Compliance tier and above). Rows written by earlier releases carry auth.login_failed for failed attempts.
  • Billingbilling.portal_opened and subscription lifecycle events mirrored from Stripe. See Billing.
  • AI engineorg.foundry.configured, org.foundry.cleared (your per-tenant Azure AI Foundry connection).
  • Org connectionsorg_db.created, org_db.updated, org_db.deleted, connection.test_failed.
  • Atlassian extensionsorg.confluence_config_updated (any save in the Confluence group of the Atlassian extension page), plus every write Strata makes: confluence.page_created, confluence.comment_added, jira.issue_created, jira.comment_added. Confluence reads are not audited — searching a space or opening a page leaves no row.
  • Invitationsinvite.created, invite.revoked, invite.preconfigured.
  • API keysapi_key.created, api_key.updated, api_key.rotated, api_key.revoked, api_key.purged.
  • SCIMscim.token_issued, scim.token_revoked. (SCIM user deactivation flows through user.disabled with a scim: actor.)
  • Member-chat oversightmember_chat.viewed, member_chat.files_viewed, member_chat.file_downloaded, member_chat.conversations_exported.
  • Org deletionorg.deletion_requested, org.deletion_canceled.
  • Metaadmin.users_exported (organization data export), audit.exported (a CSV export of the audit log itself), admin.legal_cache_flushed.

This list grows over time; treat the live table as authoritative.

Audit detail level

Beyond admin mutations, your organization can opt into capturing user activity at one of three tiers. The level is set in Organization settings → Defaults → Audit detail level, and changing it requires the canManageCompliance permission (an owner-reserved capability).

TierWhat it addsVolume
StandardDefault. Admin mutations, plus user sign-ins (auth.sign_in) and failed sign-in attempts (auth.sign_in_failed) — those are security-critical and recorded at every tier.Baseline.
ComplianceAdds user sign-out (auth.sign_out) plus extension activity such as email sends and OneDrive uploads.Higher.
ForensicAdds a per-message record (chat.message_sent) capturing the model, mode, and the count of tool calls used, plus a kb.search record per Knowledge Base lookup.Highest — roughly 30× the row volume.
Key

At Standard, user chat activity is not in the audit log — it lives in the activity_log table surfaced under Usage. Sign-ins are already captured at every tier; Compliance adds sign-outs and extension activity. Per-message chat activity is written only at Forensic.

Tier-gated events are dropped at insert time if the org hasn't opted up, so a Standard-tier org never accumulates user-event rows it didn't choose to keep. Raising the tier applies going forward; it does not backfill.

Note

Raise the tier before the period you need it to cover — it applies going forward and never backfills. Treat the audit log as an internal control record for your own reviews and investigations, not as a compliance attestation: Kronisys holds no independent certification (SOC 2, ISO 27001, FedRAMP) and offers no BAA, and the Usage Policy and DPA prohibit submitting data regulated under HIPAA, PCI-DSS, FERPA or GLBA unless your organization has an enterprise agreement that expressly permits it.

Exporting the log

Click the export icon above the table (requires canExportAudit) to open the export dialog. You choose:

  • Columns — any of Time, Action, Category, Actor, Target, IP address, Location, Details, and Audit ID.
  • Timezone — timestamps in the CSV are rendered in the IANA timezone you pick (UTC by default).
  • Date range — bound the export window; it inherits any filters already active on the table.

The download is audit-<timestamp>.csv, up to 50,000 rows per export, streamed server-side from a fresh DB read at the moment you confirm. For more than 50,000 rows, run multiple narrower date-range exports and concatenate.

The API export endpoint (GET /api/admin/audit/export) without a columns parameter keeps the original fixed layout for existing integrations:

audit_id, actor_email, action, target_email, details, ip, created_at
Note

Every CSV export writes a meta-audit entry of its own (audit.exported), recorded on every tier — so a compromised admin can't drain the log via export without leaving a record.

Reading the log via API

Call GET /api/admin/audit directly (requires canViewAudit). Supported query parameters:

ParameterWhat it does
actionExact action match (e.g. user.role_changed).
actionPrefixPrefix match (e.g. user. for all user-lifecycle events).
actorUserId / targetUserIdFilter by actor or target UUID.
actorEmailExact actor email match.
qFree-text search across action, actor email, target email, and IP address.
since / untilISO-8601 time window.
limit / offsetPagination — limit is capped at 5,000 per call.
withMeta=1Changes the response shape to { entries, total, earliest } for building pagers.

Each returned entry carries a read-time geo field (country, city, ll) resolved from the stored IP — it is computed per request and never persisted.

Tamper evidence

Audit rows are sealed into a hash chain (prev_hash / row_hash). GET /api/admin/audit/verify (requires canViewAudit) re-walks your organization's chain and recomputes every row's SHA-256. ok: false means a sealed row was edited or deleted after sealing — strong evidence of tampering at the storage layer.

Retention

The audit table is swept nightly by a cleanup job. Entries older than your organization's audit_retention_days setting are hard-deleted.

  • Default retention: 365 days.
  • Allowed range: 30 to 3650 days (values outside the range are clamped).
  • Set under Organization settings → Defaults → Audit log retention. Changing it requires canManageCompliance.

The sweeper runs once on server boot, then every 24 hours, per-organization so each tenant's policy is honored independently. There is no way to recover entries older than the retention window — set the value to match your compliance posture before any cleanup runs.

Warning

Most financial firms keep 7 years (2555 days) for compliance. Pick your retention deliberately; deletion is irreversible.

What can go wrong

ErrorWhat it means
Admin access requiredYour role does not grant canAccessAdmin.
Permission required: canViewAuditYour admin role does not include audit read.
Permission required: canExportAuditYou can view the table but cannot download the CSV.
Compliance settings won't saveChanging Audit detail level or Audit log retention requires canManageCompliance, which is owner-reserved.
CSV export is shorter than expectedThe CSV is capped at 50,000 rows. Narrow the date range and export in slices.
Flags or the map don't renderGeolocation is best-effort — private-network IPs and unresolvable addresses simply show no flag and no map. The record itself is unaffected.

See Rate limits and quotas for rate-limit logging (separate from audit), and Organization deletion for how the audit log behaves around an org deletion.

Related