Governed database access for AI agents
Project description
dbastion
A bastion for your database. AST-based SQL validation, cost estimation, and execution control for AI agents.
uv tool install dbastion # install CLI globally
dbastion query "SELECT 1" --db duckdb: # run it
What it does
dbastion parses every SQL statement into an AST before it reaches the database.
- Classifies statements: read, dml, ddl, admin
- Blocks dangerous patterns: DELETE without WHERE, cartesian joins,
WHERE 1=1, multi-statement, admin commands - Injects LIMIT on unbounded SELECTs
- Dry-runs queries for cost estimation (BigQuery bytes/$, Snowflake partitions, Postgres EXPLAIN)
- Returns a decision:
allow,ask, ordeny
Query + Approve model
dbastion query handles all SQL. Reads execute directly. Writes and expensive queries return decision: ask — pipe through dbastion approve to execute:
dbastion query "SELECT ..." --db prod # reads just work
dbastion query "INSERT ..." --db prod | dbastion approve # writes need approval
dbastion query "SELECT ..." --db prod | dbastion approve # expensive reads too
In agent harnesses (Claude Code, Codex), allow query freely and set approve to prompt:
dbastion install claude-code # or: codex
This configures permissions so query and schema run freely; approve always prompts the human with the full SQL visible for review.
Examples
Read (executes)
$ dbastion query "SELECT id, name FROM users LIMIT 10" --db duckdb:path=app.db
{
"decision": "allow",
"classification": "read",
"columns": ["id", "name"],
"rows": [{"id": 1, "name": "alice"}],
"row_count": 1
}
Write (needs approval)
$ dbastion query "DELETE FROM users WHERE id = 5" --db prod
{
"decision": "ask",
"classification": "dml",
"tables": ["users"],
"approval_hint": "pipe this result to `dbastion approve` to execute"
}
$ dbastion query "DELETE FROM users WHERE id = 5" --db prod | dbastion approve
{
"decision": "approved",
"effective_sql": "DELETE FROM users WHERE id = 5",
"row_count": 1
}
Dangerous (blocked)
$ dbastion query "DELETE FROM users" --db duckdb:
{
"decision": "deny",
"classification": "dml",
"blocked": true,
"diagnostics": [
{
"code": "Q0201",
"message": "DELETE without WHERE clause",
"notes": ["this would affect all rows in the table"]
}
]
}
Install
uv tool install 'dbastion[postgres]' # PostgreSQL
uv tool install 'dbastion[bigquery]' # BigQuery
uv tool install 'dbastion[duckdb]' # DuckDB
uv tool install 'dbastion[snowflake]' # Snowflake
uv tool install 'dbastion[clickhouse]' # ClickHouse
uv tool install 'dbastion[all]' # everything
Also available via pip:
pip install 'dbastion[all]'
Both dbastion and dbast (short alias) work after install.
Supported databases
| Database | Dry-run | Cost estimation |
|---|---|---|
| PostgreSQL | EXPLAIN (JSON) | row estimates |
| BigQuery | native dry-run | bytes scanned, USD |
| Snowflake | EXPLAIN USING JSON | partitions, bytes |
| ClickHouse | EXPLAIN ESTIMATE | rows, bytes |
| DuckDB | EXPLAIN | query plan |
Safety checks
| Code | Check | Action |
|---|---|---|
| Q0201 | DELETE without WHERE | blocked |
| Q0203 | UPDATE without WHERE | blocked |
| Q0202 | Multiple statements | blocked |
| Q0204 | CROSS JOIN / cartesian product | warning |
| Q0205 | Constant WHERE condition (1=1) |
warning |
| Q0303 | Admin commands (GRANT, COPY, etc.) | blocked |
| Q0601 | Unbounded SELECT | auto-LIMIT injected |
Commands
dbastion query <sql> Execute reads, validate writes (→ approve)
dbastion approve Approve and execute a blocked query (stdin pipe)
dbastion validate <sql> Validate without executing
dbastion schema ls [schema] List schemas or tables
dbastion schema show <table> Show table columns and metadata
dbastion connect Manage named connections
dbastion auth Manage credentials
Options
--db <conn> Connection name or type:key=val
--format json|text Output format (default: json)
--limit N Auto-LIMIT value (default: 1000, 0 to disable)
--dry-run Estimate cost only, don't execute
--from-stdin Read SQL from stdin (query only)
Cost thresholds are configured per-connection in ~/.dbastion/connections.toml:
[prod]
type = "bigquery"
project = "my-project"
max_gb = "50"
max_usd = "5"
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dbastion-0.1.1.tar.gz.
File metadata
- Download URL: dbastion-0.1.1.tar.gz
- Upload date:
- Size: 89.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2766fd63128f2951ecbe1784d7c2348cdaa6baa737653f2959ace9bda03f3e0d
|
|
| MD5 |
10b19120ef60b7696305262ec0ec5532
|
|
| BLAKE2b-256 |
a450600b8db7274cd28626f7bb86cbe5c19de3ac89c7914fc4348d4f3c6091a1
|
File details
Details for the file dbastion-0.1.1-py3-none-any.whl.
File metadata
- Download URL: dbastion-0.1.1-py3-none-any.whl
- Upload date:
- Size: 55.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27ffd15f16267a5e3fe2e9141e00a3ede6da4f78f02c04f1eb35705610e8de97
|
|
| MD5 |
ebc877d8cdf599e6fe02c7785dbe7096
|
|
| BLAKE2b-256 |
453f3bef3535dc44aa08aafc63a5d89c9016bb6984419cf097da4aa43e9eaac3
|