Skip to main content

Verifiable evidence for AI-assisted engineering

Project description

agentwitness

Record what your coding agent did, under whose authority, with what scope, and produce signed evidence anyone can verify offline. Useful for PR review, incident response, security questionnaires, and AI governance audits.

$ agentwitness summary
manifest: 7c6adca6eae24556f8215314cdb74094aa31fe3c747a508d3ef16fe60205a608
  issued:  2026-05-23 17:32:57
  expires: 2027-05-23 17:32:57

sessions (2):
  sess_d3cf2597d1b39167aa6e3a     3 events  2026-05-23 17:32:57 → 17:32:57  (claude-vis-test)
  sess_c23db027e0ddf6e57bf9b7    18 events  2026-05-23 14:14:23 → 14:48:01  (claude-session-2)

$ agentwitness blame src/auth.ts
events touching src/auth.ts:
  2026-05-23 14:18:42  tool.requested   Edit   sess_c23db027e0ddf6e  (ok)
  2026-05-23 14:18:43  tool.completed   Edit   sess_c23db027e0ddf6e  (ok)

$ agentwitness export -o ./evidence
Bundle written to ./evidence
Verify with: agentwitness verify ./evidence

$ agentwitness verify ./evidence
agentwitness verify: OK  (./evidence)
  events verified:   18
  sessions seen:     1

Status

v0.1.0, alpha. First functional release: record via Claude Code hooks, export a bundle, verify it. POSIX only (Linux and macOS); Windows support pending a cross-platform writer lock. API may shift before v0.2 — see the changelog for the v0.1 feature set and known limitations.

Quickstart

# Install with pipx (recommended) or pip
pipx install agentwitness

# One-time setup: generates an Ed25519 keypair in your OS keychain,
# writes a default manifest, and adds hook entries to ~/.claude/settings.json
# A .bak of any existing settings.json is written first.
agentwitness install

# Use Claude Code normally. Each PreToolUse, PostToolUse,
# PostToolUseFailure, UserPromptSubmit, SessionStart, and SessionEnd
# fires a hook that records a signed event into <state>/sessions/.

# See what was recorded
agentwitness summary
agentwitness blame src/path/to/file

# Build an evidence bundle from the most recent session
agentwitness export -o ./evidence

# Confirm the bundle is internally consistent
agentwitness verify ./evidence

# Uninstall (conservative — keeps keychain and recorded sessions)
agentwitness uninstall

Any Python 3.10, 3.11, or 3.12 works. The install is idempotent: running it twice reuses the existing key and refreshes the hook entries without duplicating them.

Upgrade and recovery

Upgrade in place:

pipx upgrade agentwitness    # or: pip install -U agentwitness
agentwitness install         # re-runs idempotently; refreshes hook entries

If agentwitness install aborts partway through, the operation is safe to retry. The .bak of any pre-existing ~/.claude/settings.json is written before any modification, the keychain entry may already have been created (and will be reused on the next run), and re-running install is the supported recovery path. If you want a clean reset, run agentwitness uninstall --purge-keys --purge-state first.

What this proves — and what it doesn't

A bundle that passes agentwitness verify proves that the captured events were not modified after capture and that each one was signed by the key declared in the manifest.

It does not prove:

  • Completeness. A hostile local environment can disable hooks, delete files, or run tools outside the instrumented path. The bundle records what was captured, not what existed.
  • External identity. The bundle proves a key signed it — not that the key belongs to a particular person, machine, or organisation. That binding is a separate concern (pin the public key in a registry, post it on a known site, use Sigstore-style OIDC, etc.).
  • Semantic intent. "The agent edited auth.py" is in the record. Whether that edit was malicious, careless, or in scope is a human judgment the bundle supports but does not make.

Full enumeration in THREAT_MODEL.md.

Architecture

