Skip to content
TeamBusinessEnterprise

Audit & compliance

The audit dashboard, hash-chain integrity verification with its history, the export center, and retention controls that back your compliance program.

The Audit & Trace and Custom Reports sections of the Reports Center are built for compliance work: a dashboard summarizing audit activity, a cryptographic integrity check with a record of every run, and exports that are themselves audited. The underlying log is designed to support audits against frameworks such as SOC 2 Type II, ISO 27001, and GDPR Article 30.

Audit dashboard#

Reports → Audit Dashboard summarizes your organization's trail over the last 7, 30 or 90 days:

  • Headline figures — events recorded, active accounts (people and service identities), failures, access denied, and high or critical events. Where the equally long window before this one can be compared, events, failures, access denied and high or critical each show their change against it — for example ▲ 12% vs previous 30 days.
  • Trail integrity — on plans with integrity verification, the result of the last check and when it ran, or that no check has run for more than two days. Select it to open Integrity verification.
  • Events per day — one bar per UTC day of the window. Select a bar to open that day in the Trace explorer. Days older than the retention of some categories are hatched: their count is partial, because those categories' events are no longer readable.
  • By category and by severity — select any row to open the Trace explorer filtered to it.
  • Most frequent actions and most active accounts — select one to see its events.
  • Recent high & critical events — the ten newest. Select an action to see similar events.

Every count except active accounts is a link, and each opens the Trace explorer over exactly the dashboard's window, so the rows there add up to the figure you selected.

No comparison is shown when retention has removed part of the previous window, or when your organization changed what its audit trail records since that window began — the two periods would not be measured the same way.

Routine sign-in and navigation activity — session refreshes, vault listings, report views — is left out of every figure, exactly as the trail leaves it out by default.

Team Business Enterprise

Integrity verification#

Every audit entry is chained to the previous one: its hash covers the prior entry's hash, and the result is signed with HMAC-SHA256 using a server-side secret. Any insertion, deletion, or edit anywhere in the ledger breaks the chain — see Audit log architecture.

  1. Open Reports → Integrity Verification.
  2. Select Verify now.
  3. On success you'll see how many entries were verified, and whether everything earlier checks verified is still present and unchanged.
  4. If verification fails, the result says what kind of break it found — an entry changed, the sequence around an entry altered, a signature that does not verify, entries an earlier check verified that are now missing or different, or an entry moved between organizations — and the first affected entry. Contact support with that reference and do not delete anything: the current state is the evidence.

Every entry in your trail is verified. None is skipped as too old to check.

Each check also compares against the last one. Links between entries prove nothing was edited, inserted or removed inside the trail — but removing the newest entries would leave a shorter trail whose links all still hold. So every check records the newest entry it verified, and the next check confirms that entry is still there, unchanged. The very first check of a trail has nothing earlier to compare with, and says so.

Every check is also written to your organization's audit trail, as Audit integrity verified.

Your trail is also verified every night, whether or not anyone opens the page. Each nightly check covers exactly what Verify now covers, and appears in the history as Nightly check.

The top of the page shows where your trail stands: the last check and its result, how many clean checks in a row it has had — the number an auditor cares about, since it shows the trail has been intact continuously — when it last failed, if ever, and how many checks are on record. A trail nobody has checked yet says Not checked yet, never "passed".

Verification history lists every check — the nightly one and every check a member ran — with when it ran, by whom, how many entries it covered and how long it took, so "when was this last verified" has an answer. Select Details on any row to see what that check found: for a failure, what kind of break it was, the reference of the affected entry to give support, and Show the trail around it, which opens the Trace Explorer on the minutes surrounding that entry.

If a check fails, you are told. Everyone who can read your organization's audit trail receives a notification saying what kind of break was found and when the affected entry was written. It links to this page, and it cannot be muted. It repeats with every failing nightly check until the break is resolved, because a break does not go away by itself.

Business Enterprise — on Team, Integrity Verification does not appear in the Reports sidebar, and opening its address explains which plan includes it.

Keep a receipt#

Everything above is checked against records PulsVault holds. An integrity receipt is the one piece of evidence you hold instead: a small signed file stating how far your latest clean check verified each part of your trail. Kept by you, it lets anyone — you, or your auditor — confirm later that nothing it covers was removed or rewritten, by whoever.

  1. Select Verify now. When the check passes, its result offers Download receipt — a signed record of exactly what that check verified. Keep the file somewhere PulsVault cannot write — your document store or your auditor's.
  2. Later, select Check a receipt and choose the file. Its signature is checked first; a receipt changed by a single character is refused whole.
  3. Each part of your trail is then reported as still present and unchanged (the entry is there, and its contents still produce the fingerprint the receipt recorded), removed by your retention policy, or — a problem to raise with support — missing, changed, or still present, but an earlier entry was removed or changed (everything up to the receipted entry is re-checked, not just the entry itself).

