Metadata-Version: 2.4
Name: tollgate-gateway
Version: 0.1.0
Summary: Tollgate — the governance gate for AI agents that move money (确定性治理网关:策略裁决/人工审批/预算预留/审计哈希链)
Author: Tollgate contributors
License: Apache-2.0
Project-URL: Homepage, https://github.com/kkU1444/tollgate
Project-URL: Issues, https://github.com/kkU1444/tollgate/issues
Project-URL: Threat-Model, https://github.com/kkU1444/tollgate/blob/main/THREAT_MODEL.md
Keywords: ai,agent,governance,security,llm,mcp,audit,fintech
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: live
Requires-Dist: openai>=1.40; extra == "live"
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0; extra == "yaml"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Dynamic: license-file

# 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**.

[中文文档](README.zh-CN.md)

**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](#red-team)).

## 60-second demo

```bash
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

```bash
$ 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](THREAT_MODEL.md)
maps mechanisms to STRIDE, OWASP Agentic AI threats and MITRE ATLAS, and keeps
an honest residual-risk list.

## MCP server

```bash
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):

```bash
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](THREAT_MODEL.md) — trust boundaries, STRIDE mapping, residual risks
- [中文文档](README.zh-CN.md)

## 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](CONTRIBUTING.md). Security issues: follow
[SECURITY.md](SECURITY.md) — please do not open public issues for
vulnerabilities.

## License

[Apache-2.0](LICENSE)
