CallGuard
Runtime contracts for AI agents.
AI agents make tool calls. Tool calls have side effects. Nobody governs what happens between "agent decides" and "tool executes." CallGuard is that governance layer — preconditions, postconditions, session limits, and a full audit trail, enforced at the point where decision becomes action.
Show Me
contracts.yaml
apiVersion: callguard/v1
kind: ContractBundle
metadata:
name: my-policy
defaults:
mode: enforce
contracts:
- id: block-sensitive-reads
type: pre
tool: read_file
when:
args.path:
contains_any: [".env", ".secret", "credentials", ".pem", "id_rsa"]
then:
effect: deny
message: "Sensitive file '{args.path}' blocked."
tags: [secrets, dlp]
Python
import asyncio
from callguard import CallGuard, CallGuardDenied
async def main():
guard = CallGuard.from_yaml("contracts.yaml")
try:
result = await guard.run("read_file", {"path": "/app/config.json"}, read_file_fn)
print(result)
except CallGuardDenied as e:
print(f"Denied: {e}")
asyncio.run(main())
CLI
$ callguard validate contracts.yaml
✓ contracts.yaml — 1 contract (1 pre)
$ callguard check contracts.yaml --tool read_file --args '{"path": ".env"}'
⛔ DENIED by block-sensitive-reads
Message: Sensitive file '.env' blocked.
Tags: secrets, dlp
Rules evaluated: 1
Framework integration (one adapter, same guard)
from callguard.adapters.langchain import CallGuardMiddleware
middleware = CallGuardMiddleware(guard)
# Wraps any LangChain tool — preconditions, audit, and session limits apply automatically
Features
- YAML contracts — Preconditions, postconditions, and session limits declared in version-controlled YAML files
- 6 framework adapters — LangChain, CrewAI, Agno, Semantic Kernel, OpenAI Agents SDK, Claude Agent SDK
- Audit trail — Structured JSON events with automatic redaction of secrets (OpenAI keys, AWS creds, JWTs, GitHub tokens)
- Observe mode — Shadow-deploy contracts without blocking; review
CALL_WOULD_DENYevents before enforcing - CLI tooling —
validate,check,diff, andreplaycommands for CI/CD integration - Principal context — Role, ticket ref, and claims propagated through every decision and audit event
- Session limits — Cap total calls, attempts, and per-tool executions to catch runaway agents
- Zero runtime deps — Pure Python 3.11+. OTel, sinks, and adapters are optional extras
How It Compares
| Approach | Scope | Runtime enforcement | Audit trail |
|---|---|---|---|
| Prompt/output guardrails | Input/output text | No — advisory only | No |
| API gateways / MCP proxies | Network transport | Yes — at the proxy | Partial |
| Security scanners | Post-hoc analysis | No — detection only | Yes |
| Manual if-statements | Per-tool, ad hoc | Yes — scattered logic | No |
| CallGuard | Tool call contracts | Yes — deterministic pipeline | Yes — structured + redacted |
Install
pip install callguard # core (zero deps)
pip install callguard[yaml] # + YAML contract engine
pip install callguard[sinks] # + webhook, Splunk, Datadog sinks
pip install callguard[cli] # + validate/check/diff/replay CLI
pip install callguard[all] # everything
Built-in Templates
guard = CallGuard.from_template("file-agent") # secret file protection, destructive cmd blocking
guard = CallGuard.from_template("research-agent") # output PII detection, session limits
guard = CallGuard.from_template("devops-agent") # role gates, ticket requirements, bash safety
Links
- Documentation
- GitHub
- PyPI
- Changelog
- License (MIT)
Metadata
Release files for callguard 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| callguard-0.3.0.tar.gz | 146.3 kB | Without provenance | Details for callguard-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| callguard-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for callguard-0.3.0-py3-none-any.whl |
Total release size: 204.2 kB
Release files / callguard-0.3.0.tar.gz
| Download URL | callguard-0.3.0.tar.gz |
|---|---|
| Size | 146.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f17baf91e20891c6b443bdcf21b2a879a6967030185a60d5245c0bca08bdbd5f
|
|
BLAKE2b-256 checksum How to use checksums |
b99656faf49bb65319396c62c3d243b6d759676d62272b83931df64853231b03
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / callguard-0.3.0-py3-none-any.whl
| Download URL | callguard-0.3.0-py3-none-any.whl |
|---|---|
| Size | 57.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5d560e6437a68074c6f15b2855aaec7156cecacb5deb40bec27d270f2c8c512c
|
|
BLAKE2b-256 checksum How to use checksums |
c7c4d73307f062913e53d3e486ad6608ad1a2e4cefdcb6746170c1565e663bd1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for callguard 0.3.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.