molecule-core/tests/harness/up.sh
Hongming Wang 9dae0503ee fix(harness): generate SECRETS_ENCRYPTION_KEY per-run instead of hardcoding
Replaces the hardcoded base64 sentinel (630dd0da) with a per-run
generation in up.sh, exported into compose's interpolation environment.

Why:
- Hardcoding a 32-byte base64 string in the repo, even one labelled
  "test-only", sets a bad muscle-memory pattern. The next agent or
  contributor copies the shape into another harness — or worse, into a
  staging .env — and the test-only sentinel turns into something
  someone treats as a real key.
- Secret scanners flag key-shaped values regardless of the surrounding
  comment claiming intent. Avoiding the literal entirely sidesteps the
  false-positive.
- A fresh key per harness lifetime more closely mimics prod's
  per-tenant isolation, exercising the same code paths without any
  pretense of stable encrypted-data fixtures (which the harness wipes
  on every ./down.sh anyway).

Implementation:
- up.sh: `openssl rand -base64 32` if SECRETS_ENCRYPTION_KEY isn't
  already set in the caller's env. Honoring a pre-set value lets a
  debug session pin a key for reproducibility (e.g. when investigating
  encrypted-row corruption).
- compose.yml: `${SECRETS_ENCRYPTION_KEY:?…}` makes a misuse loud —
  running `docker compose up` directly bypassing up.sh fails fast with
  a clear error pointing at the right entry point, rather than a 100s
  unhealthy-tenant timeout.

Both paths verified via `docker compose config`:
- with key exported: value interpolates cleanly
- without it: "required variable SECRETS_ENCRYPTION_KEY is missing a
  value: must be set — run via tests/harness/up.sh, which generates
  one per run"
2026-04-30 13:30:14 -07:00

56 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Bring the production-shape harness up.
#
# Usage: ./up.sh [--rebuild]
#
# Always operates in tests/harness/ regardless of where it's invoked
# from — test scripts under tests/harness/replays/ source it via the
# absolute path, so cd-ing first prevents compose-context surprises.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$HERE"
REBUILD=false
for arg in "$@"; do
case "$arg" in
--rebuild) REBUILD=true ;;
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
echo "[harness] starting cp-stub + postgres + redis + tenant + cf-proxy ..."
docker compose -f compose.yml up -d --wait
echo "[harness] /etc/hosts entry for harness-tenant.localhost..."
if ! grep -q '^127\.0\.0\.1[[:space:]]\+harness-tenant\.localhost' /etc/hosts; then
echo " (skip — your /etc/hosts may not resolve *.localhost. If tests fail with"
echo " 'getaddrinfo' errors, add: 127.0.0.1 harness-tenant.localhost)"
fi
echo ""
echo "[harness] up. Tenant: http://harness-tenant.localhost:8080/health"
echo " http://harness-tenant.localhost:8080/buildinfo"
echo " cp-stub: http://localhost (internal-only via compose net)"
echo ""
echo "Next: ./seed.sh # mint admin token + register sample workspaces"