Three pieces, all small:

  • Recorder. A Claude Code hook entry point (agentwitness hook) reads the hook payload, builds an event, signs it with the Ed25519 key from the OS keychain, and appends it to events.jsonl plus signatures.jsonl inside a session directory.
  • Verifier. Reads a bundle, recomputes every event id, checks every signature, evaluates each tool action against the manifest's scopes, and re-checks the chain checkpoint. Errors are accumulated and reported with stable error codes.
  • Spec. spec/v0.1.md defines the on-disk format both sides agree on — canonical serialisation (RFC 8785 JCS), the event schema, the signing envelope, the manifest, and the bundle layout. The spec is the source of truth; if the code and spec disagree, the spec wins.

Configuration

State lives under:

OS Path
macOS ~/Library/Application Support/agentwitness/
Linux $XDG_DATA_HOME/agentwitness/ or ~/.local/share/agentwitness/
Windows %APPDATA%/agentwitness/ (not yet supported in v0.1)

Override either path for testing:

  • AGENTWITNESS_STATE_DIR — overrides the state root.
  • AGENTWITNESS_CLAUDE_SETTINGS — overrides the path to Claude Code's settings.json that the install command patches.

The signing key never leaves the OS keychain except as a working copy in the recorder process. To rotate keys, run agentwitness uninstall --purge-keys and then agentwitness install again. Old bundles still verify against the old public key recorded in their manifest.

Uninstall

# Default — strips hook entries, keeps keychain and recorded sessions
agentwitness uninstall

# Restore ~/.claude/settings.json from the .bak written at install time
agentwitness uninstall --restore-from-backup

# Also delete the keychain entry. Old bundles still verify (their
# manifest contains the public key) but you can no longer sign new events
# under that label.
agentwitness uninstall --purge-keys

# Also delete the state directory. Removes the manifest and every
# recorded session.
agentwitness uninstall --purge-state

# Shorthand for --purge-keys + --purge-state
agentwitness uninstall --purge-all

Roadmap

Deferred to post-v0.1:

  • Multi-hop delegation chains (subagent → tool token flow)
  • ECDSA P-256 signing for interop with IETF AAT
  • The optional attestations/ bundle directory (RFC 3161 timestamps, Sigstore certificates, transparency-log inclusion proofs, remote witnesses) — reserved in the spec, no concrete formats yet
  • DSSE envelope adoption
  • TOML manifest authoring with a JSON canonical export
  • Windows-compatible writer lock
  • Multi-machine session merging
  • Tarball bundle packaging
  • Hosted dashboard / Cowork plugin (the Python API at Recorder.bootstrap is the integration surface)

See the open questions in spec/v0.1.md §14.

Contributing

See CONTRIBUTING.md for the local setup, test commands, commit conventions, and review flow.

Bug reports and design discussion belong in GitHub issues. Security issues: see SECURITY.md.

License

Apache License 2.0 for the code.

The specification under spec/ is licensed CC-BY-4.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentwitness-0.1.0.tar.gz (111.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentwitness-0.1.0-py3-none-any.whl (48.0 kB view details)

Uploaded Python 3

File details

Details for the file agentwitness-0.1.0.tar.gz.

File metadata

  • Download URL: agentwitness-0.1.0.tar.gz
  • Upload date:
  • Size: 111.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for agentwitness-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7a4ef804e50b7219067d143b90a6bd6dcce607dfb5cddfa01f85837052dd46ac
MD5 2057505f1330439523d909a67a6ca54f
BLAKE2b-256 41e08c5cf1b99dd586538c8ef1e1c206ab0d8bc054dec7ee4eabcdecfa81dc4f

See more details on using hashes here.

File details

Details for the file agentwitness-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: agentwitness-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 48.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for agentwitness-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 20783841a684e491fd4d1cabd86007c4a4a6bbc416387fd9084035ad2eb77720
MD5 e0f62abde9745b184d3cf4d63698cf09
BLAKE2b-256 8fbb9f71a0f3692ee97437fc69c8ed1109456748c02f8024606b251763a49146

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page