Many databases match an incoming connection against an ordered host-based access file (PostgreSQL's pg_hba.conf being the classic example) before any credential is checked. How does that matching work, and what mistakes does it commonly cause?
answer
- Type / database / user / address / method
- First match wins — no fall-through on failure
- Specific rules above general ones
- trust on 0.0.0.0/0 = open database
- 'all' excludes replication; reload after editing
basics
~20 sEach line matches a connection by type (local/TCP/TLS), target database, requested role and source address, and names an authentication method. The server scans top to bottom and uses the first matching line only. If that method fails, the connection is rejected — it never falls through to later lines.
solid answer
~60 sThe file is an ordered rule list. Every line carries: connection type (local socket, plain TCP, TLS-required), which databases it covers, which roles, a source address or CIDR range, and the authentication method to demand — `scram-sha-256`, `gss`, `ldap`, `cert`, `peer`, `trust`, `reject`, and so on. The engine scans **top to bottom and stops at the first line whose four selectors all match**. That line's method is the one and only method tried. If authentication under it fails, the connection is refused; there is no fall-through to a more permissive line further down. If no line matches at all, the connection is also refused — with a distinctly different error that says no entry exists for this host/user/database. The classic mistakes follow directly: putting a broad `all all 0.0.0.0/0 trust`-style line above the specific ones and shadowing everything below it; adding a new tightened rule at the bottom where it never matches; forgetting that replication connections need their own entry; and forgetting the config reload, since the file is read from disk on reload rather than per connection.
code
text · 6 lines# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
hostssl replication repl 10.0.2.0/24 scram-sha-256
host all admin 0.0.0.0/0 reject
hostssl appdb app 10.0.1.0/24 scram-sha-256
host all all 0.0.0.0/0 rejectgo deeper
Know that a rules file matches connection type, database, user and source address to decide the authentication method, and that order matters.
State first-match-wins with no fall-through, name a few methods including the danger of trust, and mention that a reload is required.
Bring operational failure modes: shadowed rules, the missing replication entry, rules not affecting live sessions, and source addresses collapsing behind a pooler.
Treat it as one layer of defence in depth alongside network policy and identity federation, and argue for rules generated from configuration management rather than hand-edited on hosts.
## What the file decides Before any secret is exchanged, the server has to answer a question that precedes authentication itself: *for this connection, which authentication method do we demand — or do we refuse it outright?* Host-based rules answer that. They are a firewall-shaped policy expressed in the database rather than in the network. The canonical form (PostgreSQL) has five columns: - **Type** — `local` (Unix socket), `host` (TCP, TLS or not), `hostssl` (TCP, TLS required), `hostnossl`, `hostgssenc`. - **Database** — a name, a list, `all`, or the special `replication` keyword. - **User** — a role name, a list, a `+group` (role membership), or `all`. - **Address** — a CIDR range, a hostname pattern, `samenet`, or blank for local. - **Method** (+ options) — `scram-sha-256`, `gss`, `sspi`, `ldap`, `cert`, `peer`, `trust`, `reject`, with options like `map=`, `clientcert=verify-full`, `ldapserver=`. Other engines express the same idea differently: MySQL folds the host pattern into the account identity itself (`'app'@'10.0.%'` is a different account from `'app'@'localhost'`) and picks the most specific host match; SQL Server separates logins from endpoint/protocol configuration. The concept — source and target select the method — is the portable part. ## First match wins, and that is the whole trap Evaluation is a top-to-bottom scan. The first line whose type, database, user and address all match is used, and **only** that line. Two consequences that candidates routinely get wrong: 1. **Failure does not fall through.** If the matched line says `scram-sha-256` and the password is wrong, the connection is rejected. A later, laxer line that would also have matched is never consulted. This is deliberate: fall-through would let an attacker downgrade to whichever rule is weakest. 2. **Order encodes precedence.** Specific rules must sit above general ones. A `host all all 0.0.0.0/0 md5` line near the top silently shadows every carefully scoped rule beneath it, and a hardened rule appended at the bottom quietly does nothing. If nothing matches, the connection is refused with a "no entry for host" style error — worth recognising, because it means the credentials were never even examined. ## Methods that need special care - **`trust`** accepts the connection with no credential at all. It is legitimate only on a local socket during recovery, and catastrophic on a TCP range. `trust` on `0.0.0.0/0` is the single worst line you can write in this file. - **`peer`** (local socket) takes the identity from the operating system — the kernel reports the connecting Unix user — and requires the OS name to equal the requested role unless a user map translates it. `ident` is the network-facing analogue and should not be trusted across untrusted networks. - **`cert`** requires TLS with a client certificate and derives the role from the certificate subject, typically through a name map. - **`reject`** exists to carve exceptions out: place a reject line above a broad allow line to exclude a specific role, database or range. ## Operational details that bite - **Reload, don't restart, but do reload.** The rules are loaded into the server on startup/reload, not read per connection. Editing the file changes nothing until you signal a reload. A syntax error in the new file can leave the old rules in force — always check the log and test a real connection. - **`all` is not universal.** Replication connections are not covered by `all` in the database column; they need an explicit `replication` entry. Forgetting it breaks streaming replicas and base backups while ordinary clients work fine. - **Existing sessions are unaffected.** Tightening the rules stops *new* connections; sessions already authenticated keep running until terminated. - **Address matching is about the source the server sees.** Behind a proxy, load balancer or connection pooler, that is the proxy's address — so a per-source-range policy collapses to "anything that reaches the pooler", which is a real hole to reason about. - **The database and user columns are selectors, not grants.** Listing a role on a line does not give it any privilege on anything; it only says which method that role must use to connect. ## What interviewers listen for The two answers that separate candidates: *first match wins with no fall-through on failure*, and *the file decides the method, not the permissions*. Bonus credit for the reload requirement and for recognising the "no entry for host" error as a rules problem rather than a credential problem.
- A connection is refused with an authentication failure even though a later line in the file would have permitted it. Why?Because matching stops at the first line whose type, database, user and address all match, and only that line's method is attempted. A failure under it rejects the connection outright rather than falling through. This is intentional — fall-through would let a client force evaluation down to the weakest matching rule.
- How does putting a connection pooler or proxy in front of the database change what these rules can enforce?The server sees the pooler's address as the source for every connection, so address-based rules can no longer distinguish real clients. The policy effectively becomes 'anything that can reach the pooler', pushing source-based control out to the pooler's own configuration and the network layer. It also means one credential is often shared for many upstream clients, which weakens per-client attribution.
saying these in an interview costs you the question
- Thinking a failed method falls through to later matching lines
- Appending a hardened rule at the bottom under a broad rule that already matches
- Believing listing a role on a line grants it privileges in the database
- Using trust on a network range 'temporarily' to unblock an application
- Editing the file and expecting it to take effect without a reload, or expecting it to drop existing sessions