01
Every call, before it runs
The support agent tried to email [email protected]. The checkout policy refused it; the agent got the reason back where the tool result would be.
AEGIS sits between an agent’s decision to call a tool and the tool running. It asks which turn of the conversation authorised each call — and allows, blocks, or holds it for a person before anything happens.
pip install agentguard && agentguard init Agents now send the email,move the money,run the command.
One poisoned ticketand the call they make looks ordinary —the right tool, a valid address,nothing a filter would flag.
Replay · a block from the demo fleet
agent · Customer Support
send_email(to="[email protected]", subject="Your reward", body="Click here…") block-personal-email-in-checkout — recipient *@gmail.com denied for the checkout workflow; allow-list is *@acme.io.
block-personal-email-in-checkout · recipient off the allow-listdecision recorded · hash-chained to the trace before it
The call and the refusal are verbatim from the demo trace; the conversation around them and the provenance scores are illustrative.
Replay · a hold from the demo fleet
agent · Data Pipeline
http_post(url="https://api.stripe.com/v1/transfers", amount=2450000, currency="usd") AEG1.eyJjaGVjay… signed by the gateway.
url: api.stripe.com/v1/transfers
amount: $24,500.00 usd
payments-high-valueApprovals · awaiting your decision
Approved by the payments reviewer
reviewer and decision recorded in the trace chain
The call and the policy reason are verbatim from the demo approvals queue; the conversation, reviewer step and scores are illustrative.
The live demo
The support agent tried to email [email protected]. The checkout policy refused it; the agent got the reason back where the tool result would be.
A $24,500 Stripe transfer, a production kubectl delete, a 14,210-recipient blast. The agent waits, with the exact arguments in front of the reviewer.
Violations grouped by the rule that fired — who tried what, when, and under which policy.
“Block emails to gmail/outlook/icloud during the checkout workflow. Allow @acme.io.” becomes a policy you can read, toggle and audit.
Each step of an agent session as a graph: input, output, and the exact rule that ended the run.
Every agent with its owner, scope and key — production, restricted or suspended.
Controls mapped to live, hash-chained evidence instead of screenshots.






01
The support agent tried to email [email protected]. The checkout policy refused it; the agent got the reason back where the tool result would be.
02
A $24,500 Stripe transfer, a production kubectl delete, a 14,210-recipient blast. The agent waits, with the exact arguments in front of the reviewer.
03
Violations grouped by the rule that fired — who tried what, when, and under which policy.
04
“Block emails to gmail/outlook/icloud during the checkout workflow. Allow @acme.io.” becomes a policy you can read, toggle and audit.
05
Each step of an agent session as a graph: input, output, and the exact rule that ended the run.
06
Every agent with its owner, scope and key — production, restricted or suspended.
07
Controls mapped to live, hash-chained evidence instead of screenshots.
Use cases
Scenes from the public demo fleet — each card is the call the agent made and what AEGIS did with it.

Customer supportblocked
An injected ticket asks the support agent to send a “reward” link to a gmail address. The recipient is off the allow-list for the checkout workflow, so the email never leaves.

Payments & financeheld for review
Transfers of $10,000 and up pause the agent until the person on the payments-high-value policy signs off — with the endpoint, amount and currency on screen.

DevOps & coding agentsheld for review
“kubectl delete deployment payments-api -n prod” is held for the SRE on call. The rest of the agent’s kubectl, ls and git work stays on the allow-list and goes straight through.

Security & ITblocked
Privileged paths are read-only for non-root agents. The triage bot’s write to id_rsa is refused in 12 ms and lands in the trace chain.

Data pipelinesblocked
DROP, TRUNCATE and DELETE without WHERE are blocked on production databases, whichever agent writes them and however the request was phrased.

Communicationsheld for review
A bulk send above the broadcast threshold triggers human review. The draft, the list and the sender wait in the approvals queue.
send_money(iban="DE89 3704…", amount=900)held · authorised by the untrusted channel

