Trace a PostgreSQL connection from HBA first-match selection through SCRAM, peer, certificate, GSSAPI, and PostgreSQL 18 OAuth concepts; diagnose rules with pg_hba_file_rules and prove why later broad rules cannot override an earlier match.

pg_hba.conf Rule Matching, Authentication Methods, SCRAM, Certificates, and OAuth Concepts

Trace a PostgreSQL connection from HBA first-match selection through SCRAM, peer, certificate, GSSAPI, and PostgreSQL 18 OAuth concepts; diagnose rules with pg_hba_file_rules and prove why later broad rules cannot override an earlier match.

Intermediate → Advanced180–240 minutesPostgreSQL security engineeringCurrent patched PostgreSQL 18.x; verify current minor at lab timeCore PostgreSQL; OpenSSL used only for the free local TLS labServiceHub disposable objects: app.ch20_* and ch20_* rolesAdmin/superuser required for HBA/TLS/server-role exercisesLocal/free tooling; no paid identity provider requiredLast reviewed: August 2026

Learning outcomes

ServiceHub is moving from a single developer laptop to multiple application processes, administrators, and monitoring clients. Before PostgreSQL checks whether a role has SELECT on a table, it must decide whether the incoming network or local-socket connection may authenticate at all. That decision begins with pg_hba.conf: the Host-Based Authentication file.

01

Explain the connection type, database, user, address, method, and option fields in an HBA record.

02

Apply PostgreSQL's first-matching-record rule and diagnose why there is no fallback after authentication failure.

03

Create and verify a SCRAM-SHA-256 login without exposing its password verifier.

04

Place peer, certificate, GSSAPI, and OAuth in the correct platform/build/topology boundaries.

05

Use pg_hba_file_rules plus server reload/log evidence to validate changes before blaming roles or privileges.

Connection pipeline

A client reaches the listening socket/port → PostgreSQL finds the first matching HBA record → that record's authentication method succeeds or fails → only then is a session established as a database role → SQL privileges and RLS decide what that authenticated role can do. Authentication and authorization are separate layers.

1. Inspect the active HBA source before editing it

sql · HBA file location and parsed rules
SHOW hba_file;SELECT rule_number, file_name, line_number,       type, database, user_name,       address, netmask, auth_method,       options, errorFROM pg_hba_file_rulesORDER BY rule_number;

pg_hba_file_rules parses the server's configured HBA files and includes syntax/configuration errors. It does not prove that a firewall permits the client, that DNS behaves as expected, or that a supplied password/certificate/token is valid. It proves how PostgreSQL currently parses the rules.

2. First match wins—there is no backup rule

For every connection attempt, PostgreSQL scans HBA records in order. The first record whose connection type, database, role, and client address match is selected. If authentication then fails, PostgreSQL does not continue searching for a friendlier later line.

conf · deliberately wrong ordering
# TYPE  DATABASE        USER            ADDRESS          METHODhost    servicehub_lab  ch20_api_login  127.0.0.1/32     rejecthost    servicehub_lab  ch20_api_login  127.0.0.1/32     scram-sha-256host    all             all             127.0.0.1/32     scram-sha-256

The first line matches the ServiceHub API login and rejects it. Adding a broader allow rule below cannot override that decision. The repair is to remove/reorder the specific rule according to policy, not append increasingly broad records until the connection happens to work.

conf · repaired least-privilege order
# TYPE  DATABASE        USER            ADDRESS          METHODhost    servicehub_lab  ch20_api_login  127.0.0.1/32     scram-sha-256host    servicehub_lab  ch20_admin      127.0.0.1/32     scram-sha-256host    all             all             127.0.0.1/32     reject

Specific permitted identities come before the terminal local-TCP reject. Real production rules should constrain actual networks rather than copying loopback addresses blindly.

3. Create a SCRAM login without leaking credentials

sql · role and verifier policy
DROP ROLE IF EXISTS ch20_api_login;CREATE ROLE ch20_api_login LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;SHOW password_encryption;SET password_encryption = 'scram-sha-256';
psql · set the password interactively
\password ch20_api_login

The password is entered interactively so it is not written into SQL history or this lesson. PostgreSQL stores a verifier, not the plaintext password. Reading pg_authid is privileged; even in an admin lab, inspect only the verifier format rather than printing the verifier itself.

sql · admin-only verifier-type check
SELECT rolname,       CASE         WHEN rolpassword LIKE 'SCRAM-SHA-256$%' THEN 'SCRAM-SHA-256 verifier'         WHEN rolpassword LIKE 'md5%' THEN 'legacy MD5 verifier'         WHEN rolpassword IS NULL THEN 'no password'         ELSE 'other/unknown'       END AS stored_password_formatFROM pg_authidWHERE rolname = 'ch20_api_login';

PostgreSQL 18 deprecates MD5-encrypted password authentication. For new deployments, use SCRAM-capable clients and scram-sha-256 HBA rules. When TLS is used, modern libpq can also use SCRAM channel binding; requiring channel binding is a client-side anti-spoofing control, not a replacement for TLS certificate verification.

