pg_hba.conf & Authentication
pg_hba.conf (host-based authentication) decides which clients may connect, from which addresses, to which databases, using which auth method. It is your first network and identity firewall.
Search across all documentation pages
pg_hba.conf (host-based authentication) decides which clients may connect, from which addresses, to which databases, using which auth method. It is your first network and identity firewall.
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
hostssl myapp app_user 10.0.0.0/8 scram-sha-256# Validate syntax and reload
sudo -u postgres pg_ctl reload -D /var/lib/postgresql/18/mainWhen to reach for this: Any time you open Postgres beyond localhost, add an app role, or rotate auth methods.
# Reject by default - explicit allows only
host all all 0.0.0.0/0 reject
# App tier subnet
hostssl myapp_prod app_rw 10.10.1.0/24 scram-sha-256
hostssl myapp_prod app_ro 10.10.2.0/24 scram-sha-256
# Replication from standby subnet
host replication replicator 10.10.3.10/32 scram-sha-256
# Local admin socket
local all postgres peer-- Create login roles with passwords (stored as SCRAM verifier)
CREATE ROLE app_rw LOGIN PASSWORD 'rotate-me-via-vault';
CREATE ROLE app_ro LOGIN PASSWORD 'rotate-me-via-vault';
GRANT CONNECT ON DATABASE myapp_prod TO app_rw, app_ro;What this demonstrates:
hostssl requires TLS - use for remote app connectionsreject as catch-all after specific rules (order matters - first match wins)replication is a pseudo-database for physical replication connections| Field | Values | Meaning |
|---|---|---|
| TYPE | local, host, hostssl, hostnossl | Socket vs TCP; TLS requirement |
| DATABASE | name, all, sameuser, replication | Target database |
| USER | name, all, +group | + prefix matches group roles |
| ADDRESS | CIDR, hostname | Omit for local |
| METHOD | scram-sha-256, cert, peer, reject | How identity is verified |
# Preferred for password auth (PG 10+)
password_encryption = scram-sha-256 # in postgresql.conf
# Certificate auth (mTLS)
hostssl all app_user 0.0.0.0/0 cert clientcert=verify-fullmd5 is legacy - migrate to scram-sha-256.trust and password (cleartext) are audit failures - never on networks.peer maps OS user to DB user on Unix sockets - good for local postgres admin.DATABASE and USER - avoid all all on wide CIDRs.listen_addresses only on internal NICs when possible.pg_hba.conf changes apply on SIGHUP reload - no restart.pg_hba_file_rules view (PG 12+):SELECT line_number, error FROM pg_hba_file_rules WHERE error IS NOT NULL;host all all 0.0.0.0/0 scram before a reject never reaches reject. Fix: Most specific rules first, reject last.hostssl + valid server cert, or VPN/private link only.peer only works for local socket connections. Fix: Use scram-sha-256 or cert for host entries.host replication replicator <standby-ip>/32 scram-sha-256.::1 open with trust while IPv4 is locked. Fix: Mirror policies for ::1/128 or disable IPv6 listener.| Alternative | Use When | Don't Use When |
|---|---|---|
cert client authentication | mTLS service mesh, no shared passwords | Clients cannot manage cert rotation |
| RDS security groups | Managed cloud network ACL | Self-hosted bare metal |
| SSH tunnel to localhost | Emergency admin access | Production app steady-state path |
SHOW hba_file; or pg_config --hbafile on some installs. Usually alongside postgresql.conf in PGDATA.
Check server log after log_connections = on. Common causes: no matching rule, pg_hba.conf typo, or SSL required but client uses plain.
SCRAM stores salted verifiers and does not send reusable password hashes on the wire. Migrate roles with ALTER ROLE ... PASSWORD 'new'.
Yes via ldap or radius methods - common in enterprises. Still keep narrow CIDR rules.
No. Existing sessions keep their original auth context; new connections use the updated file.
Stack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, and PostGIS 3.5+.
Reviewed by Chris St. John·Last updated Jul 18, 2026