Security Model
Identify the root of trust and defensive layers before selecting security features. The root of trust needs the strongest protection. Multiple layers preserve some protection if one fails.
Trust Boundaries
Pigsty uses Ansible for declarative deployment. Its administration node is the control plane and needs the strongest protection.
| Role | Assets and Privileges |
|---|---|
| Admin node | The pigsty.yml inventory, which normally contains system and application credentials; the CA private key; SSH administration access to every node |
| INFRA nodes | Monitoring and alerts, DNS, Nginx ingress, and software repositories |
| Database nodes | Database instances, local dbsu, and restricted sudo |
| Clients | Database credentials or client certificates; access through service ports, HBA, and authentication |
These roles have different capabilities, not a simple hierarchy. Protect these three assets in particular:
- The
pigsty.ymlinventory contains component passwords and credentials. Strictly restrict administration node access and access to any Git configuration repository. - The CA private key,
files/pki/ca/ca.key, anchors deployment trust. Its holder can issue any trusted certificate. The file uses mode0600inside a0700directory. Keep an offline backup. - The administration user’s SSH private key provides passwordless sudo access to all enrolled nodes. It effectively grants root access throughout the managed deployment.
Pigsty’s security policy defines this trust boundary. Attacks requiring administration node access, or both pigsty.yml and the CA private key, are not product vulnerabilities. These control-plane assets have high trust by design. Protect them accordingly.
Seven Defensive Layers
Defense in depth combines controls so that one failure does not remove all protection. Pigsty provides seven security layers:
| # | Layer | Mechanisms | Details |
|---|---|---|---|
| 1 | Network boundary | Firewall zones, constrained listen addresses, centralized ingress | This page |
| 2 | Transport encryption | Local CA and TLS between components | Encrypted Communication |
| 3 | Authentication | HBA rules, SCRAM passwords, client certificates | Authentication |
| 4 | Access control | Role model, default privileges, database isolation | Access Control |
| 5 | Host security | SELinux, restricted sudo, dedicated OS users | This page |
| 6 | Data security | Checksums, backup and encryption, PITR, deletion safeguards | Data Security |
| 7 | Audit trail | DDL and connection logs, audit extensions, centralized logs | Data Security |
Layers 2, 3, 4, 6, and 7 have dedicated chapters. The following sections cover the network and host layers.
Network Boundaries
Node provisioning enables firewalld or ufw, depending on the OS. node_firewall_mode defaults to zone. node_firewall_intranet places 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 in the trusted zone. Public networks can reach only node_firewall_public_port ports. Defaults are 22 for SSH and 80/443 for web traffic.
The demo
pigsty.ymlalso exposes5432for local evaluation. Remove this exception in production. If direct database access is needed, restrict sources to explicit CIDRs through security groups, host firewalls, and HBA.
PostgreSQL listens on all addresses by default: pg_listen is 0.0.0.0. Listen addresses, firewall rules, and HBA jointly control access. For stricter access, constrain the listener:
The default firewall blocks direct public access to Grafana, VictoriaMetrics, and other web infrastructure. External web traffic normally uses the Nginx portal. Database traffic uses HAProxy service ports. Fewer entry points simplify hardening and auditing.
Host Security
Give each OS user only the privileges its job requires.
- The database superuser
postgres(pg_dbsu) has no password by default. It can enter the database only through localident.pg_dbsu_sudodefaults tolimit. This permits passwordless database servicesystemctloperations and log viewing, without unrestricted root access. - Operators and playbooks use
node_admin_username, defaultdba. It receives passwordless sudo (nopass) by default. For stricter control, setnode_admin_sudotoallto require a password, orlimitto restrict commands. node_selinux_modedefaults topermissive. SELinux records violations without blocking them, providing a baseline beforeenforcing.
Pigsty does not manage SSH server configuration. Put password-login restrictions, remote-root restrictions, and similar OS hardening in your host security baseline.
Hardening Levels
Harden the deployment in stages. Each level adds to the previous level:
Level 1: default baseline. Defaults provide SCRAM passwords, data checksums, a local CA, component certificates, layered HBA, four-tier roles, backups, and firewall zones. This suits development, testing, and evaluation on a trusted intranet. For production, review credentials and network boundaries, and configure client verification.
Level 2: randomized credentials. Change all public default passwords before any network-exposed deployment. Add -g to randomize recognized built-in parameters and example credentials:
This option does not replace pgBackRest cipher_pass, all Silo examples in ha/safe, or custom values. See the Default Credentials Checklist for coverage.
Level 3: policy hardening with ha/safe. conf/ha/safe.yml combines controls for further customization:
- TLS and certificates: Main TCP HBA rules use
ssl. Public administrator access requires a client certificate. PgBouncer usesrequire, and Patroni API uses HTTPS. Localidentand selected localhost password rules remain. - Password policy: The template preloads
passwordcheckand setsexpire_infor built-in users. Review and replace example passwords. - Reduced exposure: Listen addresses are limited to
${ip},${vip},${lo}. Public connection-pool access is explicitly denied for monitoring and administration accounts. - Backup encryption: pgBackRest uses the remote
miniopreset with AES-256-CBC. Replace the predictable examplepgBR.${pg_cluster}. - Security extensions: The template installs
passwordcheck,credcheck,pgaudit,pgsodium,anonymizer, and related extensions. Installation does not preload, create, or configure them.
Level 4: database hardening with crit.yml. The safe template selects CRIT for workloads that prioritize consistency. Compared with oltp, CRIT:
- Requires checksums regardless of
pg_checksum. - Enables strict synchronous replication (
synchronous_mode_strict). Writes needing synchronous acknowledgment block if no synchronous replica is available. - Logs connections and disconnections. PostgreSQL 18 separates connection receipt, authentication, and authorization.
- Sets watchdog to
automatic. It activates only if a usable device exists.
Strict synchronous mode aims to preserve acknowledged transactions. It depends on synchronous_commit, synchronous replica state, and failover eligibility. Verify RPO with failure exercises on the target topology.
You can select individual controls instead of the whole template:
Next
- π Authentication: HBA rules and password policy
- π€ Access Control: roles and least privilege
- π Encrypted Communication: local CA and TLS
- π Data Security: integrity, backup, and audit
- β Compliance: MLPS and SOC 2 mapping