Safeguard
Security Guides•

How pg_hba.conf works: first match wins, and what that means

PostgreSQL checks pg_hba.conf top to bottom and stops at the first matching line. Learn the record format, safe ordering, and how to test changes.

Safeguard Security Team
3 min read

PostgreSQL reads pg_hba.conf from the top and uses the first record that matches the connection type, client address, database and user. If that record's authentication fails, no later record is tried. If nothing matches, access is denied. Ordering is therefore a security decision, not a style choice.

The record format

Each line has a connection type, a database, a user, usually an address, and an authentication method. The main types are local for Unix sockets, host for TCP with or without SSL, hostssl for TCP with SSL only, and hostnossl for TCP without it.

local   all   all                     peer
hostssl all   app_user  10.0.0.0/24   scram-sha-256
host    all   all       0.0.0.0/0     reject

Fields are separated by spaces or tabs, and text after a hash mark is ignored. The address can be a CIDR range, a host name, or a keyword such as samehost.

No fall-through

This is the part people miss. The PostgreSQL manual says there is "no fall-through or backup": if one record is chosen and authentication fails, later records are not considered. A strict rule placed after a loose one never runs.

The documentation suggests earlier records have tight match parameters, with later records looser. Put narrow, specific rules first and broad rules last.

Methods worth knowing

  • trust lets anyone who can connect log in as any database user, with no password. Keep it out of anything reachable over a network.
  • scram-sha-256 verifies the password with SCRAM. This is the one to use for password logins.
  • md5 accepts SCRAM or MD5 and is deprecated. See how to migrate md5 passwords to SCRAM.
  • peer matches the operating system user name to the database user and works only for local connections.
  • cert authenticates with SSL client certificates.
  • reject refuses the connection outright, which is useful as an explicit last line.

Test before you reload

The file is read at startup and on a reload signal, such as pg_ctl reload or pg_reload_conf(). Before reloading, query the pg_hba_file_rules view. Rows with a non-null error field point at the broken lines. A typo in this file can lock out every client, so check first and keep a local admin session open while you reload.

A practical order

  1. Local administration through peer or a tightly scoped rule.
  2. Named application users from their specific subnets, using hostssl and scram-sha-256.
  3. A final reject for everything else, so the denial is visible in the file.

Also decide whether non-SSL TCP should exist at all. If it should not, use hostssl and add a hostnossl reject. Pair that with the right client mode, covered in sslmode require versus verify-full.

Quick check

If the first matching rule fails the password, does PostgreSQL try the next rule?

No. The first matching record decides. If authentication fails under it, the connection is refused and later records are not considered.

Does a missing match allow or deny access?

It denies access. If no record matches, the connection is refused.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.