Skip to content

Audit log API reference

Read, seal, export and verify the hash-chained action log: entry fields, the kind vocabulary and the export bundle your own verifier checks.

Last updated:

Every consequential action the platform takes lands in a hash-chained, signed log that your compliance team — or your customer's — can verify independently. Reading and sealing it requires nothing special: the same bearer API key as everywhere else on the v1 surface.

Chain and seal

seq 0 prev: GENESIS hash: hash 0 seq 1 prev: hash 0 hash: hash 1 seq 2 prev: hash 1 hash: hash 2 seq 3 prev: hash 2 hash: hash 3 seal: Ed25519 signature over the range seq 0..3 the CHAIN catches an altered or removed entry -- but not a truncated tail; the SEAL catches the truncated tail -- but not an entry edited and rehashed. verifyLog checks BOTH; neither is a verification alone
Each entry hashes its predecessor; a seal signs a range. The chain catches an altered or removed entry, the seal catches a truncated tail — both are needed.
GET /v1/audit/log

Pages through the log from a sequence number given as `from`, 5000 entries at a time, with `nextFrom` pointing at the next page.

Entry fields

Name Type Description
kind string What happened, from the vocabulary below.
at timestamp When the platform recorded it.
summary string A one-line human-readable account.
seq integer The entry's position in the chain.
prev string The hash of the previous entry.
hash string This entry's own hash, computed over its canonical encoding.

The kind vocabulary

Kinds include session.created and session.released, the verbs verb.observe, verb.act and verb.extract, credential.released and credential.denied, the safety refusals gate.refused and destination.refused, task.started and task.finished, workflow.block, takeover.granted and takeover.released, trigger.fired, and the key events key.rotated and secret.rotated.

GET /v1/audit/seals

Lists the seals and the entry ranges each one covers.

POST /v1/audit/seal

Signs a named range with Ed25519 and returns `{sealId, seal, covers}` — or 400 when nothing new is there to seal.

GET /v1/audit/export

Exports a `browserberg-action-log-v1` bundle of entries and seals, paged at 50000 entries.

Verify without us

The bundle carries howToVerify, and running a verifier needs nothing from us: replay the chain, then check every seal. Neither mechanism suffices alone — one misses a shortened tail, the other an edited entry — so treat them as one check with two halves, never as alternatives.

Seals name their algorithm. ed25519 is the original; ecdsa-p256-sha256 (since 1.4) is what the hosted service seals with, because its signing key lives in a KMS that offers P-256 and not Ed25519. An ECDSA signature is the 64-byte IEEE P1363 r||s form, base64, verified with SHA-256 over the same canonical seal string. A verifier refuses an algorithm it does not know rather than guessing.

POST /v1/audit/verify

Runs the platform's own verification — it exists for support; run your own verifier, that is the point.

What the log is not

Honesty about scope: the export is not a timestamping authority, and it is not proof the browser behaved as described. It is a tamper-evident record of what the platform said it did — strong enough that an altered, removed or truncated account shows, and no stronger.

Leave a trace, read it back

Creates and releases a session, then reads the first chain entries with their hashes.

Requires: api-key

BASE="https://browserberg.com"
AUTH="Authorization: Bearer $BROWSERBERG_API_KEY"
JSON="Content-Type: application/json"

# Leave a trace to read back.
ID=$(curl -s -X POST "$BASE/v1/sessions" -H "$AUTH" -H "$JSON" -d '{"ttlSeconds": 60}' \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["session"]["id"])')
curl -s -X DELETE "$BASE/v1/sessions/$ID" -H "$AUTH" > /dev/null

# Every entry carries seq, prev and hash: a hash chain a verifier replays.
curl -s "$BASE/v1/audit/log?from=0" -H "$AUTH" \
  | python3 -c 'import json,sys; r = json.load(sys.stdin); print(json.dumps([
      { "seq": e["seq"], "kind": e["kind"], "summary": e["summary"] }
      for e in r["entries"][:4]], indent=2))'

Context

  • Isolation and sovereignty The boundaries the log attests to
  • Limits Page sizes for the log and the export
  • Credentials vault guide The moments credential.released records