Signed, tamper-evident provenance records for AI agent runs.
AgentProv is a Rust-first MVP for answering the audit questions that ordinary LLM observability usually leaves open:
Who or what ran this agent, with what authority, where did it run, and does the record still verify?
It is designed to sit beside systems such as Langfuse, Phoenix/OpenInference, AgentOps, Helicone, MLflow, and Weave. Those tools show prompts, model calls, tool calls, latency, cost, and traces. AgentProv focuses on identity, authority, policy decisions, and tamper evidence.
- Agent identity, owner, source repository, version, runtime, capabilities, and policy reference
- Run trigger, actor chain, runtime context, available tools, and policy version
- Permission checks for agent actions against scoped resources
- Approval request events for actions that require human review
- Append-only provenance events linked by canonical hashes
- Optional local signatures for manifests, events, and run logs
- JSONL imports from Codex and Claude Code agent runs
- Experimental exports to OpenTelemetry-style and OpenInference-style JSON
Run a complete local demo:
cargo run -- demo manual-tool-run --out demo-output/
cargo run -- run verify demo-output/run.jsonlExpected output shape:
Run verifies
Events: 4
Event chain: valid
Signatures: not present
Install from GitHub:
cargo install --git https://github.com/forjd/agentprov
agentprov --versionOr clone the repository for local development:
git clone https://github.com/forjd/agentprov.git
cd agentprov
cargo run -- --versionGenerate example records:
cargo run -- manifest example
cargo run -- run exampleHash and verify event records:
cargo run -- event hash examples/event.json
cargo run -- event verify examples/event.jsonCreate and verify an append-only run log:
cargo run -- run init --agent examples/manifest.json --trigger manual --out runs/run_123.jsonl
cargo run -- event append --run runs/run_123.jsonl --type permission.check --action discord.message.create --resource discord://guild/123/channel/456
cargo run -- run verify runs/run_123.jsonl --manifest examples/manifest.jsonGenerate a local key and sign records:
cargo run -- key generate --out agentprov.key
cargo run -- manifest sign examples/manifest.json --key agentprov.key --out manifest.signed.json
cargo run -- manifest verify-signature manifest.signed.json
cargo run -- event sign examples/event.json --key agentprov.key --out event.signed.json
cargo run -- event verify-signature event.signed.jsonCheck a static policy:
cargo run -- policy check --policy examples/policy.json --agent agent_01hxexample --action discord.message.create --resource discord://guild/148756/channel/456Append a human approval decision:
cargo run -- approval grant --run runs/run_123.jsonl --approval-id approval_123 --approver danjdewhurst --agent agent_01hxexample --action github.pr.merge --resource repo://forjd/agentprov/pull/1
cargo run -- approval deny --run runs/run_123.jsonl --approval-id approval_124 --approver danjdewhurst --agent agent_01hxexample --action github.pr.merge --resource repo://forjd/agentprov/pull/2Validate records against the embedded schemas:
cargo run -- validate manifest examples/manifest.json
cargo run -- validate run-envelope examples/run.jsonExport a run log:
cargo run -- export otel demo-output/run.jsonl --out run.otlp.json
cargo run -- export openinference demo-output/run.jsonl --out run.openinference.jsonImport Codex or Claude Code JSONL streams:
codex exec --ephemeral --json --sandbox read-only "Summarize this repo." \
| cargo run -- import codex - --out runs/codex-run.jsonl
claude -p --output-format stream-json --verbose --no-session-persistence \
"Summarize this repo." \
| cargo run -- import claude - --out runs/claude-run.jsonlRun deterministic integration examples:
cargo run --example library_api -- runs/library-api.jsonl
cargo run --example openai_wrapper -- runs/openai-wrapper.jsonl
cargo run -- run verify runs/openai-wrapper.jsonl
cargo run --example anthropic_wrapper -- runs/anthropic-wrapper.jsonl
cargo run --example litellm_wrapper -- runs/litellm-wrapper.jsonl
cargo run --example github_tool_event -- runs/github-tool-event.jsonl
cargo run --example discord_tool_event -- runs/discord-tool-event.jsonl
cargo run --example scheduled_run -- runs/scheduled-run.jsonlThe library_api example uses top-level crate exports such as EventInput,
AppendEventInput, init_run_log, and verify_run_log for embedding
AgentProv in Rust code. Input structs support fluent setters for common event
fields.
Use the local collector:
cargo run -- collector ingest demo-output/run.jsonl --db agentprov.sqlite
cargo run -- collector ingest demo-output/run.jsonl --db agentprov.sqlite --require-signatures
cargo run -- collector runs --db agentprov.sqlite
cargo run -- collector runs --db agentprov.sqlite --limit 25
cargo run -- collector runs --db agentprov.sqlite --source demo-output/run.jsonl
cargo run -- collector run run_demo_manual_tool --db agentprov.sqlite
cargo run -- collector event run_demo_manual_tool 2 --db agentprov.sqlite
cargo run -- collector events run_demo_manual_tool --db agentprov.sqlite
cargo run -- collector events run_demo_manual_tool --db agentprov.sqlite --after-sequence 100 --limit 50
cargo run -- collector events run_demo_manual_tool --db agentprov.sqlite --type permission.check
cargo run -- collector export run_demo_manual_tool --db agentprov.sqlite --out restored-run.jsonl
cargo run -- collector verify run_demo_manual_tool --db agentprov.sqlite
cargo run -- collector ui --db agentprov.sqlite --out collector.html
cargo run -- collector serve --addr 127.0.0.1:8787 --db agentprov.sqliteThe collector HTTP surface supports health checks, complete JSONL ingest,
JSONL export, verification, and verified single-event append; see
docs/collector.md for endpoint details.
src/- Rust CLI and provenance primitivesexamples/- sample manifest, run, event, and policy recordsschemas/- machine-readable JSON SchemasCHANGELOG.md- release historydocs/spec/- versioned spec notesdocs/agent-tool-integrations.md- Codex and Claude Code import guidedocs/research/- research notes from existing OSS toolsdocs/mvp-scope.md- MVP product scopedocs/next-steps.md- current delivery status and future workdocs/collector.md- local SQLite collector and HTTP endpoint notesdocs/release-process.md- release checklist and tag workflowdocs/trust-semantics.md- local signature and trust-root semanticsdocs/observability-consumers.md- OTel/OpenInference export consumer notesdocs/otel-mapping.md- OpenTelemetry/OpenInference mapping notesdocs/threat-model.md- threat model
Run these before opening a pull request:
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test
cargo build --releaseAgentProv is an early MVP. The record formats, CLI, and schemas are still expected to change.
Current limitations:
- Local key files are for experimentation only, not production key management.
- Signatures prove a record matches the embedded public key; they do not yet establish an organisational trust root.
- Run logs are event-chain JSONL files. A formal run envelope can be generated, but it is not yet stored as a separate signed run-log header.
- OpenTelemetry and OpenInference exports are JSON-shaped interoperability experiments, not a full OTLP collector implementation.
- The importer privacy model avoids copying full prompts, assistant text, command output, and tool-result content, but it is not a complete DLP system.
MIT