Skip to main content

Audit log

Audit log

The audit log records consequential actions across the organisation. Reading it needs audit.read.

What is recorded

Roughly 210 distinct actions, named <target>.<what> or <target>.<noun>.<verb>: blueprint.acl.revoke, blueprint.visibility.update, apikey.revoke, enterprise.scim.deprovision.

They hang off twenty-one target types:

blueprint · user · team · org · invite · setting · portfolio · portfolio_folder · portfolio_item · diagram · vellum_save · comment · license · template · folium · integration · cloud_connection · continuum_integration · enterprise_tenant · lead · lead_company

Each entry records who acted, what they acted on, when, a structured diff of what changed, and enough request context to tell one session from another.

The diff is capped at about 4 KB. A large change is summarised rather than captured whole.

What it does not keep

The log stores a hash of the IP address, never the address itself, along with the user agent. That is enough to tell two sessions apart or spot an anomaly, without building up a record of where members live.

Append-only, and enforced twice

No codepath in the application updates or deletes an audit row.

The database also installs triggers that raise on UPDATE and DELETE against the table. If a future refactor introduced a bypass, Postgres stops it. No owner, admin or support path can rewrite this log.

Enterprise actions are catalogued

Action strings are free-typed except in the enterprise.* namespace. Thirty-five constants cover tenancy, contracts, SSO, SCIM, IP allow-listing, classification, white-label domains, integrations and stack provisioning, so an enterprise event cannot be recorded under a name that differs from the one you are searching for.

Teams

Teams have their own audit view scoped to their own content, so a team lead can review their area without being granted organisation-wide audit.read.