4. Reload and validate configuration

sql · reload HBA and inspect parser errors
SELECT pg_reload_conf();SELECT rule_number, line_number, type, database, user_name,       address, auth_method, options, errorFROM pg_hba_file_rulesORDER BY rule_number;

On Unix-like systems, HBA edits are reread on SIGHUP/reload. PostgreSQL documentation notes that Windows applies HBA changes to subsequent new connections immediately. Either way, existing authenticated sessions do not become re-authenticated simply because the file changed.

5. Diagnose one failed connection by layer

shell · client-side connection attempt
psql "host=127.0.0.1 port=55432 dbname=servicehub_lab user=ch20_api_login application_name=ch20_hba_test" 

If it fails, classify the failure in order: TCP/socket reachability → whether an HBA record matched → authentication method → supplied credential/token/certificate → role LOGIN state → database CONNECT. A later SQL permission denied for table means authentication already succeeded and the incident has moved into authorization.

sql · role/database authorization preflight
SELECT rolname, rolcanlogin, rolvaliduntilFROM pg_rolesWHERE rolname = 'ch20_api_login';SELECT has_database_privilege(  'ch20_api_login',  'servicehub_lab',  'CONNECT') AS can_connect_to_database;

6. Authentication methods belong to different trust models

Method Identity source Boundary
scram-sha-256 PostgreSQL password verifier + challenge/response General password authentication; prefer TLS/anti-spoofing on networks
peer Operating-system identity Local Unix-domain socket connections
cert Trusted TLS client certificate identity hostssl; certificate chain and username/map semantics
gss GSSAPI/Kerberos-style infrastructure TCP/IP and external realm/service configuration
oauth OAuth bearer token + validator module PostgreSQL 18, OAuth-capable build, external authorization server, server validator

Do not choose a method by perceived modernity. Choose it by identity source, threat model, client/platform support, operational ownership, and incident/revocation requirements.

7. Peer authentication is not a remote password substitute

conf · local socket peer example
# TYPE  DATABASE        USER            ADDRESS  METHODlocal   servicehub_lab  ch20_local_dba           peer

Peer asks the operating system who owns the connecting local process and compares/maps that identity to the requested PostgreSQL role. It is useful for tightly controlled local administration. It cannot authenticate arbitrary remote TCP clients because the server cannot ask its local kernel who owns a process on another machine.

8. Certificate authentication combines TLS with client identity

conf · conceptual client-certificate rule
# Requires TLS server configuration and a trusted client CA.hostssl servicehub_lab ch20_cert_login 10.20.0.0/24 cert map=ch20_cert_map

The cert method requires a valid trusted client certificate and compares certificate identity to the requested database role directly or through a username map. Lesson 2 first focuses on the opposite direction: the client verifying the PostgreSQL server.

9. PostgreSQL 18 OAuth is infrastructure, not a password-replacement keyword

conf · conceptual PostgreSQL 18 OAuth HBA record
# Example shape only; values are provider-specific:hostssl servicehub_lab ch20_oauth_user 10.20.0.0/24 oauth   issuer="https://identity.example.test/tenant-a"   scope="postgresql"   validator="company_oauth_validator"   map=ch20_oauth_map

PostgreSQL 18 adds the oauth HBA method. The issuer and scope are required; a server-side OAuth validator module validates bearer tokens, and libpq client support must have been enabled at build time. PostgreSQL is the OAuth resource server—not the authorization server. The mandatory chapter lab does not invent an identity provider or validator; production OAuth requires a separately secured, tested identity architecture.

Production judgment

Keep HBA rules small, ordered, source-controlled outside secrets, and reviewed with pg_hba_file_rules before reload. Prefer SCRAM over deprecated MD5, require encrypted/verified transport for network credentials, and treat external identity methods as dependencies with their own availability, logging, and revocation design.

10. Checkpoint

Check your understanding

  1. Why cannot a later broad HBA rule rescue a connection that matched an earlier reject?
  2. What does pg_hba_file_rules prove and what does it not prove?
  3. Why inspect only the SCRAM verifier format rather than printing pg_authid.rolpassword?
  4. Where is peer authentication appropriate?
  5. What extra infrastructure does PostgreSQL 18 OAuth require?
Review the answers

HBA stops at the first matching record and never falls through after authentication failure. The view proves parsed rule state/errors, not network reachability or credential validity. Password verifiers are still sensitive authentication material. Peer uses local OS identity over local sockets. OAuth requires an OAuth-capable client/build, an external authorization server/issuer, and a correctly implemented server-side validator module.

Authoritative references

Authentication, TLS, authorization, and policy behavior is security- and version-sensitive. The lesson uses these PostgreSQL 18 primary sources.

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only assets compatible with the Ethereum/ERC-20 network. Do not send TRC-20/TRON assets.