From 7e2481b22524ebdc8d03f44c62a6930cab1d1ab2 Mon Sep 17 00:00:00 2001 From: shankar0123 Date: Sat, 16 May 2026 17:12:42 +0000 Subject: [PATCH] =?UTF-8?q?fix(deploy):=20SEC-014=20=E2=80=94=20loopback-b?= =?UTF-8?q?ind=20Postgres=20host=20port=20in=20compose=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acquisition-audit SEC-014 closure (Sprint 2 ACQ, 2026-05-16). Both deploy/docker-compose.yml and deploy/docker-compose.test.yml published Postgres on `5432:5432` — the short Docker port-mapping form, which binds to 0.0.0.0 by default. On any host with a public-facing NIC, that quietly exposed the Postgres TCP listener to the internet. The certctl-server-to-postgres traffic itself goes over the `certctl-network` Docker bridge, not the host port; the host port mapping is a convenience for operator psql access and for the integration-test runner that lives on the host. Switch both mappings to `127.0.0.1:5432:5432` (loopback-only). Operator psql via `localhost` keeps working; the integration-test runner keeps working; cross-host exposure goes away. Audit trail: docs/operator/security.md (Postgres transport encryption subsection, SEC-014 paragraph). --- deploy/docker-compose.test.yml | 5 ++++- deploy/docker-compose.yml | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/deploy/docker-compose.test.yml b/deploy/docker-compose.test.yml index 4e53f54..15cacf3 100644 --- a/deploy/docker-compose.test.yml +++ b/deploy/docker-compose.test.yml @@ -116,8 +116,11 @@ services: networks: certctl-test: ipv4_address: 10.30.50.2 + # Acquisition-audit SEC-014 closure (Sprint 2, 2026-05-16). + # Loopback-only host-port bind — the integration-test runner on + # the host needs reachability, no other interface does. ports: - - "5432:5432" + - "127.0.0.1:5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U certctl -d certctl"] interval: 5s diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index 584251e..9779cdb 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -145,8 +145,18 @@ services: # default for screenshot/demo use; production deploys never # depend on that fallback. POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + # Acquisition-audit SEC-014 closure (Sprint 2, 2026-05-16). Bind + # the published port to 127.0.0.1 ONLY — the certctl-server + # connection comes in via the `certctl-network` Docker network + # (the host-port mapping is operator convenience for psql / DB + # inspection only). Pre-fix, the "5432:5432" form bound on + # 0.0.0.0, exposing the Postgres TCP listener on every interface + # of any host that happened to be on a public IP. The loopback + # bind keeps host-side psql access working while preventing the + # cross-network exposure landmine for compose deploys that aren't + # behind a firewall. ports: - - "5432:5432" + - "127.0.0.1:5432:5432" volumes: - postgres_data:/var/lib/postgresql/data networks: