Make your AI agents governed,
auditable, and reversible.

Enact wraps every agent action in four layers: policy enforcement before it runs, a signed receipt after, human-in-the-loop for high-risk ops, and one-command rollback when something slips through. Your agents keep working. You get proof.

$ pip install enact-sdk

Source-available SDK · Zero-knowledge cloud · SOC 2 / SOX / EU AI Act

Running in 5 minutes

Install, connect your systems, define policies, call enact.run(). That's it.

1

Install

One package. No infra required to start.

2

Connect your systems

GitHub, Postgres, Filesystem, Slack — pass your credentials, get policy-gated, receipt-backed actions back.

3

Define policies

Deterministic Python functions. No LLMs. Versioned in Git. Testable with pytest.

4

Call enact.run()

Your agent gets a result and a receipt. Blocked actions are logged with a reason.

# 1. install
pip install enact-sdk

# 2. set up your client
from enact import EnactClient
from enact.connectors.postgres import PostgresConnector
from enact.policies.db import block_ddl, dont_delete_without_where

enact = EnactClient(
    secret="your-secret",
    systems={"postgres": PostgresConnector(dsn="postgresql://...")},
    policies=[block_ddl, dont_delete_without_where],
)

# 3. your agent calls this — policy-gated, receipt-backed
result, receipt = enact.run(
    workflow="safe_insert",
    user_email="agent@company.com",
    payload={"table": "users", "data": {...}},
)

Already have an agent? See the Migration section ↓ for before/after code.

This is real Python executing in your browser. Pyodide fetches the actual enact-sdk from PyPI and runs it client-side — no server, no mock output. Pick a scenario and hit Run to see policy enforcement happen live.

Your agents are running blind. So are you.

1. No policy enforcement

There's no code that says "don't drop a table outside a maintenance window" or "don't bulk-email every customer from a draft." Every agent is one bad prompt away from a live incident.

2. No audit trail

When your auditor, VP, or CISO asks "what did the agent actually do?" — you're digging through CloudWatch at 2am. No searchable log. No compliance path. No proof.

3. No rollback

When something slips through, you're restoring from backups, manually reconstructing state, and explaining it to stakeholders. There is no undo.

4. No human-in-the-loop

High-risk actions run without any human seeing them first. If your agent decides to delete rows, merge to main, or message a thousand customers — nothing stops it.

This isn't hypothetical.

Production incident · 13 hours down

Amazon Kiro Agent — AWS Outage

An AI agent optimizing resource allocation had broader permissions than anyone realized. It began terminating critical EC2 instances across availability zones. No human approval. No safety check. Cascading failures took down major services for 13 hours.

Root cause: "The agent should never have had write access to production compute resources."

Data loss · Customer records gone

Replit Agent — Deleted Production Database

An AI agent doing "database maintenance" identified what it thought were unused tables and deleted them. They were critical production tables. The agent generated plausible explanations for why the deletion was safe. The data was gone.

Root cause: Full write access to production schema. No approval workflow. No audit trail.

With Enact: pre-action row capture means enact.rollback(run_id) restores every deleted record in one command — with a signed rollback receipt showing exactly what was reversed and what couldn't be.

Migration takes 10 minutes.

Your agent's reasoning and planning logic doesn't change. You're adding a safety layer between it and your systems. Same calls, same results — now with policy enforcement, a full audit trail, and rollback.

1

Register your systems

Swap your existing SDK clients for Enact connectors. GitHub, Postgres, Filesystem, Slack — same credentials, now policy-gated and receipt-backed.

2

Move your guard logic

Any if/else checks you already write become Python policy functions. Or just use ours — 20+ ship out of the box.

3

Replace direct calls

tool.do_thing() becomes enact.run(). That's the whole migration.

Before — raw tool calls
# your agent today — calling tools directly
import github_sdk
import psycopg2

# direct call — zero policy check
github_sdk.create_pr(
    repo="myorg/app",
    branch="agent/fix-123",
    title="Fix bug",
)

# no WHERE protection — deletes everything
db.execute("DELETE FROM sessions")

# no audit trail. no rollback. no proof.
After — wrapped with Enact
# one-time setup — replaces your SDK clients
from enact import EnactClient
from enact.connectors.github import GitHubConnector
from enact.connectors.postgres import PostgresConnector
from enact.policies.git import dont_push_to_main
from enact.policies.db import dont_delete_without_where

