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.

The Problem

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.

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

Without Edictum / With Edictum

Without -- the agent reads your secrets:

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

With -- 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 -- 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 -- no LLM in the evaluation path, just pattern matching against tool names and arguments. The agent cannot bypass a matched contract. Contract errors, type mismatches, and missing fields all fail closed (deny). Tool calls with no matching contracts are allowed by default -- add a catch-all tool: "*" contract for deny-by-default.

Works With Your Framework

# LangChain — wrap your tools
from edictum.adapters import LangChainAdapter
adapter = LangChainAdapter(guard)
tool = adapter.as_tool_wrapper(tool)

# OpenAI Agents SDK — input/output guardrails
from edictum.adapters import OpenAIAgentsAdapter
adapter = OpenAIAgentsAdapter(guard)
input_gr, output_gr = adapter.as_guardrails()

# Claude Agent SDK — hook callables
from edictum.adapters import ClaudeSDKAdapter
adapter = ClaudeSDKAdapter(guard)
hooks = adapter.to_hook_callables()

Edictum plugs into your existing agent code. You don't restructure your tools -- you wrap them. See Adapter docs for all 8 frameworks.

Install

Requires Python 3.11+.

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[gate]        # + coding assistant governance
pip install edictum[server]      # + server SDK (connect to Edictum Console)
pip install edictum[all]         # everything

What You Can Do

Contracts -- four types covering the full tool call lifecycle:

  • Preconditions deny dangerous calls before execution
  • Postconditions scan tool output -- warn, redact PII, or deny
  • Session contracts cap total calls, per-tool calls, and retry attempts
  • Sandbox contracts allowlist file paths, commands, and domains

Principal-aware enforcement -- role-gate tools with claims and env.* context. set_principal() for mid-session role changes.

Callbacks -- on_deny / on_allow for logging, alerting, or approval workflows.

Test and validate:

  • edictum validate -- catch schema errors at load time
  • edictum test -- YAML test cases with expected verdicts
  • guard.evaluate() -- dry-run without executing the tool

Ship safely:

  • Observe mode -- log what would be denied, then enforce
  • Multi-file composition with deterministic merge
  • Custom YAML operators and selectors
  • edictum diff and edictum replay for contract drift detection

Audit and observability:

  • Structured audit events on every evaluation
  • OpenTelemetry spans and metrics
  • Secret values auto-redacted in audit events
  • File, stdout, and composite sinks

Edictum Gate

Pre-execution governance for coding assistants. Sits between the assistant and the OS, evaluating every tool call against contracts.

pip install edictum[gate]
edictum gate init

Supports Claude Code, Cursor, Copilot CLI, Gemini CLI, and OpenCode. Self-protection contracts prevent the assistant from disabling governance. Optional sync to Edictum Console for centralized audit.

See the Gate guide for setup.

Framework Adapters

Framework Integration Complexity
LangChain + LangGraph as_tool_wrapper() Low
OpenAI Agents SDK as_guardrails() Medium
Agno as_tool_hook() Low
Semantic Kernel register() Medium-High
CrewAI register() High
Claude Agent SDK to_hook_callables() Low
Nanobot wrap_registry() Low
Google ADK as_plugin(), as_agent_callbacks() Low

See Adapter docs for setup and limitations.

Built-in Templates

guard = Edictum.from_template("file-agent")
# Blocks .env, .pem, credentials, id_rsa reads. Denies rm -rf, chmod 777, destructive shell commands.

guard = Edictum.from_template("research-agent")
# Postcondition PII scanning on tool output. Session limits (100 calls, 20 per tool).

guard = Edictum.from_template("devops-agent")
# Role gates (only ops principal can deploy). Ticket ID required. Bash command safety.

guard = Edictum.from_template("nanobot-agent")
# Approval gates for exec/spawn/cron/MCP. Workspace path restrictions. Session limits.

Edictum Console

Optional self-hostable operations console for governed agents. Contract management, live hot-reload via SSE, human-in-the-loop approvals, audit event feeds, and fleet monitoring.

guard = await Edictum.from_server(
    url="http://localhost:8000",
    api_key="edk_production_...",
    agent_id="my-agent",
)

See edictum-console for deployment.

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

Use Cases

Domain What Edictum enforces
Coding agents Secret protection, destructive command denial, write scope (Gate guide)
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

Research

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

Paper -- Benchmark

Demos & Examples

  • edictum-demo -- Full scenario demos, adversarial tests, benchmarks, and Grafana observability
  • Contract Patterns -- Real-world contract recipes by concern

Security

See SECURITY.md for vulnerability reporting.

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.15.0.tar.gz (599.0 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.15.0-py3-none-any.whl (144.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: edictum-0.15.0.tar.gz
  • Upload date:
  • Size: 599.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","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.15.0.tar.gz
Algorithm Hash digest
SHA256 abbea56de0beb9639b3bf7971ff17d871b284cb0cc4c27e7631544bead36673d
MD5 f0cedc4016c18c3876b30077776383ac
BLAKE2b-256 8bd2ab550b1f4dfa356579cd0688487e0e3d31c946ddc9caafde97323a670d49

See more details on using hashes here.

File details

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

File metadata

  • Download URL: edictum-0.15.0-py3-none-any.whl
  • Upload date:
  • Size: 144.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","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.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1214497eedee0a73e5cc7569f14b0e357187dbab109d5c2f47ab591549fb9daf
MD5 5500c365977d0d415dc39cbc5b04ea13
BLAKE2b-256 cacd5ff7a2b933793d2a6fae0ee1c85e1f1402720cab3327165ccd7b9af18ac0

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