What is database access control?
Updated:
Database access control is how an organisation decides three things: who may reach a database, what they may do once they are there, and what they are allowed to see in the result. Most teams have an answer to the first, a partial answer to the second, and no answer at all to the third.
The three layers
Who may connect
This is the layer everyone builds first: network rules, a bastion host or VPN, SSH keys, and credentials held in a password manager. It answers a real question and answers it well. Its limit is that its job ends the moment the connection is established.
What they may do
The database’s own permission system lives here — GRANT, roles, row-level
security where the engine supports it. It is genuinely powerful and genuinely
coarse. A read-only role permits SELECT across every column of every row. A
role permitting UPDATE cannot tell a careful one-row change from a statement
with no WHERE clause that rewrites the whole table.
What they may see
The layer most teams skip. Even a correctly scoped read returns real email addresses, real phone numbers and real card numbers — onto a laptop, into a terminal’s scrollback, sometimes into a spreadsheet that outlives the incident it was pulled for.
Why the layers do not add up
The gap is structural rather than a failure of configuration. Network controls cannot read SQL. Database grants cannot judge intent. Neither can mask a result.
So the common arrangement — a bastion plus a read-only role plus a credential in a vault — leaves a real hole: an authenticated engineer with a legitimate reason runs a legitimate-looking query and receives unmasked production data, and the only record is that a connection happened.
Practices that close it
Least privilege, actually applied. Read-only where reads suffice; one schema rather than the whole instance; no standing production access for anyone who does not need it daily.
No shared credentials. A password two people know is a password with no owner. Every action should trace to a person. The post on production access without shared passwords shows the alternative.
Review the statement, not just the identity. Parsing the SQL before it runs
catches the UPDATE with no WHERE and the unbounded SELECT that authentication
never could.
Approval by a second person. The same logic as code review: cheap, and it catches what the author could not see about their own work.
Mask on the way out. If PII is masked as results stream to storage, an unmasked copy never exists to leak.
Log immutably. Who asked, who approved, what ran, how long it took, what it touched — in a store that permits inserts and reads but not edits.
By database engine
The idea is the same on every engine, but what the engine itself offers, and
what a guard has to block, differs. Engine-specific pages cover
PostgreSQL,
MySQL and MariaDB and
SQL Server. SQLite targets are supported too:
the SQL guards reference lists that the guard blocks
ATTACH, DETACH, VACUUM ... INTO and load_extension(, and a setting can
limit which files a connection may open. To see how QueryProxy compares with
other ways of reaching a database, read the comparisons.
Compliance
Auditors ask the same question of database access: who could reach the data, who approved a change, and can you show it. QueryProxy helps produce that evidence; it does not make anyone pass an audit. Each page below lists the controls it relates to, and what stays with your organization:
- SOC 2 and database access controls
- PCI DSS and database access controls
- ISO 27001 and database access controls
- GDPR and database access
Where QueryProxy fits
QueryProxy implements the second and third layers, and assumes you already have the first. Developers never hold production credentials; they submit SQL against connections a DBA granted them. Statements are parsed before they run. A DBA approves from the web queue or from a Slack card, and no DBA may approve their own request — only an administrator can override that, and the override is flagged in the audit log. Results come back limited, masked by your rules before they touch disk, and recorded in an append-only audit log that the application never edits or deletes from.
It is not a replacement for your network controls or your database’s own grants. It is the layer that sits between them and asks the question neither one can: should this particular statement run, and who else agrees?
Read the introduction for how a request travels end to end, or compare QueryProxy with a bastion host for what changes against the usual setup.
Frequently asked
- What is database access control?
- Database access control is the set of rules and mechanisms that decide who may connect to a database, which operations they may perform, and what data they are allowed to see in the result. It spans the database's own GRANT system, the network path, and any approval or masking layer in front of it.
- Is database access control the same as authentication?
- No. Authentication establishes who someone is. Access control decides what that identity may then do. A system can authenticate perfectly and still let every engineer run DELETE against production, because those are separate questions.
- What is the principle of least privilege?
- Granting each identity the narrowest set of permissions that still lets it do its job, rather than a broad role that happens to include what it needs. In database terms it means read-only where reads suffice, one schema rather than the whole instance, and no standing production access for anyone who does not need it daily.
- Why is role-based access control not enough on its own?
- Roles are coarse. A read-only role still permits SELECT over every column of every row, including personal data, and a role that permits UPDATE cannot distinguish a careful one-row update from a WHERE-less statement that rewrites the table. Roles say who may act; they cannot review the specific statement.