Policy enforcement and taint tracking for AI agent tool calls.
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_policy_gateway-0.1.0.tar.gz.
File metadata
- Download URL: agent_policy_gateway-0.1.0.tar.gz
- Upload date:
- Size: 76.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fec1a50390e27b3082a7c0705df1b4105d41533cd962b37c82c4bc4d5192f94
|
|
| MD5 |
e563ab18e8fd54137538c229a0ac4826
|
|
| BLAKE2b-256 |
e5168e7cd58a70cfbe9eddfd9d8d7549fa710dedec3e2c1830ea55465a833f9a
|
Provenance
The following attestation bundles were made for agent_policy_gateway-0.1.0.tar.gz:
Publisher:
publish.yml on howardhsieh/agent-policy-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_policy_gateway-0.1.0.tar.gz -
Subject digest:
2fec1a50390e27b3082a7c0705df1b4105d41533cd962b37c82c4bc4d5192f94 - Sigstore transparency entry: 1568473146
- Sigstore integration time:
-
Permalink:
howardhsieh/agent-policy-gateway@73276319d01cac49f38e2751bf8a4558b27173fd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/howardhsieh
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@73276319d01cac49f38e2751bf8a4558b27173fd -
Trigger Event:
push
-
Statement type:
File details
Details for the file agent_policy_gateway-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agent_policy_gateway-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2790cd5b5b0eb75143b5598418f30e643b20d0b652bb1ec690615b8b226abb8d
|
|
| MD5 |
bdf3e90baec0d9d6b3fb828b6865a148
|
|
| BLAKE2b-256 |
85ed3fc4d19193eb6146822f879165971ede278104a2637b865ea9406681907a
|
Provenance
The following attestation bundles were made for agent_policy_gateway-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on howardhsieh/agent-policy-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_policy_gateway-0.1.0-py3-none-any.whl -
Subject digest:
2790cd5b5b0eb75143b5598418f30e643b20d0b652bb1ec690615b8b226abb8d - Sigstore transparency entry: 1568473211
- Sigstore integration time:
-
Permalink:
howardhsieh/agent-policy-gateway@73276319d01cac49f38e2751bf8a4558b27173fd -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/howardhsieh
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@73276319d01cac49f38e2751bf8a4558b27173fd -
Trigger Event:
push
-
Statement type: