PostgreSQL Healthcare Security Configuration Guide: HIPAA-Compliant Encryption, Access Controls, and Auditing
This guide shows you how to harden PostgreSQL for healthcare workloads so Protected Health Information (PHI) is protected end to end. You will implement encryption, granular authorization, auditing, and recoverability aligned to HIPAA’s Security Rule.
Follow each section in order: translate HIPAA requirements into database controls, enforce encryption at rest and in transit, apply least-privilege and row-level security for PHI, capture trustworthy audit trails, and design a backup strategy that supports point-in-time recovery and retention mandates.
Implement HIPAA Compliance Requirements
Map HIPAA safeguards to PostgreSQL
- Administrative: complete a risk analysis, maintain policies, conduct access reviews, and sign a Business Associate Agreement (BAA) with hosting, backup, and monitoring providers.
- Technical: enforce access control (roles, RLS), audit controls (pgAudit logging), integrity (checksums, backups), authentication (strong credentials, MFA upstream), and transmission security (TLS).
- Physical: restrict server/volume access, protect keys, and secure off-site backups.
Foundational configuration checklist
- Scope PHI tables and minimize fields; tokenize or de-identify when possible.
- Use separate environments and VPC network controls; restrict inbound to application subnets and bastions only.
- Harden roles: no shared accounts; avoid superuser; disable unnecessary privileges (CREATEDB, CREATEROLE).
- Time-sync all systems for accurate audits; standardize log formats; define retention and secure archives.
- Document key management and rotation; monitor for anomalous access; test incident response and restore procedures.
Configure Encryption at Rest
HIPAA expects reasonable encryption for stored PHI. Because native Transparent Data Encryption (TDE) is not universally available in upstream PostgreSQL, prioritize platform or OS-level encryption plus selective column-level protection using the pgcrypto extension.
Primary options
- Full-disk or filesystem encryption: use dm-crypt/LUKS, BitLocker, or ZFS native encryption for the data directory, WAL, temp files, and swap. In cloud, enable volume encryption with customer-managed keys.
- Backups and snapshots: encrypt base backups and Write-Ahead Logging (WAL) archives with a KMS-managed key; restrict key usage by principal and region.
- Column-level encryption: apply the pgcrypto extension to the highest-risk PHI fields (for example, SSN, medical record numbers) to prevent exposure in plaintext copies.
pgcrypto example (application-supplied keys)
-- Enable once per database
CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- Example table with selectively encrypted columns
CREATE TABLE patients (
id bigserial PRIMARY KEY,
full_name text NOT NULL,
ssn_enc bytea, -- encrypted SSN
dob date,
contact_phone text
);
-- Insert with application-supplied key material (do not hardcode keys in SQL)
INSERT INTO patients (full_name, ssn_enc, dob, contact_phone)
VALUES (
$1,
pgp_sym_encrypt($2, $3, 'cipher-algo=aes256, compress-algo=1'),
$4,
$5
);
-- Decrypt when strictly required
SELECT id,
full_name,
pgp_sym_decrypt(ssn_enc, $3)::text AS ssn
FROM patients
WHERE id = $1;
Manage keys outside PostgreSQL (KMS/HSM or a vault), rotate them on a schedule, and re-encrypt data using envelope encryption to avoid touching raw master keys.
Ready to simplify HIPAA compliance?
Join thousands of organizations that trust Accountable to manage their compliance needs.
Additional hardening
- Initialize clusters with data checksums and verify regularly; monitor for corruption.
- Encrypt temporary directories and swap; pin secrets in memory only as needed.
- Restrict filesystem permissions on the data directory, backups, and WAL archives.
Enforce Encryption in Transit
Always require TLS between clients, application servers, replicas, and backup pipelines. Disable plaintext connections and weak protocols.
postgresql.conf essentials
ssl = on
ssl_min_protocol_version = 'TLSv1.2' # Prefer TLSv1.3 if supported
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root-ca.crt'
ssl_prefer_server_ciphers = on
password_encryption = scram-sha-256
pg_hba.conf hostssl entries
# Require TLS + SCRAM for app servers
hostssl mydb app_user 10.0.0.0/8 scram-sha-256
Ready to simplify HIPAA compliance?
Join thousands of organizations that trust Accountable to manage their compliance needs.