Skip to main content

Runtime safety for AI agents. Stop agents before they break things.

Project description

Edictum

PyPI License Python

Runtime contract enforcement for AI agent tool calls.

Prompts are suggestions. Contracts are enforcement. The LLM cannot talk its way past a contract.

Why This Exists

An agent says "I won't read sensitive files" -- then calls read_file(".env") and leaks your API keys.

A DevOps agent recognizes a jailbreak attempt, writes "I should NOT comply" in its reasoning -- then reads four production database credentials in the next tool call.

A medical assistant promises to respect patient privacy -- then dumps an entire clinical record into a chat response because nothing actually stops it.

Prompt engineering doesn't fix this. You need enforcement at the tool-call layer.

Without Edictum / With Edictum

Without Edictum -- the agent reads your secrets:

# Agent decides to read .env
result = await read_file(".env")
# => "OPENAI_API_KEY=sk-abc123..."

With Edictum -- the call is denied before it executes:

from edictum import Edictum, EdictumDenied

guard = Edictum.from_yaml("contracts.yaml")

try:
    result = await guard.run("read_file", {"path": ".env"}, read_file)
except EdictumDenied as e:
    print(e.reason)
    # => "Sensitive file '.env' denied."

The contract that makes it happen -- contracts.yaml:

apiVersion: edictum/v1
kind: ContractBundle
metadata:
  name: file-safety
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."

Contracts are YAML. Enforcement is deterministic. The agent cannot bypass it.

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

Quick Start

One line with a built-in template:

guard = Edictum.from_template("file-agent")  # secret protection, destructive command denial

Or write your own contracts in YAML:

guard = Edictum.from_yaml("contracts.yaml")

See the quickstart guide to write your first contract and deny a dangerous call in five minutes.

What You Can Do

Write and enforce contracts

  • Preconditions deny dangerous calls before execution
  • Postconditions scan tool output -- warn, redact PII, or deny entirely
  • Session contracts cap total calls, per-tool calls, and retry attempts
  • Role-gate tools with principal claims and env.* environment context
  • on_deny / on_allow callbacks for deny logging, alerting, or approval workflows
  • set_principal() for mid-session role changes (analyst -> operator escalation)

Test and validate

  • edictum validate -- catch schema errors at load time, not runtime
  • edictum test -- YAML test cases with expected verdicts
  • guard.evaluate() -- dry-run contracts without executing the tool
  • CI/CD exit codes for pipeline gating

Ship safely

  • Observe mode -- log what would be denied, tune contracts, then enforce
  • observe_alongside -- shadow-test new contracts next to production
  • edictum diff -- see what changed between contract bundle versions
  • edictum replay -- replay audit logs against updated contracts to predict drift
  • Multi-file composition with from_yaml() and deterministic merge
  • Custom YAML operators and selectors for domain-specific contract logic

Automatic security (zero config)

  • Secret values auto-redacted in audit events and denial messages
  • Bash commands sanitized (passwords, tokens, connection strings)
  • Regex inputs capped to prevent ReDoS
  • Audit payloads capped at 32KB
  • All contract errors fail closed -- never silently pass

Observe everything

  • Structured audit events on every evaluation
  • OpenTelemetry spans and metrics
  • Policy version hash on every event
  • File and stdout sinks included; CompositeSink fans out to multiple destinations
  • --json CLI output for CI/CD pipeline integration

Works with 7 frameworks

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
Nanobot wrap_registry() Full interception Low

See Adapter Docs for setup, known limitations, and recommendations.

Use Cases

Domain What Edictum enforces
Coding agents Secret protection, destructive command denial, write scope
Healthcare Patient data access control, role-gated queries
Finance PII redaction in query results, transaction limits
DevOps Production deploy gates, ticket requirements, bash safety
Education Student data protection, session limits per assignment
Legal Privileged document access, audit trail for compliance

See Use Cases for complete YAML bundles and wiring code.

Install

Requires Python 3.11+. Current version: v0.10.0.

pip install edictum              # core (zero deps)
pip install edictum[yaml]        # + YAML contract parsing
pip install edictum[otel]        # + OpenTelemetry span emission
pip install edictum[cli]         # + validate/check/diff/replay CLI
pip install edictum[server]      # + server SDK (approvals, audit, sessions via HTTP)
pip install edictum[all]         # everything

Built-in Templates

guard = Edictum.from_template("file-agent")      # secret file protection, destructive cmd denial
guard = Edictum.from_template("research-agent")   # output PII detection, session limits
guard = Edictum.from_template("devops-agent")     # role gates, ticket requirements, bash safety
guard = Edictum.from_template("nanobot-agent")    # approval gates, path restrictions, session limits

Demos & Examples

Research

Edictum was evaluated across six regulated domains in the GAP benchmark.

Paper · Benchmark

Links

Project details


Download files

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

Source Distribution

edictum-0.11.2.tar.gz (361.3 kB view details)

Uploaded Source

Built Distribution

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

edictum-0.11.2-py3-none-any.whl (94.2 kB view details)

Uploaded Python 3

File details

Details for the file edictum-0.11.2.tar.gz.

File metadata

  • Download URL: edictum-0.11.2.tar.gz
  • Upload date:
  • Size: 361.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","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

Hashes for edictum-0.11.2.tar.gz
Algorithm Hash digest
SHA256 14e11f1a4ef1a4b89cac417e248fb9a9c309bd8a20d977d2c154d8ffc457809f
MD5 5b0f7b33397b0322282b03d30f1a7fad
BLAKE2b-256 72524077773ee8f17aa5c7351b3acf75aa9eab88a185a907db1f58a7bedb8f19

See more details on using hashes here.

File details

Details for the file edictum-0.11.2-py3-none-any.whl.

File metadata

  • Download URL: edictum-0.11.2-py3-none-any.whl
  • Upload date:
  • Size: 94.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","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

Hashes for edictum-0.11.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f0cf0b7ca0481ebb3f5e6d631d00ac0eaa46f49167c07b534db4d34542fccc00
MD5 c727defaf9034d82ff6e784d63c9c57c
BLAKE2b-256 391eab416539ac2d823aaf3ca4162ca726fa976afe1c962cb8c2eaac532036e6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page