Skip to main content

sql-write-gate

CI Release Python 3.11+ License: MIT

写库前门禁 · Policy firewall for AI agents writing to databases.

Prevent Claude Code, Codex, Cursor and MCP agents from executing unsafe database operations.

  Agent SQL  ──►  sql-write-gate  ──►  ALLOW / BLOCK / APPROVAL  ──►  Database

Deterministic policy engine (sqlglot AST + catalog + policy.yaml). No LLM. No API key.

非生产唯一边界 — Early gate prototype; not the sole production security boundary. 未列语法拒绝 — unsupported / ambiguous SQL → REJECT/BLOCK (fail closed), never silent ALLOW as read-only.

Install

pip install sql-write-gate
pip install 'sql-write-gate[postgres]'   # optional: psycopg
pip install 'sql-write-gate[mysql]'      # optional: pymysql
pip install 'sql-write-gate[mcp]'        # optional: MCP server

From a clone:

pip install -e ".[dev]"                 # or: make install
pip install -e ".[postgres,mysql]"
make test                               # PG/MySQL live tests skip if no service
sql-write-gate check "DELETE FROM users"
# → BLOCKED  rule=delete_without_where

Commands

sql-write-gate check "SQL"       # evaluate SQL; no execute
sql-write-gate hook              # PreToolUse: block raw psql/mysql/…
sql-write-gate mcp               # MCP stdio (query_sql / write_sql)
sql-write-gate proxy --sql "..." # gate then execute if ALLOW
sql-write-gate approve <id>      # human approve then write
sql-write-gate audit             # TIME / SOURCE / OP / TABLE / VERDICT
sql-write-gate init              # scaffold policy.yaml + catalog.json

What it does (current)

  • DROP / TRUNCATE / ALTER → BLOCK
  • DELETE / UPDATE without WHERE → BLOCK
  • Blast-radius COUNT vs update_rows / delete_rows (dialect quoting; fail-closed on estimate error)
  • Schema / PII / restricted columns; PII SELECT → REQUIRE_APPROVAL (approve executes once)
  • Freshness partitions (dt); range / NOT / OR / UPSERT SET expired → BLOCK
  • Nested / data-modifying CTE / SELECT INTO → REJECT (unsupported_sql)
  • Approval queue with atomic pendingexecuting claim under fcntl.flock
  • JSONL audit (redacts URL passwords; records execute failures)
  • Adapters: DuckDB (default), PostgreSQL, MySQL, SQLite

Platform support matrix

Surface Linux / macOS Windows
pip install / CLI check / init / audit
DuckDB file backend
SQLite sqlite:/// paths (incl. C:/…)
Postgres / MySQL URL adapters ✅ (drivers via extras)
PreToolUse hook / MCP stdio ✅ (same Python entrypoints)
Concurrent approve (flock + atomic replace) fail closedApprovalError if fcntl.flock unavailable (no silent unlock)

Windows: install, CLI evaluate/execute on DuckDB/SQLite/URL backends work. The approvals JSONL concurrency lock requires Unix fcntl; without it, approval mutations refuse rather than silently degrading. Use a single-process approve path on Unix hosts, or run the gate where flock is available.

Database URLs

Env / kwarg Backend
POSTGRES_URL or postgresql://… / postgres://… PostgreSQL
MYSQL_URL or mysql://… / mysql+pymysql://… MySQL
DATABASE_URL (scheme-detected) Postgres / MySQL / SQLite
sqlite:/// / sqlite+aiosqlite:// SQLite (stdlib)
file path / default seed/warehouse.duckdb DuckDB

Priority: database=database_url=db_path=POSTGRES_URLMYSQL_URLDATABASE_URL → DuckDB default.

Live integration tests (optional locally)

export POSTGRES_URL=postgresql://gate:gate@localhost:5432/writegate
export MYSQL_URL=mysql://gate:gate@127.0.0.1:3306/writegate
pip install -e ".[dev,postgres,mysql]"
make test

Without those services, live tests skip; CI runs Postgres + MySQL service containers.

Policy (default production)

operation rule
select allow
insert approval
update approval
delete block
ddl block

Limits: update_rows: 100, delete_rows: 50. Demo policy (examples/policy.demo.yaml) allows insert/update for walkthroughs.

Guards (any BLOCK wins, else any APPROVAL, else ALLOW):

destructiveschemapiifreshnessblast_radiusenvironment

Decision model

ALLOW | BLOCK | REQUIRE_APPROVAL with risk, rule_id, reason, evidence.

Boundaries (non-goals)

  • 非生产唯一边界 — combine with least-privilege DB roles, network isolation, and human workflows
  • Not a distributed approval lock, MySQL wire-protocol proxy, or Web UI
  • Not an enterprise DQ / lineage / ChatBI / multi-tenant platform

See CHANGELOG.md for version history (v0.1 → v0.20).

Backlog (post-0.20)

  • Real Postgres / MySQL CI services + persist/recheck integration tests (0.20)
  • R1–R6 permanent regression (dangerous + safe paths) (0.20)
  • Windows support matrix + flock fail-closed (0.20)
  • Release gate: wheel install smoke; publish needs test+build on same tag (0.20)
  • Deferred: distributed / multi-host approval lock
  • Deferred: MySQL wire-protocol proxy
  • Deferred: Web UI

许可

MIT。见 LICENSE.

Download files

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

Source Distribution

sql_write_gate-0.20.0.tar.gz (74.1 kB view details)

Uploaded Source

Built Distribution

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

sql_write_gate-0.20.0-py3-none-any.whl (63.1 kB view details)

Uploaded Python 3

File details

Details for the file sql_write_gate-0.20.0.tar.gz.

File metadata

  • Download URL: sql_write_gate-0.20.0.tar.gz
  • Upload date:
  • Size: 74.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sql_write_gate-0.20.0.tar.gz
Algorithm Hash digest
SHA256 3a12cb87e8885b6893acbd96d252db928fa5b6ecd100b1ead7f7afa6d752bce8
MD5 d380552346406f8097d1477b9784130b
BLAKE2b-256 69186906c6898df9e97bb711b86f0916b46b49e6b760f6497d5bfcd0972835c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for sql_write_gate-0.20.0.tar.gz:

Publisher: publish.yml on tangyf07/sql-write-gate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sql_write_gate-0.20.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sql_write_gate-0.20.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a595d5a9a68f648cf77475d4d07b68eb8d92355a894e118585d38ab9705f34b
MD5 894f1a62e0100cfc1fce2ae3d3b87ba9
BLAKE2b-256 d7194da14a252bfe6a62314c4e6d71a621204b774cbe729c090474d0c5bb5af8

See more details on using hashes here.

Provenance

The following attestation bundles were made for sql_write_gate-0.20.0-py3-none-any.whl:

Publisher: publish.yml on tangyf07/sql-write-gate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.0.1

2 files

1.0.0

2 files

0.23.0

2 files

0.22.0

2 files

0.21.0

2 files

This release

0.20.0 This release

2 files

0.19.0

2 files

0.18.0

2 files

0.17.0

2 files

0.16.1

2 files

0.16.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page