Framework-agnostic runtime governance for AI agents.
Project description
Agent Runtime Governance
A lightweight, framework-agnostic runtime governance framework for AI agents.
It governs an immutable ExecutionContext through a deterministic middleware
pipeline, then produces an explicit decision, an auditable execution, and a
replayable trace.
Quick start
pip install agent-runtime-governance
from pathlib import Path
from agent_runtime_governance import ExecutionMode, Runtime
runtime = Runtime()
WORKSPACE_ROOT = Path.cwd().resolve()
@runtime.tool(execution_mode=ExecutionMode.READ_ONLY)
def read_file(path: str) -> str:
candidate = (WORKSPACE_ROOT / path).resolve()
try:
candidate.relative_to(WORKSPACE_ROOT)
except ValueError as exc:
raise ValueError("path must remain inside the workspace") from exc
return candidate.read_text(encoding="utf-8")
print(read_file("README.md"))
Add deterministic rules, semantic review, human decisions, and signed audit:
import os
from agent_runtime_governance import (
ApprovalMiddleware, AuditMiddleware, HumanDecisionProvider,
InvocationOptions, JSONLAuditSink, LLMMiddleware, RiskTier,
Rule, RuleMiddleware, Runtime,
)
runtime = Runtime([
RuleMiddleware([Rule("explicit-wipe", r"\bwipe\s+all\b", "bulk wipe is forbidden")]),
LLMMiddleware(lambda ctx: True),
ApprovalMiddleware(HumanDecisionProvider(lambda ctx, request: True)),
AuditMiddleware(
JSONLAuditSink("audit.log", sign_key=os.environ["ARG_AUDIT_HMAC_KEY"])
),
])
@runtime.tool(risk=RiskTier.HIGH, requires_approval=True)
def delete_file(path: str) -> bool:
return True
delete_file(
"old.log",
_governance=InvocationOptions(input_text="remove the old application log"),
)
Why it exists
| Approach | Deterministic boundary | Human decision | Audit and replay |
|---|---|---|---|
| Prompt-only guardrails | No | Ad hoc | No |
| Hand-written permission checks | Partial | Application-specific | Ad hoc |
| Agent Runtime Governance | Yes | Provider interface | Built in |
Prompt instructions are useful guidance, but they are not an authorization boundary. This project places deterministic policy, explicit decisions, and audit outside the model while remaining independent from agent planning and model providers.
Architecture
Tool Registry
|
v
Immutable ExecutionContext
|
v
Runtime Pipeline
Rule -> LLM -> Human Decision -> Audit
|
v
Explicit Decision -> Tool Executor -> Final Audit Snapshot
Gating middleware may stop execution and fails closed. Observing middleware cannot grant permission and normally cannot interrupt an allowed tool. An audit sink explicitly configured as critical is the exception: failed delivery stops the call because an unaudited privileged action is not allowed. Earlier denials cannot be overridden by later middleware.
Design principles
- Deterministic first - code and policy establish the execution boundary.
- Policy over prompt - prompts guide behavior; policies authorize actions.
- Defense in depth - independent controls can only tighten a decision.
- Framework agnostic - the runtime does not own planning or model calls.
- Human in the loop - applications supply the decision channel.
- Observability by default - each transition produces traceable state.
- Immutable context - middleware returns a new context instead of mutating shared state.
Examples
examples/standalone_demo.py: framework-free pipelineexamples/cli_approval_demo.py: interactive human decision providerexamples/langgraph_integration.py: LangGraph tool-node integrationexamples/openai_agents_integration.py: OpenAI Agents SDK tool integrationexamples/crewai_integration.py: CrewAI decorated toolexamples/agno_integration.py: Agno function toolexamples/llamaindex_integration.py: LlamaIndexFunctionToolexamples/autogen_integration.py: Microsoft AutoGenFunctionToolscripts/replay.py: print the snapshots for a trace from JSONL audit data
Each framework adapter is intentionally an example rather than a runtime dependency. The governed function remains ordinary Python and can be wrapped by the framework's native tool interface.
Engineering controls
v0.2 adds immutable pipeline composition, lifecycle hooks, Python-native policy, metrics, retries, timeouts, and optional OpenTelemetry export:
from agent_runtime_governance import (
MetricsMiddleware, Pipeline, PolicyMiddleware, RetryMiddleware,
SimplePolicy, TimeoutMiddleware,
)
pipeline = Pipeline([
PolicyMiddleware(SimplePolicy(admin_only={"restart_service"})),
RetryMiddleware(max_attempts=2),
TimeoutMiddleware(5.0),
MetricsMiddleware(),
])
runtime = Runtime(pipeline)
@runtime.before_tool
def attach_region(ctx):
return ctx.evolve(metadata={**ctx.metadata, "region": "cn-beijing"})
Pipeline edits return a new Pipeline; a live runtime is never mutated behind
concurrent calls. Hooks may enrich context but cannot change status or decisions.
Policies, snapshots, and regression
Load a strict versioned policy with a deterministic digest:
from agent_runtime_governance import Runtime, YAMLPolicyLoader
document = YAMLPolicyLoader.load("examples/policy.yaml")
runtime = Runtime([document.middleware()])
print(document.version, document.digest)
Duplicate tool entries, unknown fields, invalid risks, and unsafe YAML tags are
rejected. YAML remains a configuration format over the deliberately small
SimplePolicy model; it is not a general policy language.
SnapshotMiddleware records immutable lifecycle snapshots. ReplayDebugger
prints timelines and field-level diffs, while EvaluationSuite runs governance
without executing tools. PolicyDriftDetector reapplies deterministic policy to
the same recorded request identity and reports decision or risk changes.
python scripts/trace_debug.py snapshots.jsonl TRACE_ID
python scripts/trace_debug.py snapshots.jsonl TRACE_ID --diff 0 1
python scripts/trace_debug.py snapshots.jsonl TRACE_ID --mermaid
Plugins and integrations
Plugins register components during construction; the built runtime remains immutable:
from agent_runtime_governance import OPAClient, OPAPlugin, PluginManager
manager = PluginManager()
manager.load(OPAPlugin(OPAClient("http://localhost:8181", "agents/tools/allow")))
runtime = manager.build()
Third-party plugins can publish the Python entry-point group
agent_runtime_governance.plugins. Entry points execute Python code and must be
treated as trusted dependencies. The project does not download plugins or
provide a marketplace.
| Integration | Extra | Behavior |
|---|---|---|
| Prometheus | prometheus |
Terminal status and duration; no trace/user labels |
| Slack | none | Denial/failure notifications; official HTTPS webhooks only |
| OPA | none | Minimal decision input; fail closed by default |
| LangGraph | langgraph |
Governed function in a graph node |
| OpenAI Agents SDK | openai-agents |
Governed async function tool |
| CrewAI | crewai |
Decorated governed async tool |
| Agno | agno |
Typed governed Python function |
| LlamaIndex | llamaindex |
Governed FunctionTool async function |
| Microsoft AutoGen | autogen |
Governed FunctionTool async function |
Install only the integrations an application uses:
pip install "agent-runtime-governance[yaml,prometheus,crewai]"
Production reliability
v0.5 focuses on production behavior instead of adding a new agent framework:
- idempotent tool execution with mandatory keys and in-memory or SQLite stores;
- durable approval recovery with leased reserve/commit/release transitions;
- absolute deadline propagation through admission, middleware, identity, tools, and idempotency waits;
- cancellation handling that records mutating in-flight work as
UNKNOWN; - trusted HMAC identity envelopes with replay protection;
- contract validation for parameters, results, and payload size limits;
- reliable JSONL and SQLite audit sinks with hash-chain verification;
- bounded concurrency, external integration circuit breakers, and fault tests.
The production smoke suite starts real Docker services for OPA and the
OpenTelemetry Collector, exports through OTLP HTTP, scrapes a real HTTP
/metrics exposition endpoint, and can run a local Kind smoke with a pinned
node image:
python integration/production_smoke.py --skip-kind
python integration/production_smoke.py
Production deployments must configure a trusted identity provider with
require_verified_identity=True; caller-supplied user, tenant, and
permissions fields are compatibility inputs, not a trust boundary. SQLite
stores coordinate processes on one host and require a distributed adapter for
multi-host deployments.
v0.5 release verification record
The release was validated on 2026-07-26 (UTC) on Windows 11 with Python 3.12, Docker Engine 29.4.2, and Kind 0.31.0, and on GitHub-hosted Linux runners:
- 359 tests passed locally with 88.52% branch coverage on Python 3.12;
- the same 359-test suite passed on Python 3.10, 3.11, 3.12, and 3.13 in GitHub Actions, with 88.63%-88.66% branch coverage; the enforced floor is 80%;
- 15 repository-policy tests passed;
- real OPA HTTP allow/deny, OTLP HTTP export to an OpenTelemetry Collector, Prometheus scraping, and a Kind 1.34.3 control-plane readiness check passed;
- the wheel and source distribution installed and imported from separate clean virtual environments; and
- an isolated environment with the OTel, YAML, and Prometheus extras had no
known dependency vulnerabilities reported by
pip-audit2.10.1 at the time of the run; before publication, the root distribution was reported as unavailable on PyPI and was not treated as an audited third-party dependency.
These are point-in-time verification results, not a latency SLA or a guarantee against future advisories. CI repeats the test matrix, policy checks, dependency audit, and Docker integration smoke from clean runners.
Benchmarks measure incremental runtime overhead for baseline, Rule, OPA, Audit, OpenTelemetry, and 10-middleware pipelines:
python benchmarks/benchmark_runtime.py --requests 100,500,1000 --concurrency 100
The committed Windows/Python 3.12 measurement is available in
benchmarks/results/v0.5.0-windows-python312.json.
Its 100-waiter, zero-hold FIFO admission test measured 2.93 ms p99 wait time.
This point-in-time result is regression evidence for that machine, not a
cross-platform latency SLA.
Releases
| Version | Scope |
|---|---|
| v0.1.0 | Immutable context, registry, rule/LLM/approval/audit middleware, basic replay |
| v0.2.0 | Hooks, Python policy, metrics, retry, timeout, and OpenTelemetry bridge |
| v0.3.0 | Strict YAML policy, snapshots, replay diff, evaluation, and policy drift |
| v0.4.0 | Trusted plugins, Prometheus, Slack, OPA, and six framework integrations |
| v0.4.1 | Mandatory linked issues and merge-policy verification |
| v0.4.2 | Fail-closed CodeRabbit review verification for the current commit |
| v0.5.0 | Production reliability: idempotency, identity, durable approvals, audit, deadlines, cancellation, contracts, real integration smoke |
| v0.5.1 | Security hardening: caller metadata isolation and exact approval binding |
Released versions are preserved as immutable Git tags. See CHANGELOG.md for the detailed compatibility and security notes.
Non-goals
- Agent planning, prompting, model routing, or memory
- Multi-agent communication or distributed execution
- Approval UI or a hosted control plane
- A general policy language, plugin marketplace, or mutable live pipeline
- Production-grade time-travel debugging
- Arbitrary condition evaluation, policy inheritance, or conflict resolution
See ARCHITECTURE.md for invariants and ROADMAP.md for the deliberately staged scope. Security reports and integration boundaries are documented in SECURITY.md. Contributor workflow and plugin contribution rules are documented in CONTRIBUTING.md. Production configuration and recovery are covered in docs/production.md, and the release procedure is defined in RELEASING.md.
Development
python -m pip install -e ".[dev]"
pytest
python integration/production_smoke.py --skip-kind
python -m build
Python 3.10+ is supported. The core package depends on filelock and
jsonschema; optional integrations are installed via extras.
Pull requests must link an existing issue in this repository with a closing
keyword such as Fixes #123. A repository workflow closes unlinked pull
requests automatically. Pull requests to main must also pass every CI job and
the CodeRabbit status, receive a verified CodeRabbit approval for the current
head commit, and resolve blocking reviews. A skipped, rate-limited, stale, or
missing CodeRabbit review fails closed. GitHub does not allow a pull request
author to approve their own change, so the single-maintainer phase has no human
approval count; one code-owner approval and last-push approval become mandatory
when a second maintainer is added. Maintainers still use the same issue and pull
request flow as external contributors, and administrators cannot push directly
to main or bypass protection.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_runtime_governance-0.5.1.tar.gz.
File metadata
- Download URL: agent_runtime_governance-0.5.1.tar.gz
- Upload date:
- Size: 121.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c579bc16ce40acca8c8105128238016ba311fa2ca6c6d7e27102c2a3fdb93a4
|
|
| MD5 |
c414ae52894ba6a02161b98a54bd1a3a
|
|
| BLAKE2b-256 |
88c74d59e976bb28aa855a87b6a19b71472cca4a02001d1bf537d0574d7662b8
|
Provenance
The following attestation bundles were made for agent_runtime_governance-0.5.1.tar.gz:
Publisher:
publish-pypi.yml on Success6666/agent-runtime-governance
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_runtime_governance-0.5.1.tar.gz -
Subject digest:
2c579bc16ce40acca8c8105128238016ba311fa2ca6c6d7e27102c2a3fdb93a4 - Sigstore transparency entry: 2255481536
- Sigstore integration time:
-
Permalink:
Success6666/agent-runtime-governance@f26ee88c84b2a06e67ecdfd97900d508d7a27394 -
Branch / Tag:
refs/tags/v0.5.1 - Owner: https://github.com/Success6666
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f26ee88c84b2a06e67ecdfd97900d508d7a27394 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file agent_runtime_governance-0.5.1-py3-none-any.whl.
File metadata
- Download URL: agent_runtime_governance-0.5.1-py3-none-any.whl
- Upload date:
- Size: 91.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbb05dc87516b841cfb31b794b073b6305e074a7fffde07616a32d857e21c485
|
|
| MD5 |
ece5e898270a112683980607d4f4fc9d
|
|
| BLAKE2b-256 |
c1265ebe967884e925e34723aea0fbc624759999c878af954b8dd3de40b2ff47
|
Provenance
The following attestation bundles were made for agent_runtime_governance-0.5.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on Success6666/agent-runtime-governance
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_runtime_governance-0.5.1-py3-none-any.whl -
Subject digest:
bbb05dc87516b841cfb31b794b073b6305e074a7fffde07616a32d857e21c485 - Sigstore transparency entry: 2255481539
- Sigstore integration time:
-
Permalink:
Success6666/agent-runtime-governance@f26ee88c84b2a06e67ecdfd97900d508d7a27394 -
Branch / Tag:
refs/tags/v0.5.1 - Owner: https://github.com/Success6666
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f26ee88c84b2a06e67ecdfd97900d508d7a27394 -
Trigger Event:
workflow_dispatch
-
Statement type: