Architecture

PostgreSQL Security Hardening: A Practical Checklist for Production

Most PostgreSQL breaches do not involve clever exploits. They involve a database reachable from the internet, a shared superuser password or a backup nobody protected. Here is the checklist we use to close those gaps.

· 8 min read · AG Data Team

When a database is breached, the post-mortem rarely describes a sophisticated zero-day. Far more often it describes a PostgreSQL port open to the internet, an application connecting as a superuser, a password shared across five systems, or a backup sitting unencrypted in a storage bucket. These gaps are boring — and that is exactly why they survive for years. This is the checklist we work through on a security review, ordered from the most common problems to the more advanced ones.

1. Limit who can reach the database at all

The cheapest security control is not being reachable. PostgreSQL should listen only on the interfaces it needs (listen_addresses), and a firewall or cloud security group should allow connections only from application servers, poolers and administrative hosts.

2. Make pg_hba.conf strict and explicit

The pg_hba.conf file decides which users may connect to which databases, from where, and how they must authenticate. Read it line by line — rules are matched top to bottom, and the first match wins.

3. Apply least privilege to roles

Applications should not connect as postgres or any other superuser. A practical role model:

Also check the public schema. Since PostgreSQL 15 ordinary users can no longer create objects in it by default, but databases upgraded from older versions keep the old, more permissive rights unless you revoke them: REVOKE CREATE ON SCHEMA public FROM PUBLIC;

A quick test: run SELECT rolname FROM pg_roles WHERE rolsuper;. In most production systems the answer should be one or two roles. We regularly find application accounts, former employees and monitoring users on that list.

4. Encrypt data in transit and at rest

5. Log and audit what matters

Without logs you cannot answer the first question after an incident: what happened, and when? At minimum enable log_connections and log_disconnections, and log DDL with log_statement = 'ddl'. For regulated environments, the pgAudit extension provides detailed, structured audit logging of reads and writes on sensitive tables. Ship logs off the database server, so an attacker with server access cannot quietly erase them.

6. Protect backups as carefully as the database

A backup is a complete copy of your data, often with weaker protection than the original. Restrict who can read the backup storage, encrypt it, keep at least one copy that cannot be deleted or overwritten from the production environment, and — as we describe in our guide to restore testing — prove regularly that it can actually be restored.

7. Keep PostgreSQL patched and supported

Minor releases contain security fixes and are designed to be applied with a simple restart. Apply them within weeks, not years. And make sure every database runs a supported major version: PostgreSQL 14, for example, receives its final update in November 2026 — see what to do about PostgreSQL 14 end of life.

Why this matters for compliance

For many organisations in Latvia and across the EU, NIS2 and the national laws implementing it turn these practices from "good idea" into an obligation: access control, encryption, logging, backup and vulnerability management are all explicitly expected. A documented hardening checklist, applied and reviewed, is also exactly the evidence an auditor will ask for.

Key takeaways

PostgreSQL Security Compliance NIS2
Work with us

Not sure how exposed your database is?

We run a fixed-scope PostgreSQL security review and hand you a prioritised list of fixes — most of which can be applied without downtime.

Get in touch More from the blog