Menu QaldyDocs

The audit log

Every sign-in, build, run, share and refused call is a row in a log that checks itself. How to read it, verify it, keep your own copy, and what it still cannot prove.

"Who did that?" should have an answer. Qaldy writes a row for every action that changes something or that the sandbox refused, in the same transaction as the action, so there is no change without a record.

What goes in

Sign-ins and sign-outs, builds and approvals, runs, shares and removals, role and invite changes, connector connects, tests and disconnects, key rotations, plan and cap changes, token and MCP sign-in grants, what the spending cap did, and every call the gate refused with the reason. An MCP call is a row before its handler runs: the actor is the grant or token, and the person it acts for is recorded.

Reads are recorded too. Opening the audit log, listing the connections or keys (which names every sealed key) and exporting the log each leave a row: who, which view, how many, never what was read. Repeated views fold into one row per person per ten minutes; exports never fold.

What does not go in: secrets, request or response bodies, app data, prompts and replies. A row holds ids, names, counts and metadata. A refused egress call records the host and method, never the path or query, because those can carry data.

Read it

Open Security (admins). The log is newest first, filterable (for example "Blocked calls"), and a row opens in a side sheet. Over the API it is GET /v1/workspaces/{ws}/audit; admins can also read it with a read-scope token, or over MCP with the audit_log tool.

Verify it

Each row stores a hash of the previous row and of itself: hash = sha256(previous hash ‖ canonical JSON of the event), where "canonical" is RFC 8785 (keys sorted, no spaces). Editing, deleting or reordering any row breaks every hash after it. Security → Verify again recomputes the chain and says "Audit chain verified · N events", or names the first row that does not match. The same check is GET /v1/workspaces/{ws}/audit/verify.

The database role the API uses can insert and read audit rows but not change or delete them, and a trigger rejects updates, deletes and truncates. That raises the bar. It does not remove it: someone with the database owner's rights could still rewrite the chain from some row onward. That is what checkpoints are for.

Signed checkpoints

Beta Once a day, for each workspace whose log moved, the API signs a short statement: "this workspace's chain had N events and ended in this hash". The key is an ed25519 key that is not in Postgres. Because every hash covers every event before it, one checkpoint vouches for events 1 to N: change any of them and the hash at N no longer matches; cut the tail and there is no event N.

  • Security shows the signing key's id, where it comes from, and its public key. Pin that public key somewhere you trust; a key read from the same place as the data proves nothing about it.
  • A locked copy. Where an install has a vault configured, each checkpoint is also written to an Object-Locked bucket the API can write to but not read, overwrite or delete. A checkpoint is shown as copied only after that write returned. On the pilot this copy is not on yet: the API runs in a container that cannot reach the host's AWS role, so it has no credentials to write with. The Security screen says which it is.
  • It cannot vouch for events newer than the newest checkpoint. Streaming your log out narrows that window to the delivery lag.

Keep your own copy

Admins can download the whole log (JSON Lines), stream it to a signed webhook (Beta) or to their own S3 bucket through a role they own (Preview), and check a copy offline with no Qaldy account. How, with a short checker you can read: Stream, export and verify the audit log.

What it cannot prove

State the limits plainly:

  • Events after the newest checkpoint can still be rewritten by someone with database access, unless you stream the log out as it grows.
  • The locked copy is not on the pilot yet (see above), and the vault is in Governance mode (35 days), which an AWS administrator with the bypass permission can override. Compliance mode is Planned.
  • Until a dedicated signing key is set, the checkpoint key is derived from the API's own key. Rotating the API's key then changes the checkpoint key, and older checkpoints need the old public key to verify.
  • Nothing here is an independent audit. No outside party has checked it.

The proofs E1 to E3 in the proof list check the chain end to end: it verifies after a run, a tampered row fails verification and restoring it heals it, and every action of the run has its row. Checkpoint verification is checked by the API's tests and, on the live cell, by proofs L9 and L10 when the production proof job has its token.

Type to search. Up and down to choose, Enter to open, Esc to close.