
An execution-authority gateway for AI agents and APIs. It intercepts consequential HTTP actions, ask
An execution-authority gateway for AI agents and APIs. It intercepts consequential HTTP actions, ask
Put an authority boundary in front of any agent or API.
AgentSafe intercepts consequential actions and checks whether they are authorized before forwarding them. An agent, an application or a tool sends its HTTP request to AgentSafe instead of the target; AgentSafe captures the action as an intent, asks the Decionis control plane for a decision, and forwards exactly the authorized request once on a claimed single-use grant, holds it for a person, or refuses it, leaving a chained record of each. It decides nothing itself.
brew tap decionis/agent-safe https://github.com/decionis/agent-safe-pipeline && brew install agentsafe
agentsafe proxy \
--upstream http://localhost:3000 \
--port 80805-minute quickstart · Homebrew · Linux · Docker · Kubernetes · Hosted
The installed forms are produced by the release workflow from the first release after
v0.1.4. Until that release, the same commands run from a clone, as the quickstart shows.
Nothing here needs an account: without a Decionis key the gateway runs a local demo authority in the same process, on loopback, with a synthetic policy, and says so on every line.
agentsafe proxy --upstream http://localhost:3000 --port 8080AgentSafe 0.1.0
Gateway http://127.0.0.1:8080
Upstream http://localhost:3000
Mode ENFORCEMENT
Authority local/demo (synthetic policy on loopback; not Decionis)
Failure fail-closed
Routes none named; every unsafe method is governed
Evidence not written; use --verbose or evidence.journalDir
Status READY
Waiting for consequential actions...Send it one request:
curl -i -X POST http://127.0.0.1:8080/payments -H 'content-type: application/json' -d '{"amount": 500}'ESCALATE
POST /payments
Action http.post
Decision ESCALATE
Reason HUMAN_APPROVAL_REQUIRED
Execution HELD
Dossier synthetic-dossier-1
Latency 4msThe caller gets 202 and nothing reached the upstream. {"amount": 50} is ALLOW: forwarded
once, byte for byte, with the dossier id beside the upstream's own answer. {"amount": 5000} is
BLOCK: 403, not forwarded. A GET passes through untouched. Every state has its own heading
and, with a terminal, its own color: ALLOW, BLOCK, ESCALATE, SHADOW, AUTHORITY UNAVAILABLE. --verbose shows the chained evidence lines; agentsafe init writes the
configuration file; agentsafe doctor says what would stop it from governing; agentsafe login
connects a Decionis key, after which the same gateway asks Decionis, in shadow first. The
quickstart is the full walk, and the
CLI reference every command.
…AgentSafe owns ingress and interception, action extraction and normalization, enforcement of the
verdict, claim-before-forward, forwarding, effect evidence, finalization, fail-safe behavior and
the local ergonomics. Decionis owns execution authority: policy evaluation, ALLOW / BLOCK /
ESCALATE, policy versioning, ExecutionBinding semantics, Presence verification, Decision Dossiers,
and the verification of evidence and authority. AgentSafe is not a second policy engine: the local
demo authority is a loopback double of the Decionis routes, named local/demo everywhere, refused
in production.
| State | What happened | The caller sees |
|---|---|---|
ALLOW |
The grant was claimed and the exact request forwarded once | The upstream's response, plus agentsafe-decision, agentsafe-dossier-id, agentsafe-execution |
ESCALATE |
Held for a person; with Presence, a resume asks Decionis again | 202, execution: HELD, a resume path |
BLOCK |
Refused; nothing forwarded | 403 with the dossier that records why |
AUTHORITY_UNAVAILABLE |
Decionis could not be asked; fail-closed refuses, fail-open forwards ungoverned and records it | 503 with Retry-After, never a BLOCK |
SHADOW |
Forwarded unchanged while Decionis recorded what it would have decided | The upstream's response, agentsafe-mode: SHADOW |
What is bound and forwarded, and what each outcome finalizes as, is docs/gateway/http-interception.md; what happens when the authority cannot be reached is docs/gateway/failure-policy.md; the configuration, one schema for every distribution with the precedence flags, environment, file, defaults, is docs/gateway/configuration.md.
One runtime, five ways to run it. The executable, the packages, the image and the chart are built and smoke-tested by the release workflow from the same code; nothing about authority, binding, claim or finalization differs between them.
| Where | How | Page |
|---|---|---|
| macOS | brew tap decionis/agent-safe https://github.com/decionis/agent-safe-pipeline && brew install agentsafe |
macOS |
| Linux | curl -fsSL https://raw.githubusercontent.com/decionis/agent-safe-pipeline/master/packaging/install.sh | sh, or the .deb / .rpm with a hardened systemd unit |
Linux |
| Docker | ghcr.io/decionis/agentsafe:, distroless, non-root, two architectures |
Docker |
| Kubernetes | helm install agentsafe oci://ghcr.io/decionis/charts/agentsafe, one Deployment in front of one Service |
Kubernetes |
| Hosted | agentsafe.decionis.com, the same runtime behind one listener; not live yet |
Hosted |
| From source | git clone, pnpm install --frozen-lockfile, pnpm build, node packages/agentsafe/dist/Cli.js |
Quickstart |
Every install page ends at the same place: send your first governed action.
One legitimate path and eight adversarial attempts against the same boundary, offline, in a few seconds, with every expectation asserted:
git clone https://github.com/decionis/agent-safe-pipeline.git && cd agent-safe-pipeline
pnpm install --frozen-lockfile
pnpm --filter @decionis/agent-safe-example-golden-adversarial demoA treasury agent proposes a USD 250,000 wire, a remote Chief Risk Officer completes a FIDO2 plus liveness ceremony, and exactly one wire executes. Injected authorization fields, a fabricated ALLOW, an asserted approval, a swapped receipt, a post-approval amount change, a replayed grant, 25 concurrent claims, a shadow observation, and an expired grant all fail to execute. The run exits 0 only when that holds. See examples/golden-adversarial-demo, the bank-audience walkthrough in docs/remote-cro-authorization.md, and the receipt semantics in docs/presence-evidence.md.
For a consequential action, in every distribution and in the library alike:
request → normalize intent → enforce-and-bind → ALLOW | BLOCK | ESCALATE
ALLOW → claim-token → forward the exact authorized action, once → capture effect → finalize-token
COMMITTED | FAILED | INDETERMINATE
BLOCK → nothing is forwarded
ESCALATE → nothing is forwarded → Presence, or a managed ceremony Decionis runs → signed approval
evidence → Decionis reauthorization → a new grant → claim → execute once → finalizeAn ESCALATE is never turned into an ALLOW locally, and a Presence approval is never trusted
without Decionis reauthorization. The pages under docs/authority
map each step onto the protocol: ExecutionBinding,
claim and finalize, Presence,
evidence.
{decisionId, dossierId, grantId} binding. A dossier identifier is never an execution credential.Presence supports two explicit integration levels. In DIRECT mode, the trusted executor coordinates Presence and returns the receipt reference to Decionis. In MANAGED mode, the executor asks Decionis to orchestrate Presence and polls Decionis for a terminal status. Both modes require independently signed Presence evidence, exact-intent verification, current-policy re-evaluation, and the same claim-before-handler grant path. Invitation delivery and Presence evidence are never execution authority, and approval cannot revive a five-minute intent after it expires.
The gateway holds an ESCALATE and, with presence.managed: true, asks Decionis to orchestrate the ceremony; a resume through /_agentsafe/v1/escalations/{intent_id}/resume asks Decionis again, and only a fresh ALLOW with a grant executes the held request, once. docs/authority/presence.md says what a receipt establishes and what it does not; docs/human-approval.md and docs/presence-evidence.md are the protocol pages.
See [docs/trust-boundary.md](./docs/trust