Tamper-evident audit log
The hash-chained, HMAC-signed audit ledger — write strategies from fail-closed to asynchronous, correlation IDs, durable fallback, and plan-tiered retention and visibility.
PulsVault records security-relevant events in an append-only, cryptographically chained audit ledger designed for SOC 2 Type II, ISO 27001, and GDPR Article 30 requirements. The design goal is not just logging but tamper evidence: any insertion, deletion, or modification of a past entry breaks the chain and is detectable.
Hash chaining and signatures#
Each entry links to its predecessor and is independently signed:
entry_hash = SHA-256(correlation_id | action | actor_id | created_at | previous_hash)
hmac_signature = HMAC-SHA256(entry_hash, server_secret)- The
previous_hashlink makes the ledger a chain: altering entry N invalidates every entry after it. - The HMAC signature prevents an attacker with database access from silently recomputing the chain — they would also need the server's HMAC secret.
- Sensitive values inside events (keys, raw tokens) are HMAC-hashed before write; passwords are redacted outright. Secrets never enter the ledger in plaintext.
- An integrity verification endpoint re-walks the chain on demand and reports any break (Business/Enterprise admins and compliance auditors).
Write strategies: fail-closed where it matters#
Auditing is applied uniformly across the operations that matter, rather than being written into each feature by hand. Each class of event routes to one of three write strategies:
| Strategy | Behavior | Used for |
|---|---|---|
| Blocking | Writes in the same transaction; audit failure rolls back the business operation | High-risk actions: password changes, policy modifications |
| Synchronous, best effort | Written before the response, but a write failure does not block the operation | Logins, logouts |
| Asynchronous | Written after the operation commits | High-volume, lower-risk events |
Failed operations are still recorded — with a FAILURE result and the error reason — so the
ledger captures denied and errored attempts, not just successes.
Reliability: never lose an event silently#
- Correlation IDs — every request gets an
X-Correlation-IDassigned by the server (one sent by a client is ignored) that is propagated across async threads, tying all log lines and audit entries of one request together. Explore them in the Trace explorer. - Durable fallback — if the ledger cannot be written during an asynchronous write, the event is held in a separate durable queue and replayed into the ledger once the write path recovers. Events are not dropped silently.
- Retention cleanup — entries past their retention category (90 days to 7 years, or permanent) are purged automatically, per organization settings or plan defaults.
Visibility and retention by plan#
What gets archived, who can see it, and for how long is plan-tiered:
| Capability | Free | Premium/Family | Team | Business/Enterprise |
|---|---|---|---|---|
| Authentication logs | Own | Own | Own/team | Team/organization |
| Data mutations (vault/item CRUD) | — | Own | Team | Team/organization |
| Data access logs (item opened) | — | — | Team | Team/organization |
| Admin & organization policy actions | — | — | Admins | Admins |
| Chain integrity verification + CSV/JSON export | — | — | — | Admins/auditors |
| Default retention | 30 days | 90 days / 1 year | 1 year | 7 years / unlimited (configurable) |
Organization-scoped queries additionally require an admin role — members are limited to their own history. Clients can also report client-side actions (clipboard copy, secret reveal) into the same ledger.
Related#
- Activity & audit log — your personal view
- Organization audit logs — the admin view
- Audit & compliance reports