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 <cursoragent@cursor.com>
This commit is contained in:
senke 2026-02-11 22:43:09 +01:00
parent 2d3cb18b7c
commit 8fa866baaa
2 changed files with 13 additions and 13 deletions

View file

@ -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:

View file

@ -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