security: fail-fast dev-bypass flag in production (#42)

Both auth.ts and trpc.ts now delegate the E2E_TEST_MODE-in-production
check to a single shared helper (packages/api/src/lib/runtime-security.ts).
trpc.ts used to only console.warn; it now throws at module load time,
matching the behaviour already enforced by assertSecureRuntimeEnv on the
auth side. A future refactor can no longer silently drop the guard on
either side.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 08:56:27 +02:00
parent c2d05b4b99
commit 93a7fbaa4c
5 changed files with 92 additions and 10 deletions
+6 -4
View File
@@ -1,3 +1,5 @@
import { getDevBypassViolations } from "@capakraken/api/lib/runtime-security";
const DISALLOWED_PRODUCTION_SECRETS = new Set([
"dev-secret-change-in-production",
"changeme",
@@ -39,12 +41,12 @@ export function getRuntimeEnvViolations(env: RuntimeEnv = process.env): string[]
if (!authSecret) {
violations.push("AUTH_SECRET or NEXTAUTH_SECRET must be set in production.");
} else if (DISALLOWED_PRODUCTION_SECRETS.has(authSecret)) {
violations.push("AUTH_SECRET or NEXTAUTH_SECRET must not use a known development placeholder in production.");
violations.push(
"AUTH_SECRET or NEXTAUTH_SECRET must not use a known development placeholder in production.",
);
}
if ((env.E2E_TEST_MODE ?? "").trim() === "true") {
violations.push("E2E_TEST_MODE must not be 'true' in production — it disables all rate limiting and session controls.");
}
violations.push(...getDevBypassViolations(env));
if (!authUrl) {
violations.push("AUTH_URL or NEXTAUTH_URL must be set in production.");