diff --git a/apps/backend/.env b/apps/backend/.env index 228c065825..7948f6efb8 100644 --- a/apps/backend/.env +++ b/apps/backend/.env @@ -14,7 +14,7 @@ STACK_SEED_INTERNAL_PROJECT_USER_EMAIL=# default user added to the dashboard STACK_SEED_INTERNAL_PROJECT_USER_PASSWORD=# default user's password, paired with STACK_SEED_INTERNAL_PROJECT_USER_EMAIL STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=# if the default user has access to the internal dashboard project STACK_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=# add github oauth id to the default user -STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=# default publishable client key for the internal project +STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=# default publishable client key for the internal project STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY=# default secret server key for the internal project STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=# default super secret admin key for the internal project diff --git a/apps/backend/.env.development b/apps/backend/.env.development index f20581e078..c6badac70a 100644 --- a/apps/backend/.env.development +++ b/apps/backend/.env.development @@ -13,7 +13,7 @@ STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=true STACK_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS=github,spotify,google,microsoft STACK_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=admin@example.com STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=true -STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=this-super-secret-admin-key-is-for-local-development-only diff --git a/apps/backend/prisma/seed.ts b/apps/backend/prisma/seed.ts index bfc16d617b..dd86dbbf67 100644 --- a/apps/backend/prisma/seed.ts +++ b/apps/backend/prisma/seed.ts @@ -362,15 +362,15 @@ export async function seed() { // internal project using the pck stored here, so it must land before the rest // of the seed even if something later fails. const isLocalEmulator = process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === 'true'; - const rawPck = process.env.STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY; + const rawPck = process.env.STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY; if (isLocalEmulator && !rawPck) { // Emulator images build before a per-VM pck is available. Runtime boots set - // STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY from the VM-generated + // STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY from the VM-generated // random value and re-run the seed, which upserts the internal key set then. console.log('Skipping internal API key set (no pck provided; emulator mode).'); } else { const keySet = { - publishableClientKey: rawPck || throwErr('STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY is not set'), + publishableClientKey: rawPck || throwErr('STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY is not set'), secretServerKey: isLocalEmulator ? (process.env.STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY ?? null) : (process.env.STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY || throwErr('STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY is not set')), diff --git a/apps/backend/src/stack.tsx b/apps/backend/src/stack.tsx index 0fcd087b8e..170dc08860 100644 --- a/apps/backend/src/stack.tsx +++ b/apps/backend/src/stack.tsx @@ -17,7 +17,7 @@ export function getStackServerApp() { return new StackServerApp({ projectId: 'internal', tokenStore: null, - publishableClientKey: getEnvVariable('STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY'), + publishableClientKey: getEnvVariable('STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY'), secretServerKey: getEnvVariable('STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY'), }); } diff --git a/docker/local-emulator/generate-env-development.mjs b/docker/local-emulator/generate-env-development.mjs index 1266c2bae8..74d0a8c921 100644 --- a/docker/local-emulator/generate-env-development.mjs +++ b/docker/local-emulator/generate-env-development.mjs @@ -90,7 +90,7 @@ const entries = [ fromSource("apps/backend/.env.development", backendEnv, "STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST"), fromSource("apps/backend/.env.development", backendEnv, "STACK_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS"), fromSource("apps/backend/.env.development", backendEnv, "STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS"), - // STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY is generated per-VM at boot + // STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY is generated per-VM at boot // by docker/local-emulator/qemu/cloud-init/emulator/user-data and injected via // /run/stack-auth/local-emulator.env. SECRET_SERVER_KEY and SUPER_SECRET_ADMIN_KEY // are intentionally omitted so the seed script leaves them null on the internal diff --git a/docker/local-emulator/qemu/cloud-init/emulator/user-data b/docker/local-emulator/qemu/cloud-init/emulator/user-data index cad28a9166..b87d9b00c9 100644 --- a/docker/local-emulator/qemu/cloud-init/emulator/user-data +++ b/docker/local-emulator/qemu/cloud-init/emulator/user-data @@ -117,7 +117,7 @@ write_files: # Static vars from base config and runtime (e.g. API keys, feature flags) cat /mnt/stack-runtime/base.env cat /mnt/stack-runtime/runtime.env - printf 'STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=%s\n' "$INTERNAL_PCK" + printf 'STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=%s\n' "$INTERNAL_PCK" printf 'STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY=%s\n' "$INTERNAL_SSK" printf 'STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=%s\n' "$INTERNAL_SAK" if [ -n "$EMULATOR_CRON_SECRET" ]; then @@ -502,7 +502,7 @@ write_files: --network host \ --env-file /etc/stack-build.env \ --env-file /etc/stack-build-computed.env \ - -e STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY="$SMOKE_PCK" \ + -e STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY="$SMOKE_PCK" \ -e STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY="$SMOKE_SSK" \ -e STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY="$SMOKE_SAK" \ -e STACK_SKIP_MIGRATIONS=true \ @@ -645,7 +645,7 @@ write_files: rm -f "$tmp" exec docker exec \ - -e STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY \ + -e STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY \ -e STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY \ -e STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY \ -e CRON_SECRET \ diff --git a/docker/local-emulator/qemu/run-emulator.sh b/docker/local-emulator/qemu/run-emulator.sh index cd23da383d..0ed6d4a8e8 100755 --- a/docker/local-emulator/qemu/run-emulator.sh +++ b/docker/local-emulator/qemu/run-emulator.sh @@ -692,7 +692,7 @@ qga_trigger_fast_rotate() { fresh_sak="$(openssl rand -hex 32)" fresh_cron="$(openssl rand -hex 32)" payload=$( - printf 'STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=%s\n' "$fresh_pck" + printf 'STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=%s\n' "$fresh_pck" printf 'STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY=%s\n' "$fresh_ssk" printf 'STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=%s\n' "$fresh_sak" printf 'CRON_SECRET=%s\n' "$fresh_cron" diff --git a/docker/local-emulator/rotate-secrets.sh b/docker/local-emulator/rotate-secrets.sh index d374446426..e8e4a030e1 100644 --- a/docker/local-emulator/rotate-secrets.sh +++ b/docker/local-emulator/rotate-secrets.sh @@ -37,7 +37,7 @@ if [ -n "${STACK_ROTATE_INPUT:-}" ] && [ -f "$STACK_ROTATE_INPUT" ]; then set +a fi -for var in STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY \ +for var in STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY \ STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY \ STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY \ CRON_SECRET; do @@ -55,12 +55,12 @@ done mkdir -p "$(dirname "$OUTPUT")" umask 077 { - printf 'STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=%s\n' "$STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY" + printf 'STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=%s\n' "$STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY" printf 'STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY=%s\n' "$STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY" printf 'STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=%s\n' "$STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY" printf 'CRON_SECRET=%s\n' "$CRON_SECRET" # Mirror these so process.env lookups in Node match env after restart. - printf 'NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=%s\n' "$STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY" + printf 'NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=%s\n' "$STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY" printf 'STACK_SECRET_SERVER_KEY=%s\n' "$STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY" printf 'STACK_SUPER_SECRET_ADMIN_KEY=%s\n' "$STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY" } > "$OUTPUT" @@ -71,13 +71,13 @@ log "wrote $OUTPUT" # container start (see /app-entrypoint.sh). Swap the placeholder hex for the # fresh value across the built tree. Only *.js files need patching; this # runs in ~1s on the standalone Next.js bundles. -if [ "$STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY" != "$PLACEHOLDER_PCK" ]; then +if [ "$STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY" != "$PLACEHOLDER_PCK" ]; then log "rewriting PCK placeholder in $WORK_DIR" # grep -rl narrows the find to only files that contain the placeholder, so # the follow-up sed doesn't walk the whole tree. mapfile -t files < <(grep -rl --include='*.js' "$PLACEHOLDER_PCK" "$WORK_DIR/apps" 2>/dev/null || true) if [ "${#files[@]}" -gt 0 ]; then - sed -i "s|${PLACEHOLDER_PCK}|${STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY}|g" "${files[@]}" + sed -i "s|${PLACEHOLDER_PCK}|${STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY}|g" "${files[@]}" log "patched ${#files[@]} file(s)" else log "no files contained the placeholder (already rotated?)" @@ -91,7 +91,7 @@ if [ -n "${STACK_DATABASE_CONNECTION_STRING:-}" ]; then log "updating internal ApiKeySet" psql "$STACK_DATABASE_CONNECTION_STRING" -v ON_ERROR_STOP=1 <&2 exit 1 fi done - export STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY + export STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY else - export STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=${STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY:-$(openssl rand -base64 32)} + export STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=${STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY:-$(openssl rand -base64 32)} export STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY=${STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY:-$(openssl rand -base64 32)} export STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=${STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY:-$(openssl rand -base64 32)} fi export NEXT_PUBLIC_STACK_PROJECT_ID=internal -export NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=${STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY} +export NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=${STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY} if [ -n "${STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY:-}" ]; then export STACK_SECRET_SERVER_KEY=${STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY} fi @@ -99,10 +99,10 @@ fi # - ssk/sak: required by the emulator's own dashboard (StackServerApp ctor # throws without ssk). User-app flows don't use these — per-project # credentials come from the /local-emulator/project route. -if [ "$NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR" = "true" ] && [ -n "${STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY:-}" ] && [ -n "${STACK_DATABASE_CONNECTION_STRING:-}" ]; then +if [ "$NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR" = "true" ] && [ -n "${STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY:-}" ] && [ -n "${STACK_DATABASE_CONNECTION_STRING:-}" ]; then # Validate the keys are hex-only to defuse any SQL-injection risk (the VM # generates them via `openssl rand -hex 32`, so this is an assert, not a filter). - for varname in STACK_SEED_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY; do + for varname in STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY STACK_SEED_INTERNAL_PROJECT_SECRET_SERVER_KEY STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY; do val="${!varname:-}" if [ -z "$val" ]; then echo "ERROR: $varname is not set; refusing to bootstrap internal api key set." >&2 @@ -117,7 +117,7 @@ if [ "$NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR" = "true" ] && [ -n "${STACK_SEED_INT psql "$STACK_DATABASE_CONNECTION_STRING" -v ON_ERROR_STOP=1 <