✓ Writ

The gate before the write.

Authorization, attribution, revocation, and evidence for AI agent actions. Allow or deny the write. Keep a verifiable receipt. Kill a token in one click.

Instrument this Python repository with Writ. Writ puts an allow/deny
gate in front of every function that writes to a system of record —
database, API, file, email, queue, or AWS call.

Best for: Python agent scripts and services that call Stripe, HTTP APIs,
or databases. Writ's scanner is Python AST-based; it does not cover
TypeScript, Go, or other languages yet.

Do not modify production data, deploy, rotate credentials, push policy,
or use production keys. Work in the repository root only; do not scan
parent directories or monorepo siblings.

1. Install and scan

From the repository root, run:

  pip install pywrit
  writ scan .

Writ is a Python on-ramp: it finds likely writes (database, HTTP, file,
email, queue, AWS) and suggests verb names like
<domain>.<action> — the domain comes from the directory/file/class, the
action from the function name (e.g. payments/refunds.py + issue_refund()
becomes payments.refund).

One check is added per function (not per write site). The scan generates
writ-policy.json and shows an instrumentation diff. It is dry-run by
default; nothing is modified.

Scan is discovery, not complete security coverage. Known gaps: ORM
.save() calls, raw SQL strings, boto3 wrappers, Celery tasks, and
shared HTTP clients three layers down may be missed. Note any you
find as coverage gaps.

2. Review the policy

Read writ-policy.json. For each verb, confirm:
- The domain matches the system of record (payments, orders, users…)
- The action matches the intent (refund, create, delete…)
- No write is missing from the list

To exclude paths, use --exclude with a path substring.

New verbs default to require_grant mode: the check will DENY until a
sponsor grants it, or you change the policy to allow. For a sandbox
demo, set money verbs to require_grant and everything else to allow.

3. Apply instrumentation

After human review and approval, run:

  writ scan . --apply

This inserts a _writ_check() helper at module level and adds a gate at
the top of each function. ALLOW proceeds, DENY raises PermissionError.
The helper is idempotent — re-running scan will not double-instrument.

Every decision writes a tamper-evident receipt to your audit log, but
only if WRIT_API_KEY is set. Without a key, checks fail closed to DENY
and no receipt is written.

4. Verify (five-minute proof)

Set WRIT_API_KEY, then:
- Run one call that should be DENIED. Confirm no write happens and
  PermissionError is raised.
- Run one call that should be ALLOWED. Confirm the write happens and
  a receipt appears in the audit log with a valid chain hash.

Report: the verbs instrumented, any coverage gaps, and the exact
commands run. Stop and wait for approval before pushing policy
to production.
$ curl -fsSL https://withwrit.com/writ -o writ && chmod +x writ
$ ./writ key --email you@company.com
$ pip install pywrit
$ writ key --email you@company.com
21:41:03 ALLOW payments.refund · acme-agent · wr_8f3a2b1c
21:41:07 ALLOW db.write · etl-worker · wr_8f3a2b2a
21:41:12 DENY iam.grant_admin · acme-agent · policy
21:41:18 ALLOW email.send · notifier · wr_8f3a2b3f
21:41:22 DENY payments.refund · unknown-agent · revoked
21:41:29 REVOKED acme-agent · 3 tokens killed

What Writ is

01

Authorize

An allow/deny gate in front of the write. No ALLOW, no write.

02

Attribute

Who acted, under which sponsor, for what purpose — on every decision.

03

Revoke & evidence

Kill a token in one click. Every decision leaves a tamper-evident receipt.

Python on-ramp: writ scan finds writes and suggests verbs for agent scripts. It is discovery for instrumentation — not complete security coverage.

Enforcement today: SDK and check API. Next: credential-bound writes and MCP/proxy. Scan finds the writes; the gate is the guarantee.

Before / after

One line between your agent and the money.

Before

No gate. No receipt.

AI Agent
→
Stripe API
→
$50,000 refund

If the agent is wrong — or compromised — the money is gone. No record of who authorized it.

After

With Writ in front.

AI Agent
→
Writ
policy check
→
Stripe
→
Audit receipt

Every write asks first. Allowed writes leave a tamper-evident receipt. Denied writes never happen.

Kill switch

Kill agent → revoke token → all future actions denied. One call, immediate, across every verb the agent could touch.

$ ./writ revoke --principal acme-agent
REVOKED  3 tokens killed  receipt=wr_9e4c7d2a

Pricing

Start free. Pay only for what you use. No per-seat pricing.

Free

Try it

1,000 receipts/month, no card.

Metered

$0.01 / receipt

Above the free tier, billed monthly. No per-seat pricing, no plans to manage.

Enterprise

Talk to us

When you need production verbs on customer systems and custom policy.