A real audit log, checked by your browser just now
bundle.jsonRecomputing every hash…
Open source, Apache-2.0Self-hostedNo phone-home
Primary Path pauses an agent's consequential actions until a person with the right role approves them, with the agent's full reasoning in front of them. Every run lands in a hash-chained, signed log that your auditor checks on their own machine, without trusting you or us.
Recomputing every hash…
The problem
Refunds, rollbacks, record exports: most teams guard them in one of three ways, and each one breaks in a predictable place.
Works until the one refund that was fraud, or the rollback of the deploy that was fine. The log tells you afterwards. It can't stop anything.
"OK to roll back checkout?" gets a thumbs-up from someone who saw one line, not the agent's evidence. Six months later nobody can prove who approved what.
Every team writes its own pause, queue and audit table. The table is rows in a database the operator controls: to an auditor, a promise rather than proof.
How it works
The agent sends the action it wants to take: tool, exact arguments, and its reasoning.
The run waits, durably. The agent or the server can restart and the case is still there.
A person with the right role approves, rejects with a reason, or sends it back, in the inbox, Slack or Teams.
The agent gets the decision. An approval carries a signed, single-use grant bound to that exact action.
Every step is a hash-chained, signed record. Anyone can verify an export offline, and tampering names the record.
It doesn't run your agent and doesn't care what it is written in. Any agent that can make two HTTP calls can be governed: one to propose, one to learn the decision.
For LangGraph, the OpenAI Agents SDK, the Claude Agent SDK and drangue there is a package that uses the framework's own pause. For tools over MCP, a gateway sits in between and the agent needs no changes. Integrations
# 1. propose: the run pauses POST /api/approvals {"run_id": "run-42", "call_id": "step-7", "tool": "send_wire", "arguments": {"amount": 90000, "to": "ACME GmbH"}, "reasoning": "Invoice INV-311 matches the PO."} # 2. poll until a person decides GET /api/approvals/run-42:step-7 {"status": "granted", "reviewer": "m.okafor", ...}
See it run
A support agent gets a claim for an €840 espresso machine that "never arrived". It was signed for at the door, and the account is 22 days old. The agent's small-refund tool refuses anything over €100 in code, so it escalates. The reviewer rejects it with a reason, and nothing is paid.
pip install primarypath-demos primarypath-demo refunds
An on-call agent works an incident: error rate, logs, recent deploys, the runbook. It can investigate alone, but rolling back production waits for the on-call lead, who sees the whole investigation and approves. The approval comes with a signed grant for that exact version.
primarypath-demo sre
Use cases
Refunds, payouts, credits and wires above a limit: two approvers for large amounts, approval limited to your finance group's IdP group, and a rejected payment that provably never ran.
read →Rollbacks, deploys, scaling and deletes: the diagnosis, the approval and the grant in one signed chain, with routine actions earning autonomy from their track record.
read →Exports, disclosures and access grants: who approved each one, of what, to whom and why, in a record nobody can edit without the chain showing it.
read →Run it
You need Docker. The compose file pins the signed image by digest and starts Postgres beside it, on this machine only.
Everything else: Helm, the Python and TypeScript packages, and how to verify what you download.
curl -fsSLO https://github.com/om-er/primarypath-releases/releases/latest/download/docker-compose.yml
docker compose up -d --wait
# open http://127.0.0.1:8123python3 -m venv demo && . demo/bin/activate pip install primarypath-demos primarypath-demo refunds
On Apple Silicon, run the stack under amd64 emulation: Install has the one extra flag.
Built to be checked
primarypath-verify re-proves an export on an air-gapped machine against a key you pinned.