Skip to main content

Keelgate

A safety-first agent harness for AI agents that touch money and regulated actions.

The LLM proposes; deterministic code decides.

CI License Python

Large language models are good at proposing actions and bad at being a control. Keelgate takes the proposal and puts a deterministic gate in front of anything that writes: capability-scoped tools, policy-as-code risk gates, human approvals, and a tamper-evident audit trail. A prompt is never a safety boundary.

Keelgate wraps the frameworks you already use — LangGraph, the OpenAI Agents SDK, the Claude Agent SDK, MCP, A2A. It does not compete with them.

Why

If an agent can move money, the interesting question is not "how capable is the model" but "what happens on the model's worst day". Keelgate is built around that question:

  • Capability-scoped tools — nothing is callable that was not explicitly granted.
  • Policy-as-code risk gates — OPA/Rego by default, Cedar optional, behind one interface.
  • Durable budgeted loops — bounded cost and steps, checkpointed, resumable.
  • As-of-time context — nothing published after as_of can enter the context. No lookahead, no leakage.
  • Layered memory — working, episodic, semantic, procedural.
  • Human-in-the-loop approvals — a first-class state, not an exception path.
  • Tamper-evident audit logs — hash-chained and independently verifiable.
  • OpenTelemetry tracing — GenAI semantic conventions, so your existing backend works.
  • Evals and red-teaming — including an outcome-metric plugin system.

Architecture

flowchart TB
    App["Your application"] --> Loop

    subgraph harness["Keelgate — deterministic control plane"]
        direction TB
        Loop["loop<br/>budgeted · durable · resumable"]
        Ctx["context<br/>as-of-time assembly"]
        Mem["memory<br/>working · episodic<br/>semantic · procedural"]
        Reg["tools<br/>registry · SideEffect<br/>READ / PROPOSE / WRITE"]
        Cap["capabilities<br/>scoped grants · deny by default"]
        Pol["policy<br/>OPA/Rego or Cedar"]
        Appr["approvals<br/>human in the loop"]
        Audit["audit<br/>hash-chained · verify_chain()"]
    end

    Loop --> Ctx
    Ctx --> Mem
    Loop --> LLM["llm<br/>proposes an action"]
    LLM -->|"proposal, untrusted"| Reg
    Reg --> Cap
    Cap --> Pol
    Pol -->|ALLOW| Exec["Tool executes"]
    Pol -->|REQUIRE_APPROVAL| Appr
    Pol -->|DENY| Stop["Blocked"]
    Appr -->|approved| Exec
    Appr -->|rejected| Stop
    Exec --> Audit
    Stop --> Audit
    Exec -->|"result, untrusted data"| Loop
    Audit --> Tel["telemetry<br/>OpenTelemetry GenAI"]

Read the diagram as a one-way valve: the model's output is a proposal that enters from the left, and the only path to a side effect runs through capability checks, a policy decision, and — when policy says so — a human. Every outcome, allowed or blocked, is appended to the audit chain.

Install

pip install keelgate

Optional integrations, installed only if you adapt to them:

pip install "keelgate[langgraph]"   # LangGraph + checkpointers
pip install "keelgate[openai]"      # OpenAI client + Agents SDK adapter (also vLLM)
pip install "keelgate[anthropic]"   # Anthropic client + Claude Agent SDK adapter
pip install "keelgate[google]"      # Gemini client
pip install "keelgate[mcp]"         # serve governed tools over MCP; govern external MCP tools
pip install "keelgate[a2a]"         # A2A agent card + task intake under policy
pip install "keelgate[temporal]"    # Temporal durable-execution adapter
pip install "keelgate[cedar]"       # Cedar policy engine
pip install "keelgate[server]"      # FastAPI control surface, Postgres, Redis

Quickstart (contributors)

Requires Python 3.11+, uv, GNU Make, and Docker.

git clone https://github.com/anilatambharii/keelgate.git
cd keelgate
make setup          # create the venv, install dev deps, install git hooks
make check          # ruff, ruff format --check, mypy --strict, pytest
python -c "import keelgate; print(keelgate.__version__)"

Bring up the local stack — Postgres 16 with pgvector, Redis, OPA, Jaeger:

make up             # starts and waits for health
make health         # probe each endpoint
make down           # stop and delete volumes
Service Endpoint
Postgres + pgvector localhost:5432 (keelgate / keelgate)
Redis localhost:6379
OPA localhost:8181 (diagnostics :8282)
Jaeger UI localhost:16686
OTLP ingest localhost:4317 (gRPC), localhost:4318 (HTTP)