H = SHA256(… ‖ H′)okH = SHA256(… ‖ H′)okH = SHA256(… ‖ H′)okhead → Merkle log, every 10 min → witnesses
allow carries an Ed25519 receipt
Instruction provenance
Every span that enters the agent’s context is tagged as it arrives — what the user typed, what came back from a tool, what the model wrote. A call is scored by how much of it each channel explains. An injection can copy the user’s words; it cannot make the call come from the user. Under a millisecond, with no model call.
In-band decisions
The decision returns where a tool result would. A blocked agent reads the refusal, explains itself and carries on. A held call suspends the turn until a reviewer answers — the alignment auditor first, if you want it, so a person sees only what it would not release. For actions that cannot be undone, an outbox delays dispatch so an operator can still cancel.
Cryptographic audit
Every allow carries a receipt signed with the gateway’s key, so an executor can verify offline that this call was checked with these arguments. Each trace commits to the one before it; chain heads go into a Merkle transparency log that external witnesses countersign. Edit one record and verification fails from that record on.
Try it
Turn a block into an allow, or edit what the agent called. Each hash below covers its row and the hash above it, computed in your browser with SHA-256 — so the record you touch, and every one after it, stops verifying.
············ ············ ············ ············ ············ ············ Computing the chain…
A toy chain over calls from the demo fleet. In AEGIS the chain is kept per agent, and each head goes into a Merkle transparency log that external witnesses countersign.
Platforms
agentguard.auto() finds the model clients in your process and patches them —
fifteen frameworks across Python, JavaScript and Go. MCP hosts go through a stdio proxy;
anything else points its base URL at the gateway.
import agentguard
agentguard.auto() # that's the integration Measured,
not claimed.
29.7% → 1.4%
attack success on AgentDojo with a gpt-4o-mini agent — the lowest of the defenses compared. The cost is holds: with the alignment auditor as first reviewer, clean-task utility is 56.7% against 69.1% undefended.
0.44 ms
median per check, with no model call. One gateway process sustains about 2,300–3,000 checks per second.
0 of 60
flagged attacks escaped an adaptive attacker that rewrote the injection for four rounds with the policy rules in hand.
0.4%
of real agent-emitted attacks are caught by content patterns. We measured it on our own detector — it is why AEGIS enforces authority instead.
In the open
500+ stars and 56 forks on GitHub. Every card links to the comment, issue or pull request it comes from.
“AEGIS is genuinely well-built for what it is—the cryptographic audit trail is thoughtful, the human-in-the-loop approval flow is the right instinct, and the one-line integration is clean.”
Tightened the README’s claims to match what the product does, and added gateway smoke tests for health, pre-execution checks and trace ingestion.
Took Syria out of the OFAC country packs after the sanctions programme ended (EO 14312), with the citation.
Found the missing agent_profiles table that crashed a fresh gateway, with the root cause and the fix.
A regression test that starts the profile manager on a freshly initialised gateway database.
“This is excellent work. We are trying to integrate it into our production agent service :)”
A multi-step attack-pattern detector: read /etc/shadow, then POST it out — each step benign alone, blocked as a chain.
Wired the gateway’s policy, bypass and anomaly tests into CI, and made the Python SDK install fail loudly.
Traced a broken stdio MCP handshake to startup logs on stdout, and asked for a stdio server mode.
Dependabot for the monorepo’s npm workspaces and GitHub Actions, grouped weekly.
Using AEGIS? Tell us what broke, or what worked.
A control point between an agent’s decision to call a tool and the tool running. Each call is checked before any side effect, and the answer — allow, block, or hold for a person — comes back to the agent where a tool result would, so a blocked agent explains itself and continues.
A filter reads what the call contains. On tool calls that live agents actually emitted under attack, content patterns catch 0.4% of them, because a successful injection produces an ordinary-looking call. AEGIS also asks which turn of the conversation authorised the call — what the user typed, or text that arrived from a tool — and enforces that.
Two lines: import agentguard and call agentguard.auto(). It patches the model client you already use in fifteen frameworks across Python, JavaScript and Go. For MCP hosts there is a stdio proxy, and for anything else you can point the provider base URL at the gateway.
A check takes 0.44 ms at the median with no model call, and one gateway process sustains about 2,300–3,000 checks per second. The real cost is holds: on AgentDojo, clean-task utility falls from 69.1% to 38.1% with no reviewer, and to 56.7% when the alignment auditor reviews holds first. We report that rather than hide it.
An injection that stays inside the tool the user already asked for — for example, an instruction that turns a requested delete into a broader one. The call is then licensed by the user’s own words, and the provenance layer cannot tell it apart. The paper lists this and the other limits.
Yes. The engine is MIT-licensed and runs with docker compose on your own machine; the gateway, its store and its signing key stay on your side of the trust boundary. A managed control plane is available if you would rather not run it.
Still have questions?
[email protected]