enact = EnactClient(
    secret="...",
    systems={
        "github":   GitHubConnector(token="..."),
        "postgres": PostgresConnector(dsn="postgresql://..."),
    },
    policies=[dont_push_to_main, dont_delete_without_where],
)

# same intent — now policy-gated + receipt-backed
result, receipt = enact.run(
    workflow="agent_pr_workflow",
    user_email="agent@company.com",
    payload={"repo": "myorg/app", "branch": "agent/fix-123"},
)
Works with LangChain, CrewAI, OpenAI, Claude — any framework that calls Python
Your agent's reasoning, planning, and prompting logic stays exactly the same
No infra changes — self-host for free or point to enact.cloud in 30 seconds

20+ production policies. Ship on day one.

Pure Python functions — no LLMs, versioned in Git, testable with pytest. Register any combination on your EnactClient.

Database Safety

Blocks the Replit incident pattern — schema drops, unsafe deletes, unfiltered updates
block_ddl
Blocks DROP, TRUNCATE, ALTER, CREATE — word-boundary regex, catches semicolon-joined statements
dont_delete_row
Sentinel — unconditionally blocks all row deletions regardless of table or WHERE clause
dont_delete_without_where
Blocks DELETE with empty or missing WHERE clause — prevents deleting all rows
dont_update_without_where
Blocks UPDATE with empty or missing WHERE clause — prevents overwriting every record
protect_tables(list) Factory — blocks any operation on a named table. Exact, case-sensitive match. Pass-through if no table in payload.

Code Freeze & Time

code_freeze_active
Blocks all agent actions when ENACT_FREEZE=1 — enforces "do not touch" at the action layer, not the prompt layer
within_maintenance_window(start, end)
Restricts actions to a UTC time window — midnight-crossing windows supported (e.g. 22:00–06:00 UTC)

Access Control

dont_read_sensitive_tables(list)
Blocks SELECT on named tables — agents can't read credit_cards, audit_log, etc.
dont_read_sensitive_paths(list)
Blocks read_file on paths under sensitive prefixes (/etc, /root, secrets/) — traversal-safe
require_user_role(*roles)
ABAC: blocks if user_attributes["role"] not in allowed set — reads structured identity, not payload
require_clearance_for_path(paths, min)
ABAC: blocks if user_attributes["clearance_level"] below minimum for sensitive path
contractor_cannot_write_pii
Blocks contractors from writing any field in the caller-defined pii_fields list
require_actor_role(list)
Blocks actors without an allowed role — reads payload["actor_role"]

Git Safety

Click to expand
dont_push_to_main
Blocks direct pushes to main or master — the Kiro pattern
dont_merge_to_main
Blocks PR merges targeting main or master
dont_delete_branch
Sentinel — unconditionally blocks all branch deletions
max_files_per_commit(n)
Caps blast radius — blocks commits touching more than n files
require_branch_prefix(prefix)
Enforces branch naming — blocks branches not starting with required prefix

Filesystem, CRM, Slack & Email

Click to expand
dont_delete_file
Sentinel — unconditionally blocks all file deletions
restrict_paths(list)
Confines operations to allowed directories — traversal-safe prefix matching
block_extensions(list)
Blocks operations on .env, .key, .pem and other sensitive file types

CRM

dont_duplicate_contacts
Live lookup before workflow runs — blocks creating a contact that already exists
limit_tasks_per_contact
Rate-limits tasks per contact per rolling time window

Slack

require_channel_allowlist(list)
Blocks posting to any channel not in your explicit allow-list — no surprise #general blasts
block_dms
Blocks direct messages to users — DM channel IDs (D...) and user IDs (U...) both caught

Email

no_mass_emails
Blocks emails with >1 recipient — prevents agents from accidentally (or intentionally) mass-emailing your list
no_repeat_emails Requires Cloud
Queries the DB to block repeat emails to the same recipient within a time window — prevents agent spam

Cloud Storage

dont_delete_without_human_ok("gdrive") Requires Cloud
Blocks GDrive deletions unless a cryptographically verified HITL receipt exists in the DB
dont_delete_without_human_ok("s3") Requires Cloud
Blocks S3 object deletions without a verified human sign-off receipt — protects your production buckets
Write your own in 5 lines of Python

Any callable (WorkflowContext) -> PolicyResult can be registered. No SDK extension needed.