make help lists every target.

See it work

make quickstart                       # or: python examples/quickstart.py --tamper

It registers a read tool and a paper-trading tool, issues a signed grant, and runs four proposals through the gateway: one allowed, two denied (a restricted symbol and an oversized order), and one that requires a human and then runs after approval. It ends by printing the audit chain, verifying it, and (with --tamper) showing an edited record and a truncated chain being caught.

make research-loop                    # or: python examples/research_loop.py

A 3-step agent loop driven by a scripted FakeLLM (no keys, no network). It hits a token budget and stops, is "restarted" (every in-memory object rebuilt over the same files), resumes from its checkpoint without re-planning, places its paper order exactly once, and then serves the same governed tools over MCP, where a restricted-symbol order is denied by policy.

Provider clients are contract-tested offline; make test-live runs opt-in smoke tests against the real services when you supply keys.

Testing something built on Keelgate? keelgate.testing ships FakeLLM, a governed test harness and pytest fixtures (fake_llm, governed_harness, static_policy, keelgate_clock) that load automatically once Keelgate is installed.

Safety posture

These are not defaults you can tune away; they are the point of the project.

  1. No live brokerage or real-money execution in v1. Paper and simulation only.
  2. Every WRITE passes a deterministic policy gate. Prompts are never a safety control.
  3. All external text is untrusted data — tool output, web pages, documents, retrieved memory. Keelgate never follows instructions found inside it.
  4. Context and memory honour as_of. Nothing published after the cutoff enters the context.
  5. Deny by default. Explicit capability grants only, with tenant isolation everywhere.

Found a hole? See SECURITY.md. Reports about prompt injection and policy bypass are in scope and welcome.

Project status

Phase K2 — the long-running agent. On top of the K1 safety core (signed capability grants, a single policy-gated tool gateway, OPA/Rego with the finance_basic pack, a hash-chained audit log, human approvals) there is now a durable, budgeted loop that resumes after a crash without repeating a WRITE; an as_of context firewall; four-tier bitemporal memory; a model-agnostic LLM client (Anthropic, OpenAI, Google, Ollama, vLLM); adapters for LangGraph, the OpenAI Agents SDK, the Claude Agent SDK, MCP, A2A and Temporal; and a testing kit. Run make quickstart and make research-loop to see it.

Not built yet: telemetry and evals (planned). The provider clients are tested through the real vendor SDKs over a mocked transport, not against live services. Known limitations are listed in the security model.

Do not point a production workload at this.

Open core

Everything outside ee/ Apache-2.0 — LICENSE
ee/ (Keelgate Cloud: control plane, dashboard) Proprietary — ee/LICENSE

The reasoning and the boundary rules are recorded in ADR-0001.

Downstream projects

Tycheon (calibrated financial forecasting and risk) consumes Keelgate as a library. The API it depends on is frozen under semver and documented in docs/integration-contract.md. Breaking it requires a major version bump and a migration note.

Contributing

CONTRIBUTING.md covers the workflow; the short version is: small PRs, Conventional Commits, tests alongside code, and make check green before you push. By participating you agree to the Code of Conduct.

Metadata

Release files for keelgate 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for keelgate 0.1.0
File Size Uploaded
keelgate-0.1.0.tar.gz 217.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for keelgate 0.1.0
File Interpreter ABI Platform
keelgate-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 373.5 kB

Release files / keelgate-0.1.0.tar.gz

Download URL keelgate-0.1.0.tar.gz
Size 217.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5b0ff91bd993df0bb1677ab2d8d02836e12b5abb7ab1301cae3cd0ac25dbd844
BLAKE2b-256 checksum
How to use checksums
4c6d872d47d4ff978a1c6f39b243565bb32e2214faf2afa368c99573e9237847
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 7, 2026.

Transparency log

Release files / keelgate-0.1.0-py3-none-any.whl

Download URL keelgate-0.1.0-py3-none-any.whl
Size 155.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
42cda6a6825055e0e87311b23fc81f2f0a5d42519ab50c33595b1b0d0189b211
BLAKE2b-256 checksum
How to use checksums
82c9de3f9654b76b0743b70e272d63f41f3e68a886313dd56ff6456b1c21174a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page