AgentGate

Your agents call tools with real privileges.

Prompt injection, tool poisoning and rug pulls turn those calls into data theft or code execution. We audit the boundary where your agent meets its tools, and show you exactly where it leaks.

48-Hour Agentic Tool-Boundary Audit

$4,500 fixed price, or $6,500 with instrumentation

Gateway decision logred-team audit, 31 Oct 2026
  1. Session A Reads an untrusted web page. Session is marked tainted.Correct: tainted
  2. Session A Writes data.json after a human approval. File label: untrusted.Correct: approved write, labelled untrusted
  3. Session B New session, same disk. data.json now reads as trusted.Wrong: label was lost
  4. Session B send_email with data.json attached.Wrong: allowed, should be held for review
Simplified trace of a critical finding from our audit of our own open-source gateway. Fixed on main (PR #34). Every step passed its local check; the failure only shows across sessions.

This is already happening

Agent security failures rarely come from the model alone. They happen at the tool boundary: a validator that misreads a command, a protocol message nobody inspects, a config file one agent can write for another.

  1. A sed validator bypass in Claude Code allowed arbitrary file writes

    CVE-2025-64755 (GHSA-7mv8-j34q-vp7q): GitHub advisory, OSV record

    Claude Code's command validation could be bypassed with sed features, turning a "safe" text edit into a write anywhere on disk. It was fixed in version 2.0.31 by blocking those sed commands.

  2. MCP sampling lets a malicious server drive the client's model

    Unit 42, Palo Alto Networks, 5 Dec 2025: New Prompt Injection Attack Vectors Through MCP Sampling. Related analysis: arXiv 2601.17549

    A server that issues sampling/createMessage can inject instructions into the client's model to steal resources, hijack the conversation or invoke tools covertly. The arXiv analysis notes that sampling requests carry no origin authentication.

  3. Coding agents can free each other by rewriting shared config

    Embrace The Red, 24 Sep 2025: Cross-Agent Privilege Escalation, with commentary by Simon Willison

    On a shared workspace, one agent writes another agent's .mcp.json, AGENTS.md or editor settings, which loosens its permissions.

  4. Argument injection turns pre-approved commands into code execution

    Trail of Bits, 22 Oct 2025: Prompt injection to RCE in AI agents

    Agents that allowlist "safe" utilities can still be steered into dangerous flags on those utilities. The write-up recommends -- argument confinement and narrow facades.

What the audit covers

Seven tool-boundary areas. Each maps to a validator in our open-source reference gateway, so every test has a working model behind it and a concrete fix design in front of it.

Registry pinningValidator R
Are tool schemas and descriptions pinned, and does a silent change (a rug pull) revoke trust? Includes Unicode lookalikes and hidden instructions in tool descriptions.
Workspace and shell confinementValidators W and S
What each allowed command actually does on disk: copies, moves, in-place edits, symlinks, redirects and permission changes. Protected config paths such as .git, .mcp.json, AGENTS.md, CLAUDE.md and .vscode. Arguments are canonicalized and confined behind --.
Taint and information-flow labelsValidators T, F and P
Once a session reads untrusted content, does the taint follow the data through files, workflows and approvals, and does it survive into the next session?
Exfiltration and encoding evasionValidators I and Z
Can a protected value leave in reversed, shifted, XORed, interleaved, hex, base32 or base64 form? We measure match coverage against the real matcher thresholds and report the transforms that get through.
Return-channel secret scanningValidator D
Secrets that arrive in tool results get pinned so they can't be sent back out. We test capacity limits, secrets split across fields, and whether the pinning runs on every transport.
Budgets across subagentsValidator V
When an agent forks subagents, do their combined actions stay within one budget? Vector-clock accounting across fork and join.
MCP protocol and transport desyncMCP wire proxy
JSON-RPC id matching, error responses, id reuse, batches, duplicate keys, parser differentials, and server-initiated sampling and elicitation requests. Anything that reaches the model without being inspected.

The kind of thing we find

These five findings come from a red-team audit of our own gateway on 31 October 2026, not from a client engagement. Each was reproduced against the code. The two critical findings include a short trace. The high findings state what is on main and what is still open. Working exploit code is not published.

CriticalCross-session taint lossAn untrusted file becomes trusted when a new session starts.

Trace

  1. Session A reads untrusted content and is correctly tainted.
  2. With a human-approved write, Session A creates data.json, labelled untrusted.
  3. Labels lived only in Session A's memory. Session B, on the same disk, sees data.json as trusted.
  4. Session B emails the file out, and the gateway allows it. Shell redirects were not recorded in the provenance ledger either.

Fix

File labels now persist across sessions in an append-only, hash-chained store. With a directory bound, a file with no record that is not older than the store epoch is untrusted.

Residual risk: network filesystems without stable inodes need a path-and-hash fallback.

Status: fixed on main (PR #34).

CriticalJSON-RPC id desyncA response with id "7" instead of 7 skips inspection.

Trace

  1. The proxy matches responses to requests by their serialized id.
  2. The client sends request 7. A malicious server replies with "7" or 7.0.
  3. The lookup misses, so the proxy forwards the response unchanged. The prompt injection inside is never scanned and the session is never tainted.
  4. Error responses, a reused id, list and subscribe methods, and server-initiated elicitation requests also pass without inspection.

Fix

Request ids stay null, string, or int, with no coercion between those forms. A response whose id is not in flight is not forwarded, malformed and reused ids are rejected, and every response that reaches the model is scanned, including errors.

Residual risk: a peer that stringifies an id has that response dropped rather than inspected. Pin one codec so ids are not rewritten between hops.

Status: fixed on main (PR #34).

HighIn-place edit launders file labelsAn allowed file edit can strip a file's sensitivity label.

The bug class

An allowed in-place edit that replaces a file's underlying inode can leave its sensitivity label behind, so a protected copy can later be sent out.

Fix design

The broker that ran the command publishes an old-to-new inode map, and labels move with it. Edited files are keyed by path first. The read-write <> redirect is rejected.

Residual risk: any utility that replaces an inode without the broker observing it.

Status: fixed on main (broker inode and rename maps on rebase).

HighSecret-store pin-stuffing and split secretsThe inbound secret store can be filled up or sidestepped.

The bug class

A tool result an attacker controls can exhaust the secret store's fixed capacity, and secrets split across fields can avoid being pinned at all.

Fix design

Separate evictable soft pins from non-evicting hard pins. Join adjacent fields before enrollment, and check outbound fields concatenated. When hard capacity is reached, raise a human-review lead and forward a redacted body.

Residual risk: secrets split non-adjacently with delimiters can still evade; these surface as review leads.

Status: pin-stuffing fixed on main (separate hard and soft stores). Split secrets: fix designed, not yet merged.

HighEncoding evasionReordered or encoded secrets can slip past the exfiltration matcher.

The bug class

Some byte reorderings and common text encodings keep a protected value below the exfiltration matcher's similarity threshold.

Fix design

Decode hex, base32, base64 and percent-encoding to a fixed point (at most four rounds), de-interleave strides 2 to 4, prefilter on byte histograms, then run the existing checks. Cost is O(n·k).

Residual risk, stated plainly: no finite matcher catches arbitrary encodings. What the fix doesn't catch becomes a human-review lead.

Status: stride, hex and base64 forms fixed on main. Other encodings remain out of scope.

48 hours, start to finish

The clock starts when scope is agreed and access is in place.

What you get

  • A written report you can hand to engineering and leadership.
  • Severity-ranked findings, each with a reproducible trace.
  • Fix designs for each finding, in deterministic, standard-library-only Python where code applies, with complexity and residual risk stated.

Audit

$4,500

Everything above, fixed price.

Audit with instrumentation

$6,500

The audit, plus a localhost lab gateway pass, an offline analyzer run on a log you authorize, and canary and deception configuration for your environment.

Those two are the top of a fixed-price ladder. The rungs under them are in Services.

Services

Fixed prices, delivered by one person as a PDF, source files, or a pull request you review. Nothing is deployed on your hosts. Not a penetration test, not a certification, and not legal advice. No client list is published.

The usual path is a $149 check, then a $450 build or a $950 review, then the $1,500 drop-in, then the $4,500 audit, then $395 a month or the $2,500 quarterly refresh. The $1,800 exposure diagnostic, the +$2,500 integration blueprint, and the +$750 briefing call are unchanged.

24 hours

MCP Permission Quick Check

$149

For a team running one to five MCP servers in Cursor, Claude Code, or Claude Desktop.

  • Review of up to 5 configs you send (mcp.json or claude_desktop_config.json), secrets removed. Max 60 tools.
  • Each tool classed as read, write, send, or credential use.
  • Flags for plaintext tokens, over-broad scopes, and tools that read untrusted content and can also write or send.
  • A one-page PDF with the top 5 fixes ranked.

Config and tool-manifest review only. No code review, no runtime testing, no access to your systems, and no fixes applied. Add-ons: +$49 per extra 5 servers; +$99 for a 20-minute call.

Book the Quick Check

4 business days

Starter MCP Server Build

$450

One internal API or database, with read-only defaults.

  • An MCP server in Python or TypeScript for one system. Stdio, plus Streamable HTTP if you ask.
  • Up to 4 tools. At most 1 write tool, behind an explicit confirmation argument.
  • API-key or bearer-token auth through environment variables.
  • Allow-listed endpoints or tables, input schemas, output caps, and secret redaction in logs.
  • Tests for each tool and the deny paths. A README for Claude Desktop, Cursor, and Claude Code.
  • 1 revision within 7 days of delivery.

Out of scope unless you add it: OAuth, multi-tenant auth, hosting, more than 4 tools, more than 1 write, and delete, refund, or bulk-export tools. Production credentials are never used. Add-ons: extra read tool +$60 (up to 8 tools); extra confirmation-gated write +$100; OAuth 2.1 for one provider +$300; Dockerfile and deploy guide (you deploy) +$150; 48-hour rush +$150; extra revision +$75. A policy wrap and hash-chained audit log is the $750 build.

Book the Starter Build

48 hours

Hardened MCP Server Build

$750

The same one-system build, when you need writes and an audit trail. $350 at kickoff, $400 when the acceptance tests pass.

  • One system (Postgres, Stripe, HubSpot, Slack, or an internal REST API) on the reference blueprint, wrapped in allow / deny rules.
  • Sensitive-field redaction and a SHA-256 hash-chained audit log.
  • A pytest acceptance suite, delivered as a pull request. Nothing is deployed on your hosts.

The clock starts with a test or staging instance, never production credentials, and the tool list. Delete, refund, cancel, drop, truncate, and bulk export stay denied unless you approve one in writing, and an approved one still needs a per-call confirmation token.

Book the Hardened Build

3 business days

MCP Server Security Review

$950

$1,500 for two servers. An outside look at a server you built, adopted, or ship.

  • Code and tool descriptions, read the way the model reads them: injection, over-broad tools, validation, path, URL, and SQL arguments, secrets, and auth.
  • A loopback lab run on test data. Never your production.
  • Findings ranked by severity, each with a concrete fix, plus a SARIF 2.1.0 file.
  • A 30-minute walkthrough, and one re-test of fixed high or critical findings within 30 days.

Up to 15 tools per server. No live production test, no infrastructure pentest, no social engineering, and no compliance attestation. Fixes are recommendations. Add-ons: up to 5 findings as a pull request +$400; extra server +$550; 48-hour rush +$250.

Book the Security Review

5 business days

Agent-Gateway Guardrail Drop-In

$1,500

A deterministic policy layer and a tamper-evident log in front of MCP servers you already run.

  • Configured for up to 3 servers / 30 tools and one agent harness: allow and deny lists, path, URI, and SQL checks, and rules for an untrusted read that can reach a write or a send.
  • Log-only by default. It enforces only deterministic rules the client approves in writing, and only the client switches those rules on.
  • A SHA-256 hash-chained decision log with a verify command, and a CI job that fails on policy regressions.
  • A pull request and a runbook. Your team merges and deploys. A 30-minute handover, then 14 days of config fixes.

No custom validator beyond configuration, no production on-call, and no SIEM integration. Add-ons: extra server +$300; a custom validator +$400; a log-shipping guide +$250. The integration blueprint remains +$2,500.

Book the Drop-In

Monthly

Boundary Watch

$395 / month

For a team that already bought a build, a review, a drop-in, or an audit, and keeps adding tools.

  • A monthly re-run of the audit and SARIF export, delivered within 3 business days of the updated list.
  • Review of up to 5 new or changed tools. No rollover.
  • One small policy or code change, at most 2 hours, and a one-page summary.
  • Email support, with a reply within 2 business days.

No on-call. Month to month, cancel anytime; 2 months recommended. Add-on: extra 5 tools +$150. A quarterly written-note refresh remains $2,500 per quarter.

Book Boundary Watch

48 hours · flagship

48-Hour Tool-Boundary Audit

$4,500

$6,500 with lab instrumentation, then $2,500 per quarter if you continue. A written note for a security reviewer, from a tool list you send.

  • $4,500: the full note, a loopback policy set for your tool list, CI regression machines, and a hash-chained log. Files and a pull request your team merges.
  • $6,500: the same note, plus a lab gateway pass on 127.0.0.1 with simulated backends, and an offline analyzer pass on an authorized log you supply.

Not a penetration test, not a red team of your users, not a certification, and not legal advice. Same-author lab limits are in Method. ATLAS ids on the note are approximate. Production credentials are not accepted, and the gateway is not installed on your hosts. The $1,800 Tier 1 diagnostic stays a separate booking.

Full terms: audit-offer.md. The Apache-2.0 code stays free either way.

Why AgentGate

We test against a working reference, not a checklist. AgentGate is an open-source (Apache 2.0) policy gateway that sits in an agent's tool loop. It is deterministic and built on the Python 3.12 standard library only. Its validators are opt-in and inert until attached, so each one can be read, tested and reasoned about on its own.

When the gateway sees untrusted input, it taints the session and attenuates the agent's capability so egress can't be turned back on. Held calls go to a human. We audit your stack with the same model, and our fix designs are written to the same bar.

We focus on three areas that get less attention than prompt injection itself:

  • JSON-RPC and MCP transport desync: the gap between what a proxy inspects and what a client or server actually accepts.
  • Vector-clock budgets across subagents: keeping forked agents inside one combined budget.
  • Canonical argument confinement: deciding on the arguments a tool will really receive, not on the string the model wrote.

Methodology, and what we don't claim

Test counts are reported as recorded, with the code revision they came from. Where a figure wasn't re-run, we say so.

Gateway test suites (31 Oct records, re-measured 1 Nov 2026)
Code revisionContentsTests
main @ af43afeGateway through v12.1796 collected
PR #33, now on mainValidators R, W, F, I874 collected
4425bdd, now on main (before round-2)Full validator set R–Z1,082 collected; 1,076 passed, 6 skipped. Re-run 31 Oct with php present: 1,082 passed
Round-2 audit fixes, on main via PR #36R–Z plus fixes to V, S, T, D and Z1,122 passed (31 Oct record, Python 3.12.3)
main @ 2dbca57 (PR #36)R–Z with round-2 fixes, plus C, E, B, A1,165 collected; 1,159 passed, 6 skipped (1 Nov, Python 3.12.3, no php). The 31 Oct record counted this suite as 1,165 passed
This branch: PR #34 onto mainPR #36 tree plus cross-session labels and canonical MCP ids1,178 collected; 1,172 passed, 6 skipped (1 Nov, Python 3.12.3, no php; the skips are PHP parity)
PR #42 onto mainPR #34 tree plus shell / staged-collusion guards and URI / path normalization1,245 collected; 1,239 passed, 6 skipped (2 Nov, Python 3.12.3, no php; the skips are PHP parity); 1,245 passed with php
agent-watchLog detector and localhost honeypot514 collected. 1 Nov, with requirements-dev.txt: 512 passed, 2 skipped. The 31 Oct machine: 510 passed, 4 skipped
v14 reference packageFour bounded reference validators33 passed, per its own validation record (not re-run)

The validator layer: R ∧ W ∧ F ∧ I ∧ P ∧ T ∧ S ∧ V ∧ D ∧ Z ∧ C ∧ E ∧ B ∧ A

Fourteen bounded, deterministic predicates in the Python 3.12 standard library. A call is admitted only if every attached predicate admits it; each one is inert until a trusted adapter attaches its state, and state is committed only after all of them pass. Denials use JSON-RPC codes -32066 through -32080. The p99 column is the isolated benchmark case for that predicate (wall time, 5,000 samples, one Linux container, re-run 31 October 2026 with the round-2 fixes and v14), not a production figure.

Reference validators in the v14 tree
PredicateCodeInvariant it enforcesp99 (ms)
R registry_pin_validator.py-32066, -32067A changed, invalid or removed tool descriptor stays revoked. A bare tool name claimed by two servers is never resolved by arrival order.0.001
W workspace_path_validator.py-32068Shell syntax outside the model fails closed. No write reaches a protected name or an inode alias of one. Executes nothing.0.891
F lattice_flow_validator.py-32069Contamination only rises. Each precommitted workflow step runs at most once, in DAG order.0.024
I shingle_similarity_validator.py-32070Outbound text whose longest common subsequence covers 85% of a pinned value is denied, under two pinned normalizations.2.495
P linear_obligation_validator.py-32071A 16-place Petri net never mints tokens; no egress while a cleanup place is non-zero.0.022
T symbolic_fs_transducer.py-32072File labels only rise; non-public data never feeds egress and untrusted data never feeds execution. Committed labels persist in a hash-chained sidecar, and a broker rebase carries them onto a replacement inode or a renamed path.0.564
S canonical_argument_confinement.py-32073Equivalent argument objects reduce to identical bytes, so spelling can't carry hidden bits. No operand reaches an option position.0.589
V fork_join_vector_validator.py-32074Forked subagents spend one conserved root budget, fenced by vector clocks; taint flows along forks and joins.0.052
D dynamic_ingression_validator.py-32075Secrets first seen in a tool result are enrolled before the agent sees them. Trusted credential values are never evicted; heuristic finds rotate oldest first, so an untrusted response can't lock the store. Outbound text covering 85% of one is denied.0.845 in, 0.316 out
Z transform_invariant_validator.py-32076Pins match under a finite transform family (reversal, +k, XOR-k, Caesar, acrostic, 4-byte blocks, stride-2/3/4 interleavings) and inside hex and base64 runs. D's trusted enrollments extend Z atomically. Over-budget queries are denied whole.2.247
C causality_laundering_validator.py-32077A file created, deleted or renamed, or a status set, on a branch whose decision depended on untrusted data carries that label, tombstones included; whoever probes, lists or reads it is tainted before the call is authorized.0.031
E event_channel_capacity_validator.py-32078Which eligible tool and structural options a call picks can carry at most a budgeted number of bits per sink, counted exactly in quarter bits while the session is tainted or holds live secrets. Support accounting, not KL divergence.0.004
B blindfold_opaque_fault_validator.py-32079Refusals can be sealed into one identical envelope with a signed private receipt. A retry within 25–99% 4-gram overlap of a refusal locks that branch; the lock lifts itself after 15 minutes and goes to human review.2.367
A reachability_confinement_validator.py-32080A call must be a next step on a workflow path that can still finish with every obligation discharged and, once tainted, no forbidden step. Revoked steps stay revoked.0.005

With all fourteen attached, the combined dispatch case measured 8.28 ms at p99 (5.67 ms for the first ten), above the 5 ms reference on that host. B is the costly one at its bounds: a 2048-byte request against 32 remembered refusals. A finite matcher catches only the transforms it models; see the encoding sample finding above.

2025–2026 literature crosswalk

How the validator layer relates to seven recent papers, compared against each paper's abstract or overview as of 31 October 2026. This is not a systematic review.

AgentGate against recent work
WorkWhat it doesHow AgentGate relates
CaMeL, Debenedetti et al., arXiv:2503.18813Separates trusted control flow from untrusted data with a custom interpreter and capabilities on values.AgentGate gates at the tool boundary and doesn't rewrite the agent's planning. It doesn't provide CaMeL's control/data separation; F and S are the closest pieces.
FIDES, Costa et al., Microsoft Research, arXiv:2505.23643A planner tracks confidentiality and integrity labels, enforces policy deterministically, and hides low-integrity results in variables.T applies the same kind of (confidentiality, integrity) labels to the file effects of shell commands and file tools, a different surface from planner variables.
Progent, Shi et al., arXiv:2504.11703A policy language for tool-level privilege control, enforced deterministically at runtime.Same enforcement point. AgentGate uses fixed predicates rather than a policy language; A adds path-qualified pruning over a workflow DAG, and V one conserved budget across forked subagents.
ToolGate, Liu et al., Findings of ACL 2026Hoare-style pre- and postcondition contracts over a typed symbolic state gate each tool call.P's Petri net is a comparable pre/post gate over a bounded marking; S canonicalizes arguments before any check sees them.
Whispering Agents, Huang et al., arXiv:2508.02188A covert channel hidden in agent dialogue through storage, timing and behavior; the paper reports its tested detectors couldn't find it.E budgets exactly this selection channel per sink, and S removes spelling freedom from arguments. E bounds what a sender can choose; it doesn't detect that protocol.
Memory Provenance Laundering, Xu et al., arXiv:2607.29167Memory consolidation can erase a low-trust source; a middleware firewall keeps platform provenance and gates risky calls on it.C applies the same idea to file names and statuses, tombstones included. T persists file-effect labels in a hash-chained sidecar so a later session on the same workspace loads them. The state directory is trusted storage.
Blindfold, Zhu et al., arXiv:2610.37055Randomized audit certificates are biased if the agent can observe the audit coin, including through timing.B seals refusals into one envelope so their reasons don't leak, and quarantines near-neighbor retries. AgentGate doesn't run randomized audits, and its own timing as a side channel hasn't been evaluated.

Of these seven, none describes labels on the file effects of shell commands (T), canonical argument bytes with -- operand confinement (S), or a budget conserved across forked subagents (V). That is a statement about these seven papers, not the whole literature. T now persists labels across sessions; a replacement chain that hashes cleanly is not caught, which is the same class of residual as the provenance work above.

  • This is a reference design, not a deployed product. AgentGate is not a penetration test, a certification, a production WAF or an OS sandbox, and we make no detection-rate claims.
  • Evaluation cohorts are synthetic and written by the same author as the detectors. They show the code does what it says on those cases. They don't measure recall against an unknown adversary.
  • Benchmarks use test doubles. In the v14 reference package, the combined timing runs real code for some validators and stand-ins for the rest, so it is not a full-pipeline latency figure. In-memory cases measured below 2 ms at p99. The durable SQLite path measured 2.9 ms at p99, which exceeds that objective.
  • We can't promise a false-positive rate on natural text. A benign message can be an anagram of a protected one, so no distribution-free bound exists. A 10,000-message synthetic smoke test produced zero hits, which is a fixture result, not a corpus study.
  • Property-based tests find counterexamples. They are not proofs. The gateway suite has 23 Hypothesis state machines (counted in the test files on 31 October). The 31 October re-run used Hypothesis 6.140.0 rather than the pinned 6.170.9.
  • MITRE ATLAS technique IDs in reports are approximate mappings.

Questions

What's in scope?

The tool boundary of your agent system: which tools and MCP servers your agents can call, what they can read and write, what can come back into the model's context, and what can leave. It isn't a general pentest of your infrastructure or a review of model quality.

What do you never do?
  • We don't recommend automatic blocking. Detection leads go to human review.
  • The only automated action in our reference design is a 15-minute freeze of a registered internal agent credential. It lifts on its own and pages a human.
  • We never deploy honeypots on the public internet. Ours binds to localhost, and contact with a canary is treated as a lead, not proof of intent.
  • We don't push to your repositories. Fixes come as designs or pull requests that you review and merge.
  • We don't hand over exploit kits. Traces show the mechanism and how to fix it.
Is this a penetration test or a certification?

No. It's a focused engineering audit of the agent tool boundary. You get findings and fix designs, not a compliance attestation.

Find out where your agents' tool boundary leaks, in 48 hours

Tell us what your agents do and which MCP servers they talk to. We'll reply with scope and a start time.

Email to book an audit