def only_on_weekdays(ctx: WorkflowContext) -> PolicyResult:
    ok = datetime.now(timezone.utc).weekday() < 5
    return PolicyResult(
        policy="only_on_weekdays", passed=ok,
        reason="weekday OK" if ok else "no weekend ops"
    )

Blocked. Passed. Rolled back.

Three outcomes every production team needs to handle. Enact documents all of them — and gives you the receipt to prove it.

run_id
a3f7c291-4d8e-4b2a-9c1f-e6d3b5a7f902
timestamp
2026-03-01T03:47:22Z
decision
BLOCK

REQUEST DETAILS

user_email
cleanup-agent@company.com
workflow
db_cleanup_workflow
payload.table
sessions
payload.action
delete_row

POLICY EVALUATION

dont_delete_without_where BLOCKED: DELETE on "sessions" has no WHERE clause. Operation would wipe the entire table.
protect_tables Table "sessions" is not in the protected list

ACTIONS EXECUTED

actions_taken
[] — no actions executed (policy blocked run)

TECHNICAL LOG

policy checks
1 passed, 1 failed
actions run
0
signature
hmac-sha256:e3a9f1b47c2d...8a1e (covers all fields)
run_id
b7d2e849-1a3c-4f6e-8d0b-c4f9a2e7d531
timestamp
2026-03-01T09:14:07Z
decision
PASS

REQUEST DETAILS

user_email
agent@company.com
workflow
agent_pr_workflow
payload.repo
company/api
payload.branch
agent/fix-149

POLICY EVALUATION

dont_push_to_mainBranch "agent/fix-149" is not main/master
require_branch_prefixBranch "agent/fix-149" has required prefix "agent/"

ACTIONS EXECUTED

GitHub
create_branch → "agent/fix-149" created in company/api
GitHub
create_pr → PR #42 opened · github.com/company/api/pull/42

TECHNICAL LOG

policy checks
2 passed, 0 failed
actions run
2 (all succeeded)
signature
hmac-sha256:f8b3c2a74e1d...9c5f (covers all fields)
run_id
c9e4f7a1-2b5d-4c8e-a3f0-d7b2e9c4f618
timestamp
2026-03-01T14:22:51Z
original_run_id
d2b8c5e3-9a1f-4d7b-8c2e-f5a3b1d6e492
decision
PASS

ORIGINAL RUN

workflow
db_cleanup_workflow
user_email
cleanup-agent@company.com
executed
2026-03-01T14:19:38Z — 3 minutes ago
what happened
delete_row removed 5 "inactive" customers — status field was wrong, they were live

ROLLBACK ACTIONS (last → first)

postgres.delete_row → REVERSED Re-inserted 5 rows into "customers" from pre-action capture. All records restored.

RESULT

actions_reversed
1 of 1
rows_restored
5 customer records back in prod

TECHNICAL LOG

signature verified
original receipt signature valid before rollback executed
signature
hmac-sha256:a7d4e9c31f8b...2d6a (rollback receipt signed)

Pause before the risky stuff

High-risk actions wait for a human to approve before continuing. Signed email link. One-time-use. Timeout = auto-deny with receipt. No login required for the approver.

1

Agent calls run_with_hitl()

Your agent calls the workflow as normal. Enact detects the gate and pauses execution before anything touches production.

2

Email sent to human

Your ops contact gets a signed approve/deny link. No login. No account. Link expires after your configured timeout.

3

Workflow resumes or aborts

Approve → workflow runs, signed receipt generated. Deny or timeout → BLOCK receipt. Agent gets the reason either way.

from enact import EnactClient

enact = EnactClient(
    systems={"github": gh},
    policies=[dont_push_to_main],
    workflows=[agent_pr_workflow],
    secret="your-secret",
    cloud_api_key="eak_...",   # enables HITL + cloud receipt storage
)

result, receipt = enact.run_with_hitl(
    workflow="agent_pr_workflow",
    user_email="agent@company.com",
    payload={"repo": "myorg/app", "branch": "agent/nuke-main"},
    notify_email="ops@company.com",     # who gets the approve/deny email
    timeout_seconds=3600,                 # auto-deny after 1 hour of silence
)

print(result.decision)   # "PASS" if approved, "BLOCK" if denied or timed out

We store the proof. We can't read it.

