administration
Audit logs
An append-only, tamper-evident audit log with a license-rooted checkpoint chain you can verify offline — scoped to your organization by row-level security.
Updated Aug 3, 2026
Every meaningful action in VaultTerm lands in an append-only audit log. The log is not just write-once; it is tamper-evident, backed by a checkpoint chain that lets you detect after the fact whether any record was altered, removed, or reordered. This is the accountability half of being an audited access broker: the server decrypts secrets in memory for authorized actions, and each of those actions leaves a record that cannot be quietly rewritten.
The log
The audit log captures who did what, when, and against which resource — reads, brokered sessions, configuration changes, and security events. Entries are written once and never updated in place.
Search and filtering are scoped to the caller’s organization by row-level security. An operator
querying audit data only ever sees rows whose org_id matches the authenticated tenant context; the
isolation is enforced at the database, not in application code. See
Tenant isolation for how the scoping works.
The checkpoint chain
On top of the raw log sits a license-rooted checkpoint chain. Periodically, a checkpoint is written that:
- Seals a contiguous range of audit rows with a hash over that range.
- Hash-links to the prior checkpoint, so the checkpoints form a chain — altering an old record changes its range hash, which breaks every checkpoint after it.
- Is stamped with the license counter, a monotonic anti-rollback value, rooting the chain in the deployment’s license rather than in a value an attacker could freely reset.
Because each checkpoint depends on the one before it and on the license counter, you cannot rewrite history without rewriting the entire downstream chain — and you cannot fabricate a fresh chain that matches the license root.
Offline reveals
A client that holds an encrypted offline copy of the vault (the browser extension and the mobile app do) fills without reaching the server, so the audit record for that reveal cannot be written before the secret is handed over. It is written afterwards, and the guarantee is enforced on the client:
- The reveal is recorded locally first. Each cache-served fill is appended to a sealed journal on the device — credential, time, surface, host, device, and a strictly increasing sequence number — and hash-chained to the entry before it, using the same construction as the checkpoint chain above.
- Batches are shipped on the next sync and become ordinary audit entries, flagged as having arrived from a device journal and carrying the time the secret was actually handed over as well as the time it reached the server.
- Dropping entries is visible, not silent. The server verifies that a batch continues from the chain position it already holds. A gap, a broken link, a refused batch and a deliberate chain restart are each written as their own audit event and can be alerted on.
- The client stops filling if it cannot report. Once unreported reveals exceed the age or count your organization sets, the device refuses to fill from its copy until it has handed them over.
- You can turn it off. Setting the age limit to zero is strict mode: no reveal is ever served from a local copy, so the audit record is always written before the secret is handed over, and an offline fill is refused instead.
What the batch authentication does and does not prove. A batch is authenticated with an HMAC-SHA256 derived from that device’s server-issued cache key. That proves the batch came from a device holding a key your organization has not withdrawn, and that no entry in it was altered. It is a symmetric MAC — the server holds the same key — so it is not a device signature and does not provide non-repudiation: the record does not distinguish a batch the device produced from one the server could have produced. The server-side chain, the checkpoint chain and row-level security are what protect the trail after it arrives.
Verifying offline
The chain is designed to be checked independently of the running server. The repository ships a verification script:
# from server/
npx tsx scripts/verify-audit-chain.ts
The script walks the checkpoints, recomputes each range hash and link, and confirms the license
counter sequence. If verification fails, the server raises an AUDIT_CHAIN_BROKEN event — a
critical anomaly indicating the checkpoint chain integrity has been broken. The admin console surfaces
the current chain status in its System view; see admin console.
The cryptographic construction behind the checkpoints (envelope encryption, hashing, and the license-rooted design) is described in Cryptography.
Retention by plan
How long audit records are kept depends on the plan:
| Plan | Retention |
|---|---|
| Free | 7 days |
| Pro | 30 days |
| Team | 365 days |
| Enterprise | Unlimited |
Self-hosted deployments derive their tier from the signed license rather than a billing catalog; see Billing and plans.
Related pages
- Cryptography — the tamper-evident construction in detail.
- admin console — where audit-chain status is reported.
- Tenant isolation — how audit search is scoped per organization.