The SQL query approval workflow, explained
Updated:
A query approval workflow replaces “run it and hope” with “submit it and have someone look”. The developer writes SQL but does not execute it; a second person reviews the statement; the system runs it on the developer’s behalf and returns a controlled result. The developer never holds the credential.
The states a request moves through
Submitted. A developer writes a statement against a connection they have been granted. Nothing has run.
Guarded. The system parses the SQL before any human sees it. This is machine
work: reject UPDATE and DELETE with no WHERE clause, inject a LIMIT into an
unbounded SELECT, block administrative statements. Catching these automatically
means reviewers spend their attention on intent rather than on syntax.
Pending. The request waits for a decision, visible to the people who can make one. If it waits somewhere nobody looks, the workflow has already failed.
Approved or rejected. A reviewer decides, and either outcome is recorded with who decided it and when.
Executed. The system connects and runs the statement. Because the wait is unbounded, this belongs on a worker rather than in a web request.
Returned. Results come back limited, masked, and stored under a retention rule — then written to an audit log.
Failure modes worth designing against
Approval fatigue. A reviewer facing forty requests approves all forty without reading them. Guards help by rejecting the obviously wrong before a human is involved, so what reaches a person is worth reading.
The workflow nobody uses. If approval is slower than the bastion host still sitting there, people use the bastion. Either the approval path becomes the fast path, or the alternative closes.
Self-approval. A workflow where reviewers can approve their own requests is a logging system wearing a workflow’s clothes. Enforce it in code, and make any exception — such as an administrator override — visible in the audit trail.
Unbounded results. An approved SELECT over a hundred million rows is an
approved outage. Cap it, and stream rather than buffer.
Approval as the only control. Approval decides whether a statement runs. It does nothing about what comes back. Without masking, an approved query still puts unmasked PII on someone’s laptop.
How QueryProxy implements it
QueryProxy is this workflow as a product. Requests are submitted in a guarded
editor, parsed by an AST inspector before review, and shown to DBAs in a web
queue and as chat cards — Approve and Reject buttons in Slack, and in Teams a
card that announces the request and links to it, with the decision made by an
automation (for example a Power Automate flow) calling an HMAC-signed action
endpoint — so the decision happens where the reviewer already is. Self-approval is blocked in
code; an administrator can override it, and the override is flagged in the audit
log. Approved queries execute on a queue worker with cursor streaming, results
are masked by your rules as they are written, and every step lands in an
append-only audit log that the application never edits or deletes from; the
audit trail post covers what that record
should contain. The WHERE rule is explained in
how to stop UPDATE and DELETE without WHERE.
See the approval workflow documentation for the roles and the exact lifecycle, or the SQL guards reference for what the parser rejects. The guards differ by engine; see PostgreSQL, MySQL and MariaDB and SQL Server. For how the approval record and the audit trail relate to audit evidence, see SOC 2 and database access controls.
Frequently asked
- What is a SQL query approval workflow?
- A process in which a developer submits a SQL statement for review rather than running it directly, a second person approves or rejects it, and the approved statement is then executed by the system on the developer's behalf. The developer never holds the database credential and never executes the query themselves.
- Who should approve production queries?
- Someone who understands the schema and is not the requester — usually a DBA or a senior engineer who owns that database. The one rule worth enforcing in software rather than in policy is that nobody approves their own request.
- Does an approval workflow slow teams down?
- It adds a wait, and the length of that wait is the whole design problem. When approvals arrive as a chat message with two buttons, the wait is typically minutes. When they require opening a separate tool and hunting for a queue, people route around the system, which is worse than not having it.
- What happens to rejected queries?
- A rejected request stays in the audit trail with its reason, so the record shows what was asked as well as what ran. The developer revises and resubmits rather than losing the work.