# What is database access control?

> Database access control decides who may reach a database, what they may do there, and what they may see in the result. A practical guide for engineering teams.

- Updated: 2026-10-13
- Source: https://queryproxy.com/what-is-database-access-control/
- Language: en-US
- Author: Muhammet Şafak

---
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](/blog/production-database-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](/postgresql-access-control/),
[MySQL and MariaDB](/mysql-mariadb-access-control/) and
[SQL Server](/sql-server-access-control/). SQLite targets are supported too:
the [SQL guards reference](/docs/sql-guards/#sqlite) 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](/compare/).

## 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](/soc-2-database-access-controls/)
- [PCI DSS and database access controls](/pci-dss-database-access-controls/)
- [ISO 27001 and database access controls](/iso-27001-database-access-controls/)
- [GDPR and database access](/gdpr-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](/docs/) for how a request travels end to end, or
[compare QueryProxy with a bastion host](/compare/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.
