Runtime safety for AI agents. Stop agents before they break things.
Project description
Edictum
Runtime contract enforcement for AI agent tool calls.
AI agents call tools with real-world side effects -- reading files, querying databases, executing commands. The standard defense is prompt engineering, but prompts are suggestions the LLM can ignore. Edictum enforces contracts at the decision-to-action seam: before a tool call executes, Edictum checks it against YAML contracts and denies it if it violates policy. The agent cannot bypass it.
This is not feature flags. This is not prompt guardrails. Edictum is a deterministic enforcement point for tool calls -- preconditions before execution, postconditions after, session limits across turns, and a full audit trail.
Show Me
contracts.yaml
apiVersion: edictum/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}' denied."
tags: [secrets, dlp]
Python
import asyncio
from edictum import Edictum, EdictumDenied
async def read_file_fn(path):
return open(path).read()
async def main():
guard = Edictum.from_yaml("contracts.yaml")
try:
result = await guard.run("read_file", {"path": "/app/config.json"}, read_file_fn)
print(result)
except EdictumDenied as e:
print(f"Denied: {e}")
asyncio.run(main())
CLI
$ edictum validate contracts.yaml
contracts.yaml -- 1 contract (1 pre)
$ edictum check contracts.yaml --tool read_file --args '{"path": ".env"}'
DENIED by block-sensitive-reads
Message: Sensitive file '.env' denied.
Tags: secrets, dlp
Rules evaluated: 1
Framework integration (one adapter, same contracts)
from edictum import Edictum, Principal
from edictum.adapters.langchain import LangChainAdapter
guard = Edictum.from_yaml("contracts.yaml")
adapter = LangChainAdapter(guard, principal=Principal(role="analyst"))
wrapper = adapter.as_tool_wrapper()
# Wraps any LangChain tool -- preconditions, audit, and session limits apply automatically
How It Works
- Write contracts in YAML. Preconditions deny dangerous calls before execution. Postconditions check tool output after. Session limits cap total calls and retries.
- Attach to your agent framework. One adapter line. Same contracts across all six frameworks.
- Every tool call passes through the pipeline. Preconditions, session limits, and principal context are evaluated. If any contract fails, the call is denied and never executes.
- Full audit trail. Every evaluation produces a structured event with automatic secret redaction.
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 |
| Edictum | Tool call contracts | Yes -- deterministic pipeline | Yes -- structured + redacted |
Framework Support
Edictum integrates with six agent frameworks. Same YAML contracts, same enforcement, different adapter patterns:
| Framework | Integration | PII Redaction | Complexity |
|---|---|---|---|
| LangChain + LangGraph | as_tool_wrapper() |
Full interception | Low |
| OpenAI Agents SDK | as_guardrails() |
Logged only | Medium |
| Agno | as_tool_hook() |
Full interception | Low |
| Semantic Kernel | register() |
Full interception | Medium-High |
| CrewAI | register() |
Partial | High |
| Claude Agent SDK | to_hook_callables() |
Logged only | Low |
See Adapter Docs for setup, known limitations, and recommendations.
Install
Requires Python 3.11+. Current version: v0.7.0.
pip install edictum # core (zero deps)
pip install edictum[yaml] # + YAML contract engine
pip install edictum[otel] # + OpenTelemetry span emission
pip install edictum[cli] # + validate/check/diff/replay CLI
pip install edictum[all] # everything
Built-in Templates
guard = Edictum.from_template("file-agent") # secret file protection, destructive cmd blocking
guard = Edictum.from_template("research-agent") # output PII detection, session limits
guard = Edictum.from_template("devops-agent") # role gates, ticket requirements, bash safety
Demos & Examples
- edictum-demo -- Full scenario demos, adversarial tests, benchmarks, and Grafana observability
- Contract Patterns -- Real-world contract recipes by concern
- Framework Adapters -- Integration guides for six frameworks
Links
- Documentation
- GitHub
- PyPI
- Changelog
- 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 edictum-0.7.0.tar.gz.
File metadata
- Download URL: edictum-0.7.0.tar.gz
- Upload date:
- Size: 228.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9badded89006cd951dbe871a0170864f1f116b8386c68d870ed91feff473039
|
|
| MD5 |
97cd90cf302ef14702f01b6a2ec969f7
|
|
| BLAKE2b-256 |
ec9b9ced937f097e5de560fe5f6acbce547f89753979db69d060d09fcb7879c2
|
File details
Details for the file edictum-0.7.0-py3-none-any.whl.
File metadata
- Download URL: edictum-0.7.0-py3-none-any.whl
- Upload date:
- Size: 67.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
def2d26533917f87c7e43a9c6d20c1e496fd45a8c05edcd08f4f8d43573accf7
|
|
| MD5 |
d5b6e44ea7b300f60514ea478866a217
|
|
| BLAKE2b-256 |
802390727675b33c592b4ef916dcdfc078a1f183b9875f46582009ed67ef78a5
|