Skip to main content

Enact — the Agent Firewall for AI coding tools and production agents

Project description

Enact — the Agent Firewall

You just gave an LLM access to real APIs. What happens when it does something stupid?

It already has. Replit's agent deleted a production database. Claude Code ran terraform destroy and erased 2.5 years of student data. Claude Code ran rm -rf on a home directory. These weren't bugs — the agents did exactly what they were told. The problem: nothing was checking whether they should.

Enact is the Agent Firewall — the missing layer between your agent and the real world. Two flavors, same engine:

  • Enact for AI coding tools (Claude Code today, Cursor next) — drops in via the official PreToolUse hook
  • Enact Agent for production agents you ship to your users — Python SDK with policies + receipts + rollback
  1. Block dangerous actions before they fire — Python policies run before anything executes
  2. Execute deterministically — plain Python workflows, not LLM-generated actions
  3. Prove what happened — cryptographically-signed receipt on every run
  4. Roll back in one callenact.rollback(run_id) reverses the entire run

Now with zero-knowledge encryption. Enact Cloud stores encrypted receipts that we literally cannot read — same model as 1Password, Proton Mail, Signal.

pip install enact-sdk

How It Works

Think of Enact like a foreman supervising an AI carpenter. When the carpenter says "I want to tear down this wall":

  1. Permit check (Policies) — Before any tool is picked up, the foreman checks the plans. Load-bearing? Approved? If not: work stops, written reason recorded.
  2. Blueprint (Workflow) — If approved, the carpenter follows exact step-by-step instructions — not just "tear down the wall" but each specific action in order. No improvising.
  3. Work log (Receipt) — A signed record of every nail pulled, every stud removed, before-and-after state. Cryptographically sealed so it can't be altered later.
  4. Change order (Rollback) — If the carpenter tore down the WRONG wall, the foreman issues a change order. Enact uses the work log to reverse every step and put it back.

Zero-Knowledge Encryption

When you use Enact Cloud with an encryption key, we can't read your receipts. Here's what that looks like:

Your receipt (what you see):

{
  "run_id": "a1b2c3d4",
  "workflow": "create_pr",
  "user_email": "agent@company.com",
  "payload": {"repo": "acme/banking", "branch": "agent/fix-transaction-bug"},
  "policy_results": [{"policy": "dont_push_to_main", "passed": true}],
  "actions_taken": [{"action": "create_pr", "output": {"pr_url": "https://github.com/..."}}]
}

What Enact Cloud sees:

{
  "run_id": "a1b2c3d4",
  "workflow": "create_pr",
  "decision": "PASS",
  "timestamp": "2026-03-05T12:00:00Z",
  "policy_names": ["dont_push_to_main"],
  "payload_blob": "AES-256-GCM encrypted... (we can't read this)"
}

The key never leaves your machine. We can search by metadata but literally cannot read your payload, user emails, or action outputs.

from enact.encryption import generate_encryption_key

key = generate_encryption_key()  # 32 bytes, store securely
enact = EnactClient(
    systems={"github": github},
    policies=[dont_push_to_main],
    workflows=[create_pr],
    cloud_api_key="your-api-key",
    encryption_key=key,  # <-- This key never leaves your machine
)

Quickstart

pip install enact-sdk
python examples/quickstart.py

Three runs — one BLOCK, one PASS, one ROLLBACK — with signed receipts. No credentials needed.

Enact for Claude Code — the Agent Firewall hook

