query-warden
Role-based access control for SQL queries. Decide whether a role may run a query before it ever touches the database.
Part of the Governed Agent Stack: free, on-prem building blocks for an AI agent you can point at a real database and audit.
A safety layer like sql-sop answers "is this SQL safe?" and a read-only MCP server answers "is it read-only?". Neither answers the question that gets you in trouble with an LLM near real data: "is this person allowed to see this?" query-warden is that check.
You write the policy in YAML. It parses the query with sqlglot, pulls out the tables and columns it touches, and blocks anything outside the role's allow-list. No database connection, no execution, just a decision.
Install
pip install query-warden
Policy
default_role: operator
domains:
production: [production, prod_runs, waste_log]
staff: [staff, prod_shifts]
roles:
operator:
allow_domains: [production]
deny_columns: [hourly_rate, salary] # never expose pay to the floor
analyst:
allow_tables: ["*"] # read anything
A role may allow whole domains (named groups of tables), specific tables, or "*" for everything. deny_columns blocks named columns, and a bare SELECT * is rejected when any column is denied (it could expose them). COUNT(*) is fine.
Use it
As a library:
from query_warden import Warden
warden = Warden.from_yaml("policy.yaml")
warden.check("SELECT product_id, waste_kg FROM waste_log", role="operator")
# Decision(allowed=True, role='operator', violations=[])
d = warden.check("SELECT name, hourly_rate FROM staff", role="operator")
d.allowed # False
d.reason # "role 'operator' may not query table 'staff'; role 'operator' may not access column 'hourly_rate'"
From the command line (exit 0 = allowed, 1 = denied):
query-warden check --policy policy.yaml --role operator "SELECT * FROM staff"
# DENY (role=operator): role 'operator' may not query table 'staff' ...
Where it fits
query-warden is the access-control layer in the Governed Agent Stack. Put it next to the other guards, after SQL generation and before execution:
question -> agent -> generated SQL -> [read-only] -> [sql-sop lint] -> [query-warden role check] -> database
It pairs naturally with two other tools in the stack:
- schema-scout already flags PII columns, so it can seed a starter policy ("deny these columns unless a role opts in").
- agent-blackbox can record every allow and deny, so "who tried to access what" has a tamper-evident answer.
Read-only by design
query-warden never connects to a database and never runs the query. It reasons about the SQL text alone, so it is safe to call on every query in the hot path and easy to test as a pure function.
Tests
pip install -e ".[dev]"
pytest
License
MIT.
Metadata
Release files for query-warden 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| query_warden-0.1.0.tar.gz | 6.3 kB | With provenance | Details for query_warden-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| query_warden-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for query_warden-0.1.0-py3-none-any.whl |
Total release size: 14.3 kB
Release files / query_warden-0.1.0.tar.gz
| Download URL | query_warden-0.1.0.tar.gz |
|---|---|
| Size | 6.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
62b7d3153bb0f3ce9b6d299389b8ec7a98403c85a82bb8972d32de5f35fba683
|
|
BLAKE2b-256 checksum How to use checksums |
b111e0d33b9b3c317c496769307bd86365afe0d9e772f9a5c07a7cd690238a1d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.
Transparency logRelease files / query_warden-0.1.0-py3-none-any.whl
| Download URL | query_warden-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ec09d4c4129e0f854ffebcea2108bafb67b6ade12030264e80f96a0c5b91384f
|
|
BLAKE2b-256 checksum How to use checksums |
500f283dfe4007006c6b5da51cda5fabfa3d03e246b547e0d8e8e28009b18d86
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.
Transparency logSecurity for query-warden 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for query_warden-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.