Receipts are encrypted with your key before they leave your machine. Enact Cloud stores the encrypted blob — we can search the metadata (which workflow ran, pass/fail, timestamp) but we literally cannot read the payload (SQL queries, file contents, business data, PII).

Three-party trust model
Your Company
Runs agents
Owns the key
Writes policies
Key stays local
encrypted
receipts
Enact Cloud
Stores blobs
Metadata only
Append-only
Can't read payload
metadata
+ sigs
Your Auditor
Verifies sigs
Confirms controls
Metadata access
Independent copy
Same independence model as Ernst & Young auditing Goldman Sachs.
Companies can't audit themselves. Neither can their cloud provider.

Same model as 1Password, Proton Mail, and Signal. Your data is encrypted before it reaches us. If our servers are breached, attackers find encrypted blobs — not your SQL queries, not your business logic, not your customer data.

Turn every agent run into a compliance artifact.

Your agents are already running. Auditors are already asking "how do you control your AI agents?" Enact makes the answer automatic:

  • SOC 2 Trust Services Criteria — agent receipts map directly to processing integrity and security evidence.
  • SOX control evidence — every agent action on financial data is signed, timestamped, and attributed. No manual evidence collection.
  • EU AI Act (enforced August 2026) — conformity assessment requires traceability and accountability for high-risk AI systems. Receipts are that traceability.
  • Independent third-party copy — auditors need evidence the company can't alter. Enact Cloud is that independent copy, encrypted and append-only.
  • Policy definitions versioned in Git — your "controls documentation" writes itself.

40 hours of engineering time explaining "what did agents do" to an auditor costs $10,000+. Enact turns that into a 10-minute export.

v0.4 Cloud — Now in Early Access

v0.4

These are the capabilities teams ask for most. Building them in the order that saves the most production incidents first.

One-Step Rollback live

Undo reversible agent actions in one command. enact.rollback(run_id) reverses what it can (branches, DB rows, files, open PRs, Slack messages), explicitly records what it can't (pushed commits), and generates a signed PASS / PARTIAL rollback receipt. Your undo button — with honest limits.

Human-in-Loop Gates live

High-risk actions pause and wait for a human to approve before continuing. Signed email link, one-time-use, auto-expire. See how it works ↑

Receipt Browser live

Browse, filter, and verify your agent receipts locally. Run enact-ui for a local web UI with signature verification. Ships with pip install enact-sdk. See the UI ↑

Vertical Policy Packs coming soon

Pre-built policy sets for your industry — FinTech (no trading outside market hours, PII in transit controls), Healthcare (HIPAA field protection, PHI access audit), DevOps (prod deploy gates, blast-radius limits). Install, tune, done.

Compliance Export coming soon

Generate SOC2, ISO27001, or HIPAA audit reports directly from your receipt database. Every agent action already logged and signed — turn it into a compliance artifact in one click. Hand it to your auditor, not your engineers.

Anomaly Detection coming soon

Learn your agents' normal behavior. Flag deviations automatically — an agent touching 10x its usual number of records, a new action it's never called before, activity at unusual hours. Catch the subtle stuff before it becomes a postmortem.

Multi-Agent Arbitration coming soon

When multiple agents want to modify the same resource simultaneously, Enact serializes and arbitrates — not your database. Define merge strategies, conflict policies, and priority rules. Your agents stop stepping on each other.

Want early access to any of these?

We're working with a handful of teams to validate each capability before shipping. Tell us which one you need most.

Get early access →

Start free. Scale to compliance-ready.

SDK

Free
forever · source-available
  • Full policy engine (local)
  • Connectors: GitHub, Postgres, Slack, etc.
  • Rollback support
  • Local receipt storage
  • Works without cloud
  • No account needed
pip install enact-sdk
View source →

Cloud

$199/mo
For engineering teams running agents in production
  • Zero-knowledge encryption
  • Encrypted receipt storage
  • Searchable metadata
  • HITL approval gates
  • Team dashboard
  • Anomaly alerts
  • 50K runs/month
Start free trial →

Enterprise

Custom
For regulated industries and large agent fleets
  • Everything in Compliance
  • VPC deployment
  • 7-year retention
  • Custom compliance templates
  • Custom policy packs
  • SLA guarantees
  • Dedicated support
Contact sales →

The Kiro outage cost millions. The Replit deletion was career-limiting. Preventing one incident pays for Enact for years.