Delegated authority

Bound before it runs.

An agent can only do what a person granted. Each routed call is allowed, redacted, held, or refused before it lands. Silence means no.

Logging tells you afterwards. Agent finders map the fleet. PyxGrant decides first: refuse the hop, hold the path to the sink, and print the call that went around it. A signed receipt comes with the decision — it is not a substitute for stopping the call. A call that never reaches it is named later, not stopped.

Where we built for depth

Not another agent finder. Not a log you read after the fact. The usual stack scores a hop and writes a dashboard. It does not hold the path to the sink, bind the bytes that run, read back from anyone but the actor, name the miss, or let a skeptic verify the refusal without the vendor. The set below is live control — authority that can only narrow, a decision on the path before the sink, dual-control holds, and a freeze that reaches every plane — shipped together in one binary. The shortlist public pages did not describe that stack together when we last read them. Receipts come with the decision; they are not the product.

  1. Refuse the hopAllow, redact, hold, or refuse before it lands. Silence means no. A dashboard after the fact is not this.
  2. Hold the pathUntrusted content walking to an irreversible or egress sink is held or refused under hardened — not only each hop scored in isolation.
  3. Name the missCompare what we allowed with the provider's export. The hop that never reached us is printed. Absence can be signed when coverage is complete.
  4. Verify without usA skeptic checks the signed receipt on a pinned key. Prove it in this tab. Embedded-key verify is integrity, not authenticity, until you pin.
  1. A grant can only narrow.A partner can re-delegate without a shared secret, never widen it. Revoking the parent ends every child grant and every bound session. tools/list is filtered to the tools that grant allows — the agent never sees a capability it was not granted. Authority is the control plane, not a note in a log.
  2. The path, not only the hop.Untrusted content that entered the session can walk to an irreversible or egress sink. A poisoned resources or prompts read, or a notification, taints that path the same way a tool result does. Under the hardened profile the path is held or refused until a person breaks it. The operator sees which source tainted the path. An operator can also name an ordered sequence of tools; completing it is held or refused. A hold can preview the next hop when the connector can dry-run. pyxgrant unwind runs verified inverses; what cannot be compensated stays on the desk. pyxgrant demo -consequence-close walks a clean post, a scorer-miss read, then the same sink refused on provenance — synthetic estate, stated in the command. That walk is the Go binary, not the in-browser Try (still 2.900 WASM).
  3. Freeze every plane.One command holds tool, model, A2A, and AG-UI traffic — including sampling and elicitation responses already in flight, and mid-stream, tool-result, and A2A-response legs. Freezing a parent grant expands over the grant lineage, so child-bound legs on those planes are held too. Resume is reversible. Revoke is not. Console Assurance can replay the signed session and seal a recovery drill without running undos.
  4. N keys, and what they saw.A rule can require N distinct Ed25519 approver keys, each bound to the exact payload and to the rendering shown to the person. The Slack and Teams card shows a prefix of that shown hash. A shared-secret HMAC name does not count toward a quorum. The first valid deny refuses the call. Silence means no.
  5. FinOps on the hop.The model proxy meters cost and rate per identity. A spent budget is refused before the provider. A spike can freeze the grant. pyxgrant payback lists prevented events you can re-derive — a spawn refused, a herd block, a cache hit — as exact counts or labelled estimates, not your invoice. payback prove dumps that ledger as an offline pack. LLM cache hits book avoided tokens as labelled estimates. showback -by grant -rollup folds child spend into the parent. This is not a SIEM or SOAR. Accounting-uncertain stays recorded. FinOps →
  6. Prompt injection, then the consequence.Inbound text is scored with patterns and a local classifier. Prompt injection is not solved; new phrasing can pass. Under the hardened profile, untrusted content that then walks to an irreversible or egress sink is held or refused; injection then an outbound call is blocked even without the lethal-trifecta private-read; flag-level ingress injection is blocked, not recorded-and-allowed; a memory write that launders an untrusted directive is refused; an injection-driven block kills the grant on the request, the tool result, the error, and sampling. On the model plane, a tainted run that forces a tool call is refused before forward. A strong hit on any plane quarantines a fingerprint the others refuse. pyxgrant laptop -apply installs the managed hook and starts hook-daemon -engine -profile hardened. On Linux 6.7+ it launches the agent under Landlock. It does not pass -admin-approval; Command Center hold is a separate daemon flag. Windows discovers that daemon via hookpep.win.json. pyxgrant launch -confine, -confine-fs, and -deny-net bound a Windows child (job object, AppContainer, WFP) — not Landlock, and not a wrap of the whole laptop. A bare subprocess is still a smaller PEP. Pinning and a human hold sit behind the score. How it decides →
  7. The bytes that run are the bytes approved.After allow, a mutated MCP, model, or A2A payload is refused. A valid approval with the wrong payload hash does not release the hold. The signature can bind the rendering shown, not only the bytes that will run. Only hops that hit the gateway.
  8. After the act, more than the actor.A tool's ok:true is not enough. Declarative HTTP read-back, then N-of-M across independent providers. Too few confirmations is unverifiable and fails closed under hardened. A confirming read-back can mint a signed PhaseVerified receipt that closes the loop.
  9. Kill names what died.Kill freezes the grant across tool, model, A2A, and browser serve. Memory Forget and RAG content-hash CRL when those stores are on. Grant-kill certificates go into the evidence pack and verify offline. Provider drop is kill:probed or UNVERIFIABLE — not a silent “killed.” IdP revoke is not claimed without a connector.
  10. Pay only the approved cart.A swapped cart, a line-item swap at the same total, a tainted cart, or an amount over the cap is refused before your rail moves money. An opt-in signed payment mandate binds the cart so a goal from the environment is not enough. The model cannot talk its way past the ceiling.
  11. Name the bypass. Prove the absence.Compare what we allowed with the provider's export and print each action that went around us. noninclusion signs that a declared action did not occur when coverage is complete. Optional coverage-gap quarantine and egress default-deny fail closed when traffic is supposed to go through us. evidence prove hands a skeptic one file, verifies it on a pinned key, and shows that a flipped byte fails. Verify binds the whole decision — principal, grant, verdict — not a detached stamp. Embedded-key verify is integrity, not authenticity, until you pin that key. That closes the loop after a refuse, not instead of one.