Enterprise organizations with a backup archive receive a receipt in every archive automatically, and the recovery kit checks it with no connection to us at all.

Keep receipts as long as you keep audit entries

Once your retention policy removes the entries a receipt names, the receipt can only confirm they were removed by that policy — on our records. To prove a period independently for years, retain its audit entries for years too.

Receipt format, for auditors#

A receipt is JSON: format (pulsvault.audit-receipt/1), organizationId, issuedAt, checkRunId, verified (entry counts), chains (each with chainKey, chainSeq, entryHash, entryId, entryCreatedAt) and signature (alg, keyId, value). The signature is Ed25519 over this exact text, one field per line, each line ending in a newline, chains sorted by chainKey:

text
pulsvault.audit-receipt/1
organizationId=<organizationId>
issuedAt=<issuedAt>
checkRunId=<checkRunId>
verified=<totalEntries>,<verifiedEntries>,<legacyUnverifiableEntries>
chain=<chainKey>|<chainSeq>|<entryHash>|<entryId>|<entryCreatedAt>

The third count on the verified line is always 0: every entry is verified, and none is skipped. It is kept so receipts already issued keep the same signed format.

value is the base64 signature; the public key for each keyId is published at /api/v1/public/audit/receipt-keys and bundled in the recovery kit. Because only the field values are signed, a receipt re-saved with different spacing still verifies.

In a backup archive, audit/chain-proof.json lists every audit entry with the exact text its fingerprint covers (hashInput). An entry is intact when the SHA-256 of hashInput equals its entryHash, and linked when hashInput ends with its previousHash field and that previousHash is the previous entry's entryHash in the same chain. Every entry's fingerprint is recomputed; an entry cannot opt out of the check, whatever it is labelled.

hashInput is a list of fields, each written as <length>:<value>| (the length counts UTF-16 code units), or -| for an empty field. It comes in two formats, told apart by their shape:

  • 31 fields, starting with v2 — the current format, used for every new entry: v2, correlation id, stream, action, actor id, actor email, actor IP, resource type, resource id, target user id, result, severity, failure reason, description, before state, after state, metadata, retention category, time written, organization id, chain key, chain position, machine key id, target user email, resource label, related item id, related vault id, user agent, session id, plan, previous hash. In the three state and metadata maps, every plain value carries its type: n for a number, b for true/false, s for text.
  • 19 fields — the earlier format, kept by entries written before it changed: the same list without the v2 tag and without the eleven fields in bold, and with map values untyped.

For a v2 entry, the chain key and chain position inside hashInput must equal the entry's own chainKey and chainSeq, and every chain in an organization's archive is one of that organization's own (org:<organizationId>:…). The recovery kit checks all three.

Export center#

Reports → Export Center builds a copy of the trail for your records, your auditor or your SIEM:

  • Choose a category (or every category), a period of up to three months, and a format — CSV, one row per entry, or JSON, as the API returns entries.
  • The period is 7 days, 30 days (the default), 90 days or Custom, which shows From and To date pickers. Periods are whole days in your browser's time zone, and a longer span goes in parts.
  • Include routine sign-in and navigation activity is off by default. Session refreshes, vault listings and report views are recorded but outnumber everything else, so an export leaves them out unless you switch this on.
  • Recent exports lists every export taken in the last 90 days: who took it, how many entries it held, which categories and period it covered, and the file's SHA-256. Taking a copy of the audit log is itself an audited event (Audit log exported), so there is no way to export it without leaving a trace.

Checking a file is the one that was exported#

The SHA-256 is computed over the exact bytes you downloaded and recorded in the audit trail, which is itself tamper-evident. To show a file is unaltered, copy its fingerprint from Recent exports with the copy button beside it, then compute the file's own and compare the two:

bash
sha256sum audit-log-2026-07-01_to_2026-09-29.csv

One changed character — an edited row, a deleted line — produces a different fingerprint. Exports taken before fingerprints were recorded show Not recorded in that column.

Values that members typed — item names, labels, descriptions — are written so a spreadsheet shows them as text and never runs them as formulas.

Team Business Enterprise

Retention#

How long entries are kept is set by your plan and, where your plan allows, your organization's audit policy — see Organization audit log settings. When a reader may change that policy, the Audit dashboard shows the retention in force beneath it, and whether it is set per category. Expired entries are purged automatically by a scheduled cleanup job.

Evidence for auditors#

Export the relevant window from the Export center or the Trace explorer, run an integrity verification, and hand over both. The verification history shows the auditor the trail has been checked before, not only on the day they asked.

Fail-closed logging for high-risk actions

High-security operations (such as policy changes) are logged synchronously in the same transaction as the action itself: if the audit write fails, the action is rolled back. An attacker cannot perform a sensitive operation while suppressing its audit record.

Was this page helpful?