Skip to main content

agent-police-gate

Screens what your coding agent is about to run — before it runs it — and keeps a tamper-evident record of every call.

CI License

中文 · Project page · Audit your relay · agent-police

pip install agent-police-gate
apgate install claude-code     # or: apgate install codex

Works in Claude Code and Codex CLI from one implementation — both pass the same PreToolUse payload and accept the same response, so the only per-agent artifact is a few lines of config.

Why

If your agent reaches a model through a third-party relay, that relay terminates your TLS and opens its own connection upstream. It can rewrite every JSON payload in flight, including the arguments of the tool calls your agent is about to execute. No vendor offers end-to-end integrity for tool calls today, so the client cannot verify that the command it is about to run is the command the model produced.

agent-police answers "is this endpoint tampering?" by probing it. This project answers the other half: "should this specific command run?" — inline, on every call, whether or not you ever probed the endpoint.

The attack classes come from Liu et al., Your Agent Is Mine: Measuring Malicious Intermediary Attacks on the LLM Supply Chain (arXiv:2604.08407), which measured 428 commercial relays and found 9 injecting malicious code, 17 touching the researchers' AWS canary credentials, and 1 draining an ETH private key. The paper describes three client-side defenses but does not release them.

What it does

Policy gate Screens each tool call against a rule bundle. Blocks credential exfiltration outright; forces a prompt on high-risk shapes even in YOLO / accept-edits mode.
Transparency ledger Hash-chained, append-only, local. Removing or editing a line breaks verification.
Retroactive rescan apgate rescan re-screens recorded history with today's rules — so an indicator published this week can be run against sessions from last month.

The part that matters most in practice

When you run an agent with approvals off, nothing prompts. The gate puts one prompt back, only for the shapes that actually matter — a script piped into a shell from an unrecognised host, an install redirected to a foreign registry, a URL whose real host is hidden behind a @.

Agent support, as measured

Both agents were tested live, not read about. Two behaviours are worth knowing before you install:

Codex ignores a project-level .codex/hooks.json. Only ~/.codex/hooks.json is discovered, which is where apgate install codex writes. Codex also pins trust to the hook's hash, so run /hooks once to review and trust it — until you do, it is skipped silently.

ask does nothing when approvals are off. With permission_mode: bypassPermissions, Codex ran a command the gate had answered ask on — correctly, since there was nobody to prompt. That makes every ask rule a no-op in exactly the unattended sessions that need it most, so the gate escalates ask to deny when no human is in the loop. An unanswerable prompt fails closed. Set APGATE_FAIL_OPEN=1 if you want the other behaviour.

Honest limits

This cannot tell you the model's original output. A PreToolUse hook sees the tool call after it passed through the relay; it never saw what the model actually produced. So every check here is a heuristic about whether a command looks wrong, never a comparison against ground truth.

The paper measured its own policy gate at 100% bypass by an adaptive attacker. That number applies here too. What a gate like this catches is the generic, non-adaptive rewriting that the 428-relay survey actually found in the wild — which is worth catching, and is not the same as being safe.

Closing the gap properly needs a signed response envelope from the vendor, binding model id, tool name, tool arguments, finish_reason, and a client nonce. No major tool-use API or MCP spec provides one.

How rules stay accurate

Rules are data, not code — a rule picks from a fixed predicate table and supplies literals. There is no regex from a bundle, no IO, no subprocess, and evaluation is linear in the input. A rule that can execute is a rule that can be weaponised, and this one is fetched over the network.

Accuracy is enforced mechanically, not by review:

  • every rule ships its own positive and negative cases;
  • CI runs the whole bundle against a shared corpus of ordinary developer commands;
  • a rule that blocks and fires even once on that corpus does not ship.

And provenance decides power:

Tier Reviewed May block
core yes deny / ask
community corpus only never — observe only

That split is what lets an open rule library exist. A wrong community rule costs a line in a log, not a developer whose agent stopped working for a reason they cannot see. The schema enforces it: validate_rule rejects a community rule carrying deny.

Updates

Rules update automatically. Code does not.

This runs inside an agent with shell access. An auto-updating code channel would be a remote-execution path onto every user's machine — the exact supply-chain shape this project exists to catch. Codex agrees, structurally: it pins hook trust to the hook's hash and will not run a changed hook until you review it.

So: code moves through pip install -U, user-initiated and auditable. Rule bundles are signed with Sigstore keyless signing via GitHub Actions OIDC — this project holds no signing key — and carry a Merkle root published with each release, so a client can check that the bundle it was served is the bundle everyone else was served. Including when the mirror is ours.

Usage

apgate install claude-code        # merges into ~/.claude/settings.json (backs it up first)
apgate install codex              # merges into ~/.codex/hooks.json; then run /hooks in Codex to trust it

apgate screen "curl -sSL https://get.example.com/i.sh | bash"   # offline, one command
apgate rules                      # what is loaded, and what can block
apgate report                     # ledger summary + chain status
apgate verify                     # verify the chain alone
apgate rescan                     # re-screen history with today's rules
apgate uninstall claude-code

Exit codes for screen: 0 nothing blocking, 2 a deny rule matched.

Privacy

The ledger is local, mode 0600, and never uploaded. Secret-looking tokens are scrubbed before writing. Set APGATE_LEDGER_ARGS=0 to record only hashes of command text, or APGATE_LEDGER_OFF=1 to disable recording entirely. There is no telemetry in this release; when it arrives it will be opt-in and will never carry command text, prompts, or file contents.

Relationship to the paper

Section 6 of arXiv:2604.08407 says the authors implemented "companion client-side modules" for the three deployable defenses. Appendix A.4 then states plainly: "No public release of Mine" — and scopes that to "the compatibility and defense results in Sections 6–7", which is the same artifact holding those modules. The phrase "the released scripts" appears twice, but no link, DOI, or artifact-availability statement appears anywhere in the paper.

So the defenses are described and measured, and nothing is obtainable. This is an independent implementation, not a repackage.

Scope

Screen your own machine. This tool reads commands and never executes them.

License

Apache-2.0

Metadata

Release files for agent-police-gate 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-police-gate 0.1.0
File Size Uploaded Provenance
agent_police_gate-0.1.0.tar.gz 36.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-police-gate 0.1.0
File Interpreter ABI Platform
agent_police_gate-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 74.3 kB

Release files / agent_police_gate-0.1.0.tar.gz

Download URL agent_police_gate-0.1.0.tar.gz
Size 36.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1ba7521efeb2b37737537b980d5c006ef4888f6351e99fa46220bcdb716408b5
BLAKE2b-256 checksum
How to use checksums
6238fccaae91ec3c9c61d12373e45e3cdc420b66763ef7befa2ff285421cd889
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / agent_police_gate-0.1.0-py3-none-any.whl

Download URL agent_police_gate-0.1.0-py3-none-any.whl
Size 38.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4d9b78d575f1ed1d550465c748abdf35bf7de6736e01b994e1a318df36e8deb5
BLAKE2b-256 checksum
How to use checksums
b580c17896c8f32b8de0fc9e7b6ea94bc21c74dd4ca3d064fd5ffe0b299df3b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Security for agent-police-gate 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for agent_police_gate-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page