Where they are ahead: finding agents across SaaS platforms, and trained-model detection. We say that on Compare. Live authority and refusal is what we built to own. Compare, question by question →

In plain terms
  1. DiscoverWho is running — then the decision, not the map
  2. DecideThe path to the sink, not only the hop
  3. ApproveN keys, bound to what they saw
  4. ContainFreeze every plane; kill names the sinks
  5. ProveName the bypass. Verify without us
  1. FinOpsRefused before the provider; prevented events you can re-derive
  2. Prompt injectionScored, then the path is held — not solved
  3. Sensitive dataSecrets and records masked before the model
Try the real engine

A hostile call. Refused.

This is the product, not a screenshot of a log. Every answer below comes from PyxGrant's own decision engine under its hardened policy — allow, redact, hold, or refuse before the call lands. Switch to live and the engine itself runs in this tab, compiled to WebAssembly. Edit the request. The signature is how you verify the decision; the product is the decision.

Loading…
What the agent tries
Edit the request switch to live to run it
Signed decision receipt
…

Loading…

Tool call
Why
Decided
Receipt
This record
Previous
Signature
Full engine output

In the product, a held call waits up to ten minutes by default for a signed approval. Controls that need the real machine, such as kernel confinement of a wrapped child or Linux egress-cage, aren't part of this demo. The live engine is about 21 MB to download and loads once — it is the 2.900.0 WASM, not the 2.1239.0 shipping kernel. On the binary, pyxgrant demo -consequence-close is the scorer-miss then path-stop walk, with a pack you verify offline. For the skeptic walk in this tab — flip a byte, swap approved args, kill a grant, N-of-M, witness independence — open Prove it →

Where it sits

Start with grants, tools, and coding agents. The rest of the map is labeled.

Each plane is tagged shipped, decision-only, or preview. A pilot starts with coding agents and the MCP tools they load. Pick a plane to watch what PyxGrant does there. Each animation replays a check from the walkthrough and tests, or behaviour read from the code.

