Skip to main content

acp-governance

Thin Python SDK for the Agentic Control Plane governance hook protocol.

Wraps the two endpoints ACP exposes:

  • POST /govern/tool-use — pre-tool check (allow / deny / ask)
  • POST /govern/tool-output — post-tool audit + PII scan

Same protocol Claude Code uses. Works with any Python agent runtime.

Install

pip install acp-governance

Usage

from fastapi import FastAPI, Header
from acp_governance import governed, set_context

app = FastAPI()

@governed("web_search")
def web_search(query: str) -> str:
    """Search the web."""
    return my_search(query)  # your code, your credentials

@app.post("/run")
def run(topic: str, authorization: str = Header(...)):
    token = authorization.removeprefix("Bearer ").strip()
    set_context(user_token=token)
    return {"result": web_search(topic)}

What happens per call

  1. pre_tool_use POSTs to /govern/tool-use with { tool_name, tool_input, session_id } + Authorization: Bearer <user-jwt>.
  2. Gateway evaluates policy, rate limits, scope, PII → returns { decision, reason }.
  3. On deny, the wrapped function short-circuits with "tool_error: <reason>" (the model sees it and adapts).
  4. On allow, the function runs. Result is sent to /govern/tool-output for audit.
  5. If gateway returns action: "redact", the redacted output is returned to the caller.

Fail-open

Network errors, timeouts (5s), non-2xx responses → tool proceeds with reason "fail-open". Governance is never a single point of failure for the agent.

Both planes in one call

@governed covers what your agent does. The ACP proxy covers what it spends. init() wires both — call it before you construct a model client, since the SDKs read their config from the environment at construction time:

import acp_governance as acp
from anthropic import Anthropic

acp.init()                # governance + proxy
client = Anthropic()      # now priced and metered by ACP

Constructing clients explicitly instead? Skip init() and pass the config:

from acp_governance import model_client_kwargs

client = Anthropic(**model_client_kwargs("anthropic"))

Set ACP_API_KEY=gsk_... from the console.

Routing is all-or-nothing per provider. init() either sets both the base URL and the key, or leaves that provider completely alone and warns — a half-applied provider (ACP's URL against your real vendor key) is just a 401. So if OPENAI_BASE_URL already points at your own gateway, ACP won't silently reroute you; it tells you those calls aren't being priced.

Three API shapes, each on its own mount — "anthropic", "openai" (chat completions), and "openai-responses". The last two are not interchangeable: /v1 serves chat completions, /openai/v1 serves responses.

Framework adapters

This package is the core. For framework-native usage:

API

# decorator
governed(name_or_fn=None)                    # @governed or @governed("tool_name")

# context binding
set_context(user_token, *, session_id=None, agent_tier=None, agent_name=None)
get_context()
clear_context()

# manual (if you need to hook somewhere other than a function boundary)
pre_tool_use(tool_name, tool_input) -> (allowed, reason)
post_tool_output(tool_name, tool_input, tool_output) -> response_dict | None

# config
configure(base_url=..., timeout_s=..., client_header=...)
get_config()

# proxy plane — price and meter model calls
init(proxy=True, shapes=("anthropic", "openai"), **configure_kwargs)  # both planes
model_base_url(shape="anthropic") -> str
model_client_kwargs(shape="anthropic") -> dict   # {"base_url": ..., "api_key": ...}
api_key() -> str                                 # reads ACP_API_KEY

Supports both sync and async tool functions — @governed detects via inspect.iscoroutinefunction and dispatches accordingly.

License

MIT

Download files

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

Source Distribution

acp_governance-0.2.0.tar.gz (12.7 kB view details)

Uploaded Source

Built Distribution

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

acp_governance-0.2.0-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file acp_governance-0.2.0.tar.gz.

File metadata

  • Download URL: acp_governance-0.2.0.tar.gz
  • Upload date:
  • Size: 12.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.12

File hashes

Hashes for acp_governance-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7301473b3c8647cd45fc74dbe29cdbea1523a7e5d1c4a43112b0a080567bbbe1
MD5 73b347ca128a3ebedcd2b5d2045ef531
BLAKE2b-256 68dfe3e015650a4dfd42e6fc5d739204fd4c1cd96e88c687fb595553000cad9f

See more details on using hashes here.

File details

Details for the file acp_governance-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: acp_governance-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.12

File hashes

Hashes for acp_governance-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f98a4e118ad48e48f7099b6d4d59364ab40f2c4b7733a2610a9383d4d87b0ffd
MD5 a5598eb5ff82f32831dea5bb2c19044c
BLAKE2b-256 9f2dd21fb874f622268a4880f78d2dafa0af10e675bd0453b81c718253371e3e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 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