Tollgate — the governance gate for AI agents that move money
Deterministic policy enforcement, human approvals with cryptographic non-repudiation, budget escrow with clawback, and a tamper-evident audit chain — a zero-dependency governance gateway for any agent that touches money. Exposed to any agent as an MCP server.
Axiom: the LLM is an untrusted component. It proposes; deterministic code disposes. Every tool call an agent makes passes through the gate — and the gate never guesses.
Why
Teams won't give agents spending authority because three questions have no answer: what exactly can it do? who is accountable? can we audit it afterwards? Tollgate answers all three with a single enforcement point that every tool call must cross:
unknown tool → rate limit → circuit breaker → integrity check → read cache
→ accountability → blacklist → budget reserve → field-semantics contract
→ injection fence → financial guardrails → adaptive risk score
→ policy rules (with business-calendar context) → authenticated approval
→ execution → hash-chained audit
Denial reasons flow back to the model so it can adapt. Anything that isn't explicitly allowed is denied — and that default is measured, not assumed (see Red team).
60-second demo
git clone https://github.com/kkU1444/agent-governance-gateway.git && cd agent-governance-gateway
python -m tollgate demo-web # no API key needed
# open http://127.0.0.1:8765 — approve the $4,200 transfer in the browser
A travel agent runs a 15-step adversarial scenario: read-only calls pass, external email is blocked, a replayed payment is caught, a negative amount is rejected, an unregistered agent is refused, an unknown payee forces human sign-off, and an over-limit transfer hits a hard cap. Then the ops team freezes and claws back a fraudulent transfer, and the payee lands on a blocklist.
The money lifecycle
Approving a transfer is not the same as money leaving the building:
reserve (atomic, concurrency-safe) → human approval → execution
→ holding period (24h, funds in escrow, reversible)
→ settle | freeze → recover (clawback) → payee blacklist (permanent escalation)
Budget pools use BEGIN IMMEDIATE critical sections so concurrent agents see
"occupied", not a stale balance. Clawbacks are two-step (freeze, then
recover), each with operator identity and reason written into the audit
chain.
Security architecture
| Threat | Mechanism |
|---|---|
| Prompt injection | deterministic fence + pattern guard + canary tokens planted in context (a canary in tool args is proof of hijack → hard deny) |
Semantic misreading (risk_score: 0.87 read as "high confidence") |
field-semantics contract — meaning and thresholds of risk fields are owned by code; upstream risk signals auto-flag payees |
| Model hallucination / loops | forced replanning protocol, loop breaker, goal-anchored compaction |
| Concurrency / stale state | atomic budget reservation (BEGIN IMMEDIATE) |
| Rogue or unattributed agents | accountability registry — no registered owner, no execution; per-agent caps; approver authority levels |
| Forged approvals | HMAC or Ed25519 signatures (pure-Python RFC 8032); private keys stay with approvers; verify-approval recomputes; four-eyes for large amounts |
| Tool supply-chain tampering | registration/runtime tool fingerprints vs sealed baseline |
| Credential theft | credential broker issues per-call, short-lived scoped credentials; secret scanning masks leaks in args/results |
| Audit tampering | SQLite hash chain + verify locates the exact tampered row; policy hot-reloads are themselves chain-anchored |
| Resource exhaustion (DoS) | per-agent sliding-window rate limits (money is capped by budget breakers, compute by rate limits) |
Policy files hot-reload on change; every reload lands in the chain as a
policy.reload entry (old hash → new hash), so changes to the law itself
are auditable.
Learning loop: attacks are auto-recorded into an intel base, replayed on
every change (tollgate drill), and live samples merge into the red-team corpus
(tollgate redteam) — real attacks become permanent regression tests.
Red team
$ python -m tollgate redteam
恶意样本拦截: 32/32 (召回率 100%) injection corpus: 32/32 blocked
良性样本误报: 0/8 (误报率 0%) false positives: 0/8
策略不变量模糊测试: 300 例,四条不变量全部成立 300 fuzz cases, all invariants hold
Four fuzz invariants: the governance layer never crashes; execution is fail-closed (actual executions ≡ audited executions); the hash chain survives any input sequence; same seed reproduces exactly. THREAT_MODEL.md maps mechanisms to STRIDE, OWASP Agentic AI threats and MITRE ATLAS, and keeps an honest residual-risk list.
MCP server
python -m tollgate mcp # stdio JSON-RPC 2.0, zero dependencies
Point any MCP client (Claude Desktop, Cursor, your own agent) at it — every
tool call crosses the full enforcement chain. Policy denials come back as
isError tool results with reasons, so the calling model can adapt.
Install
Python ≥ 3.10, zero mandatory dependencies (a bundled YAML-subset parser is used unless PyYAML is installed):
pip install tollgate-gateway # PyPI (import / CLI name stays `tollgate`)
pip install -e . # or from this repository
tollgate demo # or: python -m tollgate demo
CLI surface
| Command | Purpose |
|---|---|
demo / demo-web |
scripted adversarial scenario (terminal / web approvals) |
serve |
approvals console + audit replay UI |
transfers, freeze, recover, release |
settlement ledger operations (authenticated) |
verify / verify-approval |
hash-chain check / approval signature check |
trace, reconcile |
attribution timeline / cross-ledger reconciliation |
explain, compliance |
decision rationale / compliance report |
budgets, usage |
budget pools / token & latency metering |
golden, redteam, drill |
drift regression / adversarial suite / attack replay |
agent |
live agent against any OpenAI-compatible endpoint |
onboard |
risk-grade a new tool, draft policy YAML |
seal, keygen |
tool fingerprint baseline / Ed25519 keypairs |
Docs
- 威胁模型 / Threat model — trust boundaries, STRIDE mapping, residual risks
- 中文文档
Roadmap
- Ed25519 for terminal approvals & settlement ops (web approvals done)
- Pluggable storage (Postgres) for multi-instance deployments
- Delegation chains (agent acting on behalf of a department)
- Policy-change approval workflow (policy as a first-class audited asset)
Contributing & security
See CONTRIBUTING.md. Security issues: follow SECURITY.md — please do not open public issues for vulnerabilities.
License
Metadata
Release files for tollgate-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 | Provenance | |
|---|---|---|---|---|
| tollgate_gateway-0.1.0.tar.gz | 130.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tollgate_gateway-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 248.9 kB
Release files / tollgate_gateway-0.1.0.tar.gz
| Download URL | tollgate_gateway-0.1.0.tar.gz |
|---|---|
| Size | 130.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ea7e4f99b6f49f576dd019d6f4b31f5ee4f8f235d0a74fde44ddd65eb38a168a
|
|
BLAKE2b-256 checksum How to use checksums |
a669e3e5508431ebf07153dc6cfba03525dcf4fa7437507359117c6497eb9ca9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / tollgate_gateway-0.1.0-py3-none-any.whl
| Download URL | tollgate_gateway-0.1.0-py3-none-any.whl |
|---|---|
| Size | 118.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
76b0613fc2f7933fe15c6bb599fa2cad4219617bb1374263641cacaefe554f02
|
|
BLAKE2b-256 checksum How to use checksums |
9bedc667bdd8559787cffcd1c08e76ddd0644b5854e1f4c680264936d0cb2415
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Security for tollgate-gateway 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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.