Start here

Also in the binary

Not binding on the host

Authority passes down as grants that can only narrow. A partner can re-delegate your grant without a shared secret but never widen it, sensitive methods can wait for a person, and revoking the parent ends every child.

Shippedpyxgrant a2apyxgrant grantProof: pyxgrant demo sections 14 and 15 pass
Where to start

A 30-day Evidence Pilot, observe only.

One team's coding agents and MCP servers. Nothing is refused. You leave with a signed pack a security owner can hand to their boss. Enforcement is a second step, if you want it.

What reaches PyxGrant, and what doesn't →

Deployment

Runs on your machine. A held call that nobody answers is refused.

The four questions every security review asks first, answered before the demo.

01

How does it deploy?

One Go binary on each machine that runs agents, with a Windows service option. Agents reach it four ways, and you can mix them.

  • MCP proxy. In front of each server, over stdio or HTTP.
  • Coding-agent hook. Claude Code and Cursor ask before each tool call. hook generic covers Codex, Gemini, Copilot, Windsurf, Cline, or Aider if the agent (or a wrapper) can shell out first.
  • Decision service. Your own agents ask over loopback.
  • Model proxy. Meters and budgets model API calls.
02

What does it do to speed?

Decisions run inside the binary, from your policy file. No vendor cloud sits in the path, and the optional data classifier runs locally.

  • pyxgrant perf measures decision time on your hardware. We don't quote a number from ours.
03

What if nobody answers?

The call is refused, not waved through.

  • A held call waits for a signed approval, ten minutes by default, then it is refused.
  • A rule can require N distinct Ed25519 approver keys. The first valid deny refuses the call.
  • Approvals are refused until approver signing is set up.
The product's own list of limits →
04

What does it work with?

It sits in front of agent actions and leaves the rest of your stack in place.

  • Identity. Okta, Entra, and SCIM exports, checked against who actually acted.
  • Policy. Open Policy Agent, through a bridge.
  • Secrets. The OS vault: DPAPI, Keychain, or secret-tool.
  • EDR. Keeps the host. PyxGrant decides agent actions and does not replace it.
Evidence

Proof from our own run.

We don't have public customer results yet. The numbers below are from a full Windows run on 26 September 2026, on our machines.

Hostile server walkthrough 90 of 90

checks pass in pyxgrant demo, which starts a hostile MCP server behind the gateway. All 26 sections pass: tool poisoning, rug pulls, poisoned results, confused deputy, blast radius, self-protection, memory poisoning, grant revocation, browsers, payments, and the audit chain among them. No planted secret reached the client or the audit log.

Open benchmark 0 allowed of 45

None of the 45 attacks were allowed. None of the 22 benign calls were flagged. An attack that was only flagged, not blocked, is printed as under_enforced and still counts as caught; we are not guessing that count here. It is our own corpus and small; the 95% range on the allow rate is 0 to 8%.

Test suite 132

Go packages passed go test cleanly. One more package failed once on a Windows temp-folder cleanup and passed on three reruns — we do not call that a clean first pass.

How we measured this →

On the hop

What is enforced when a call is routed through PyxGrant.

Enforced today

When a call is routed through PyxGrant — MCP proxy, coding-agent hook, model proxy, or decision service. A call that never reaches it is outside this list.

  • Tools whose descriptions change after approval are quarantined
  • Secrets and personal data are kept out of tool results and the audit log (no plaintext secret written to the chain)
  • Under the hardened profile, an agent can't rewrite its own MCP config or PyxGrant's policy
  • Under the hardened profile, high blast-radius actions are held or refused before they run
  • A restricted or irreversible tool result on SSE is held until the verdict; a deny on that stream releases no further bytes
  • Revoking a grant ends every child grant, with a signed record

The default profile is lighter on purpose. Path sequence, blast-radius holds, KMS/HSM sealing including PKCS#11 HSM, and the signed root token are hardened-profile controls. Scope and edges: Trust →

Start with one team's coding agents.

PyxGrant is built by Omantiv. A 30-day Evidence Pilot covers one team, its laptops and CI runners, and the MCP servers they use. Observe only; you leave with a signed pack. Company · Request the pilot