agent-policy-gateway
A policy enforcement and information-flow-control (IFC) gateway for AI agent tool calls.
Status: 0.1.0 — first tagged release. See
CHANGELOG.mdfor what's in it,ROADMAP.mdfor what's done.
Why
Autonomous AI agents increasingly call tools — read files, query databases, browse the web, send messages. When data from an untrusted source (e.g. a web page) flows into a sensitive sink (e.g. an email send), bad things happen: prompt injection becomes prompt exfiltration, indirect commands turn into real-world actions, and audit trails are missing.
Most existing guardrails focus on LLM output filtering. agent-policy-gateway instead sits
between the agent and its tools and treats the problem the way operating systems treat untrusted
input: with policy enforcement and taint tracking across calls.
What it does
- Policy enforcement. Allow / deny / quota / human-in-the-loop rules per tool, per resource, per agent identity. Policies are declarative (YAML) and composable.
- Taint tracking. Each tool call produces tainted output (sources: web, user-uploaded
docs, external API). Taint propagates through subsequent calls. Policies can refuse a
sensitive sink (e.g.
send_email) if its arguments carry high-taint sources. - Audit log. Every call, decision, and taint label is recorded in an append-only log suitable for incident response and red-team review.
- Multi-protocol adapters. Wraps tool catalogs from MCP, OpenAI function calling, Anthropic tool use — same policy language across them.
Threat model
We assume the LLM itself is not trusted to decide what tool calls are safe. Adversarial content can reach the model via any tool output, and the model may then attempt unsafe calls. The gateway is the trusted reference monitor; the model is policy-controlled, not policy-aware.
The full project threat model — assets, trust boundaries, adversary classes, assumptions,
canonical abuse scenarios mapped to the mitigations the gateway already ships, and residual
risks — lives at docs/threat-model.md.
Non-goals
- Not a content filter. We do not classify text as "harmful." This is about flow.
- Not a sandbox for tool implementations. Tools run as they always did; we mediate access.
- Not a replacement for human review of high-stakes actions. We make review tractable.
Quick start
from agent_policy_gateway import Gateway, Policy
gw = Gateway.from_yaml("policies/my-policy.yaml")
@gw.wrap_tool(name="web_search", taint_sources={"web"})
def web_search(query: str) -> str:
...
@gw.wrap_tool(name="send_email", taint_sinks={"web": "deny"})
def send_email(to: str, body: str) -> None:
...
# Now the agent calls these wrappers; the gateway enforces policy and tracks taint.
Benchmarks
The apg-bench console script runs a small standard-library-only suite that
measures per-call overhead and throughput on the gateway's hot paths
(raw call, gateway-allow, gateway-deny, gateway-allow + audit). After
pip install -e . the script is on $PATH:
apg-bench # human-readable table
apg-bench --json # machine-readable
apg-bench --scenario raw_call # one scenario only
See docs/benchmarks.md for the methodology and
the public benchmark() / run_default_suite() API.
Documentation
The full documentation site is built with mkdocs-material. Build it locally:
pip install -e ".[docs]"
mkdocs serve
The site sources live under docs/ and the configuration in
mkdocs.yml. Start with docs/index.md and
docs/quickstart.md.
Release
Releases are published to PyPI. The automated path is the GitHub
Actions workflow at .github/workflows/publish.yml:
push a v* tag and a three-job test → build → publish pipeline
runs, uploading the sdist + wheel via PyPI's trusted-publisher OIDC
flow — no long-lived API token is stored in the repo or in GitHub
secrets. A workflow_dispatch trigger is wired up too, so a release
can be re-run from the Actions tab after a transient failure. The
documented manual fallback (python -m build + python -m twine upload)
remains the disaster-recovery path. The full procedure — one-time
PyPI trusted-publisher setup, the tag-and-push flow, the manual
fallback, and a post-release verification checklist — is in
docs/release.md.
License
Apache-2.0. See LICENSE.
Contributing
This project is built incrementally and in public. See ROADMAP.md for what's
next, and docs/design.md for the architecture.
Release files for agent-policy-gateway 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agent_policy_gateway-0.1.0.tar.gz | 76.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agent_policy_gateway-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 118.6 kB
Release files / agent_policy_gateway-0.1.0.tar.gz
| Download URL | agent_policy_gateway-0.1.0.tar.gz |
|---|---|
| Size | 76.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2fec1a50390e27b3082a7c0705df1b4105d41533cd962b37c82c4bc4d5192f94
|
|
BLAKE2b-256 checksum How to use checksums |
e5168e7cd58a70cfbe9eddfd9d8d7549fa710dedec3e2c1830ea55465a833f9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 18, 2026.
Transparency logRelease files / agent_policy_gateway-0.1.0-py3-none-any.whl
| Download URL | agent_policy_gateway-0.1.0-py3-none-any.whl |
|---|---|
| Size | 42.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2790cd5b5b0eb75143b5598418f30e643b20d0b652bb1ec690615b8b226abb8d
|
|
BLAKE2b-256 checksum How to use checksums |
85ed3fc4d19193eb6146822f879165971ede278104a2637b865ea9406681907a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 18, 2026.
Transparency log