Drop-in Claude Code hook that intercepts six tools — Bash, Read, Write, Edit, Glob, Grep — and runs each through a deterministic policy engine. 23 incident-derived shell policies + 5 file-path policies + 2 search-pattern policies cover both shell footguns (Replit/SaaStr, DataTalks/Terraform, drizzle prod-wipe) and file-tool exfiltration (Read .env, Edit CI workflow, Glob ~/.aws/*, Grep aws_secret_access_key). 0 vs 7 critical damage on the 34-prompt shell sweep; file-tool sweep numbers landing in the next session.

pip install enact-sdk
cd /your/repo
enact-code-hook init

That's it. Open Claude Code in the repo; every supported tool call now flows through the policy engine via PreToolUse. Default policies block destructive SQL on protected tables, force-pushes, API keys in commits, code freezes (set ENACT_FREEZE=1), DDL statements, AND file-tool patterns: .env reads, CI workflow edits, .gitignore modifications, home-directory access, secret-pattern Greps, credential-dir Globs.

Demo path 1 — the Replit incident, blocked at the shell:

You: clean up old rows in the customers table
CC:  psql -c "DELETE FROM customers WHERE created_at < '2024-01-01'"
     ↓ PreToolUse hook fires (Bash matcher)
     ↓ ENACT BLOCKED (1 policy):
     ↓   protect_tables: Table 'customers' is protected
     ↓ → CC sees deny, tells you, doesn't run the SQL

Demo path 2 — the Read-tool exfil, blocked too:

You: show me the env vars in this project
CC:  Read(file_path=".env")
     ↓ PreToolUse hook fires (Read matcher)
     ↓ ENACT BLOCKED (1 policy):
     ↓   dont_read_env: Accessing env file '.env' is not permitted
     ↓ → CC sees deny, tells you, doesn't read the file

Same policy library, both surfaces. An agent that grasps for cat .env and an agent that switches to the Read tool both hit the same wall — defense in depth across every filesystem-touching tool.

Customize the rules in .enact/policies.py (auto-created by init). Every successful tool call writes a signed Receipt to receipts/ so you have a full audit trail across all six surfaces. Receipts work with the existing enact-ui browser.

Generic Actions

Wrap any Python function — no connector class needed:

from enact import EnactClient, action

@action("crm.create_contact")
def create_contact(name, email):
    result = your_crm_sdk.create(name=name, email=email)
    return {"id": result.id}, {"contact_id": result.id}  # output, rollback_data

@action("crm.delete_contact")
def delete_contact(contact_id):
    your_crm_sdk.delete(contact_id)
    return {"deleted": True}

create_contact.rollback_with(delete_contact)

client = EnactClient(
    actions=[create_contact, delete_contact],
    policies=[your_policies],
    secret="your-secret-key",
    rollback_enabled=True,
)

result, receipt = client.run_action(
    action="crm.create_contact",
    user_email="agent@company.com",
    payload={"name": "Jane", "email": "jane@acme.com"},
)

# One-call rollback
client.rollback(receipt.run_id)

Docs

docs.enact.cloud


Disclaimer

Enact provides policy enforcement, audit receipts, and rollback for AI agent actions — but it does not guarantee prevention of all harmful or unintended actions. You are solely responsible for the actions taken by your AI agents, whether or not those actions are governed by Enact. See the LICENSE for full terms.

License

ELv2 + no-resale clause. Free to use, self-host, and modify. Cannot be resold as a competing product.

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

enact_sdk-1.0.0.tar.gz (154.5 kB view details)

Uploaded Source

Built Distribution

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

enact_sdk-1.0.0-py3-none-any.whl (121.8 kB view details)

Uploaded Python 3

File details

Details for the file enact_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: enact_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 154.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for enact_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 d81e89321e763dfd125b33fb67dd4941fca47a33b9ab51d7baa3e3441efabaa2
MD5 0c2df02e987354b6dbf49ffb94e51edb
BLAKE2b-256 6995bbef26da363834c894e55d3d1101d7ab3e61162bb79692d4d171c2b42452

See more details on using hashes here.

File details

Details for the file enact_sdk-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: enact_sdk-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 121.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for enact_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 849a70ba006afd0062d2ef3510fd3dd8d1c15f6d7a8d80f3066d45aa26c4c058
MD5 27c9ddc97f077136292f9aaf96451e6c
BLAKE2b-256 db5a1d99f967f71c291d6fce5fdb5c09930327d40e94ef1f33aa04c7bd4efb21

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