Skip to main content

A runtime policy gate for AI agents: every tool call is evaluated against declarative policy before it executes.

Project description

Gatehouse

CI

A runtime policy gate for AI agents.

Gatehouse sits between an AI agent and its tools. Every action the agent proposes — a tool call, an API invocation — is intercepted and evaluated against declarative policy before it executes. Every evaluation resolves to one binding disposition:

Disposition Meaning
allow The action proceeds.
deny The action is blocked, with a reason.
require_approval The action is held until a human approves it.
allow_with_flag The action proceeds, but is marked for monitoring.

Every evaluation is written to a structured audit log. The default posture is deny by default, explicit allow, every disposition explainable.

Status: v0.1.0 — the complete local gate: engine, registry, audit, approvals, CLI, dashboard, MCP proxy, and a runnable demo. Young software; interfaces may still move between minor versions.

The demo in one paragraph

A scripted travel agent books fictional flights through mock MCP tools with Gatehouse in between: a permitted search streams into the dashboard as allow, an over-budget booking comes back deny with the exact reason, a watchlisted destination proceeds as allow_with_flag, and a cancellation stops the terminal until you click Approve in the dashboard — then it completes instantly. Run it yourself: examples/travel-agent.

The travel-agent demo: an allowed search, a booking denied with its reason, a flagged destination, and a held cancellation approved from the dashboard — the terminal proceeding the moment the human decides.

Features

  • Policy engine — declarative YAML rules with agent/tool matching, parameter constraints (bounds, allowlists, regex), selection predicates (where selects, params enforces), time windows, and rate/cumulative limits with per-session or rolling clock scopes. Deny by default; when rules disagree, the most restrictive disposition wins.
  • Agent registry — agents are declared with a human owner, an autonomy tier (read_only / supervised / governed / human_only), an explicit tool grant, and a credentials reference, never a value. Unregistered agents are denied before policy is consulted. Tiers are ceilings: no rule can grant past them.
  • Audit log — append-only JSONL, one record per evaluation: disposition, reason, matched rules, policy version and digest, latency. Parameters are stored as a digest, not verbatim. Usage counters (budgets, rate limits) are rebuilt from the log on restart, so restarting the gate never resets them.
  • Approval queuerequire_approval actions are held with a TTL and resolved from another process; expiry fails closed. Every resolution is an appended audit record naming who decided and why.
  • Policy test harness — scenario files declare action → expected disposition; scenarios share usage state so limit behaviour is testable. Policies without tests are policies waiting to be bypassed.
  • CLIgatehouse check (one-shot advisory evaluation, records nothing), gatehouse test, gatehouse audit tail|stats, gatehouse approvals / approve / deny, gatehouse ui.
  • Web dashboard — live disposition feed over WebSocket, approval cards with TTL countdowns, the agent registry with activity sparklines, and a read-only policy view with test results. Localhost only, no auth in v0.1.

Quickstart

pip install -e ".[ui]"      # from a checkout (PyPI: gatehouse-ai, once published)

Declare an agent and a policy:

# agents.yaml
agents:
  - id: trip-planner
    owner: you@example.test
    tier: governed
    allowed_tools: [search_flights, book_flight]
# policy.yaml
version: 1
tools:
  search_flights: {mutating: false}
  book_flight: {mutating: true}
rules:
  - id: allow-search
    agents: [trip-planner]
    tools: [search_flights]
    disposition: allow
  - id: book-within-budget
    agents: [trip-planner]
    tools: [book_flight]
    disposition: allow
    params:
      price: {max: 500}
    limits:
      - {cumulative: price, max: 2000, per: session}

Ask the gate what would happen:

$ gatehouse check trip-planner book_flight -p policy.yaml -r agents.yaml --param price=812
deny  trip-planner  book_flight
  reason: rule 'book-within-budget': parameter 'price' = 812 exceeds the maximum 500.0

Gate any MCP server without changing the agent or the server — the agent connects to Gatehouse instead:

pip install "gatehouse-ai[mcp]"
gatehouse run --agent trip-planner -p policy.yaml -r agents.yaml -- <your MCP server command>

Or gate plain Python calls directly:

from gatehouse import ApprovalQueue, AuditLog, Gate, PolicyEngine, Registry
from gatehouse.adapters import gated

gate = Gate(
    Registry.from_file("agents.yaml"),
    PolicyEngine.from_file("policy.yaml"),
    AuditLog("gatehouse-audit.jsonl"),
    approvals=ApprovalQueue("gatehouse-approvals"),
)

@gated(gate, agent="trip-planner")
def book_flight(price: float, destination: str) -> str:
    ...   # only runs if the gate says so; refusals raise ActionDeniedError

Watch it live:

gatehouse ui -p policy.yaml -r agents.yaml    # http://127.0.0.1:8422

Documentation

  • Writing policies — the tutorial; every command runs as written.
  • Policy reference — every field, and the evaluation semantics.
  • MVCP mapping — how each feature answers the five control-plane questions: identity, authority, visibility, containment, recovery.
  • Design decisions — why tiers are ceilings, why an uncheckable constraint is a breach, what a "session" is, and every other choice that shapes the semantics, with rationale.

Background and attribution

The conceptual grounding is the Agentic Control Plane ("From Prevention to Control") and the Minimum Viable Control Plane ("From the Control Gap to the Agency Gap"). The four-disposition vocabulary deliberately echoes the four outcomes described in the Monetary Authority of Singapore's SAFR white paper (July 2026) — convergent framings of the same idea: agent actions should resolve to a small, closed set of binding outcomes.

Development

pip install -e ".[dev]"
pytest && ruff check . && mypy gatehouse tests

The frontend source lives in ui/; built assets are committed under gatehouse/ui/ so installed users never need npm. Rebuild with cd ui && npm install && npm run build.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gatehouse_ai-0.1.0.tar.gz (2.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gatehouse_ai-0.1.0-py3-none-any.whl (109.0 kB view details)

Uploaded Python 3

File details

Details for the file gatehouse_ai-0.1.0.tar.gz.

File metadata

  • Download URL: gatehouse_ai-0.1.0.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for gatehouse_ai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4a780c18fa7bef4d549f97d844ce8af9df9e3a44d10a14ea7ae760986f00cc54
MD5 84679ef6339e0aa9a0d1edeb945df0dc
BLAKE2b-256 cf63f90ffcc0fc4bc732a7f5aecd0d5e3592801d9b8372355777ac0a464c4531

See more details on using hashes here.

File details

Details for the file gatehouse_ai-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: gatehouse_ai-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 109.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for gatehouse_ai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 51296e909db1d41ebc9df350a73c8df07a8ef6506c7f3f3ad7fe63e49f6f1b45
MD5 5207ea41056319064d1bc802fb4a2f3e
BLAKE2b-256 3d329e0b7e01d9a4fe02273a1892c51250f6ac4dcf088f95b3ab5b13cbffcc9b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page