diff --git a/tests/harness/compose.yml b/tests/harness/compose.yml index 3fe185cc..1a382a6a 100644 --- a/tests/harness/compose.yml +++ b/tests/harness/compose.yml @@ -86,13 +86,13 @@ services: PLATFORM_URL: "http://tenant:8080" MOLECULE_ENV: "production" # SECRETS_ENCRYPTION_KEY is required when MOLECULE_ENV=production — - # crypto.InitStrict() refuses to boot without it ("32 bytes raw or - # base64-encoded"). The harness uses a clearly-test sentinel so the - # production code path is exercised end-to-end (including the - # encrypted-secret reads/writes) without coupling to a real key. - # Value is base64 of the literal string "harness-test-only-not-for-prod!!" - # (exactly 32 bytes). Do NOT copy this to any other environment. - SECRETS_ENCRYPTION_KEY: "aGFybmVzcy10ZXN0LW9ubHktbm90LWZvci1wcm9kISE=" + # crypto.InitStrict() refuses to boot without it. up.sh generates a + # fresh 32-byte key per harness lifetime via `openssl rand -base64 32` + # and exports it into this compose file's interpolation environment. + # The :? sentinel makes the misuse loud — running `docker compose up` + # directly without going through up.sh fails fast with a clear error + # rather than getting a confusing tenant-unhealthy timeout. + SECRETS_ENCRYPTION_KEY: "${SECRETS_ENCRYPTION_KEY:?must be set — run via tests/harness/up.sh, which generates one per run}" # ADMIN_TOKEN flips the platform into strict-auth mode (matches # production's CP-minted token configuration). Seeded value lets # E2E scripts authenticate without going through CP. diff --git a/tests/harness/up.sh b/tests/harness/up.sh index b3c87936..fbc14910 100755 --- a/tests/harness/up.sh +++ b/tests/harness/up.sh @@ -18,6 +18,22 @@ for arg in "$@"; do esac done +# Generate a per-run encryption key. The tenant runs with +# MOLECULE_ENV=production (intentional, to replay prod-shape bugs), and +# crypto.InitStrict() refuses to boot without SECRETS_ENCRYPTION_KEY. +# Generate fresh so: +# - No key-shaped string lives in the repo (avoids muscle-memorying a +# hardcoded value into other places + secret-scanner false positives). +# - Each harness lifetime gets a unique key, mimicking prod's per-tenant +# isolation. Persistence across runs isn't required — the harness DB +# is wiped on every ./down.sh. +# Honor a caller-supplied value if already exported (lets a debug session +# pin a key for reproducibility). +if [ -z "${SECRETS_ENCRYPTION_KEY:-}" ]; then + SECRETS_ENCRYPTION_KEY=$(openssl rand -base64 32) + export SECRETS_ENCRYPTION_KEY +fi + if [ "$REBUILD" = true ]; then docker compose -f compose.yml build --no-cache tenant cp-stub fi