From 8fa866baaa20750fbdceb7ef88262b75811a36d1 Mon Sep 17 00:00:00 2001 From: senke Date: Wed, 11 Feb 2026 22:43:09 +0100 Subject: [PATCH] fix(security): harden docker-compose.prod.yml and staging -- sslmode, secrets Production (docker-compose.prod.yml): - Change sslmode=disable to sslmode=require on all 3 DATABASE_URLs - Replace JWT_SECRET fallback defaults with :? syntax (fails if unset) - Replace DB_PASS default 'password' with :? syntax (fails if unset) - Separate RABBITMQ_PASS from DB_PASS, require explicit setting Staging (docker-compose.staging.yml): - Add sslmode=require to DATABASE_URL - Replace all default passwords with :? syntax (fails if unset) docker-compose up with these files will now FAIL if required secrets are not explicitly provided via environment variables. Addresses audit findings: A02 (Cryptographic Failures), section 7 (Infra). Co-authored-by: Cursor --- docker-compose.prod.yml | 16 ++++++++-------- docker-compose.staging.yml | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 1426e4b3a..c51d79ee9 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -10,7 +10,7 @@ services: restart: unless-stopped environment: POSTGRES_USER: ${DB_USER:-veza} - POSTGRES_PASSWORD: ${DB_PASS:-password} + POSTGRES_PASSWORD: ${DB_PASS:?DB_PASS must be set for production} POSTGRES_DB: ${DB_NAME:-veza} volumes: - postgres_data:/var/lib/postgresql/data @@ -52,7 +52,7 @@ services: restart: unless-stopped environment: RABBITMQ_DEFAULT_USER: ${DB_USER:-veza} - RABBITMQ_DEFAULT_PASS: ${DB_PASS:-password} + RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS:?RABBITMQ_PASS must be set for production} volumes: - rabbitmq_data:/var/lib/rabbitmq healthcheck: @@ -80,10 +80,10 @@ services: restart: unless-stopped environment: - APP_ENV=production - - DATABASE_URL=postgres://${DB_USER:-veza}:${DB_PASS:-password}@postgres:5432/${DB_NAME:-veza}?sslmode=disable + - DATABASE_URL=postgres://${DB_USER:-veza}:${DB_PASS:?DB_PASS must be set}@postgres:5432/${DB_NAME:-veza}?sslmode=require - REDIS_URL=redis://redis:6379 - - AMQP_URL=amqp://${DB_USER:-veza}:${DB_PASS:-password}@rabbitmq:5672 - - JWT_SECRET=${JWT_SECRET:-change-me-in-production-minimum-32-characters} + - AMQP_URL=amqp://${DB_USER:-veza}:${RABBITMQ_PASS:?RABBITMQ_PASS must be set}@rabbitmq:5672 + - JWT_SECRET=${JWT_SECRET:?JWT_SECRET must be set for production} - COOKIE_SECURE=true - COOKIE_SAME_SITE=strict - COOKIE_HTTP_ONLY=true @@ -111,9 +111,9 @@ services: container_name: veza_chat_server restart: unless-stopped environment: - - DATABASE_URL=postgres://${DB_USER:-veza}:${DB_PASS:-password}@postgres:5432/${DB_NAME:-veza}?sslmode=disable + - DATABASE_URL=postgres://${DB_USER:-veza}:${DB_PASS:?DB_PASS must be set}@postgres:5432/${DB_NAME:-veza}?sslmode=require - REDIS_URL=redis://redis:6379 - - JWT_SECRET=${JWT_SECRET:-change-me-in-production-minimum-32-characters} + - JWT_SECRET=${JWT_SECRET:?JWT_SECRET must be set for production} - PORT=3000 depends_on: postgres: @@ -136,7 +136,7 @@ services: container_name: veza_stream_server restart: unless-stopped environment: - - DATABASE_URL=postgres://${DB_USER:-veza}:${DB_PASS:-password}@postgres:5432/${DB_NAME:-veza}?sslmode=disable + - DATABASE_URL=postgres://${DB_USER:-veza}:${DB_PASS:?DB_PASS must be set}@postgres:5432/${DB_NAME:-veza}?sslmode=require - REDIS_URL=redis://redis:6379 - PORT=3001 depends_on: diff --git a/docker-compose.staging.yml b/docker-compose.staging.yml index bc1f3b5cd..785b5ccfb 100644 --- a/docker-compose.staging.yml +++ b/docker-compose.staging.yml @@ -9,7 +9,7 @@ services: restart: unless-stopped environment: POSTGRES_USER: veza - POSTGRES_PASSWORD: ${STAGING_DB_PASSWORD:-staging_password} + POSTGRES_PASSWORD: ${STAGING_DB_PASSWORD:?STAGING_DB_PASSWORD must be set} POSTGRES_DB: veza_staging volumes: - postgres_staging_data:/var/lib/postgresql/data @@ -36,7 +36,7 @@ services: restart: unless-stopped environment: RABBITMQ_DEFAULT_USER: veza - RABBITMQ_DEFAULT_PASS: ${STAGING_RABBITMQ_PASSWORD:-staging_password} + RABBITMQ_DEFAULT_PASS: ${STAGING_RABBITMQ_PASSWORD:?STAGING_RABBITMQ_PASSWORD must be set} volumes: - rabbitmq_staging_data:/var/lib/rabbitmq healthcheck: @@ -56,11 +56,11 @@ services: - DB_HOST=postgres - DB_PORT=5432 - DB_USER=veza - - DB_PASSWORD=${STAGING_DB_PASSWORD:-staging_password} + - DB_PASSWORD=${STAGING_DB_PASSWORD:?STAGING_DB_PASSWORD must be set} - DB_NAME=veza_staging - - DATABASE_URL=postgresql://veza:${STAGING_DB_PASSWORD:-staging_password}@postgres:5432/veza_staging + - DATABASE_URL=postgresql://veza:${STAGING_DB_PASSWORD:?STAGING_DB_PASSWORD must be set}@postgres:5432/veza_staging?sslmode=require - REDIS_URL=redis://redis:6379 - - RABBITMQ_URL=amqp://veza:${STAGING_RABBITMQ_PASSWORD:-staging_password}@rabbitmq:5672/%2f + - RABBITMQ_URL=amqp://veza:${STAGING_RABBITMQ_PASSWORD:?STAGING_RABBITMQ_PASSWORD must be set}@rabbitmq:5672/%2f - JWT_SECRET=${STAGING_JWT_SECRET} - ENABLE_CLAMAV=false - LOG_DIR=/var/log/veza