From d1347ff296821c122902ec288499bd60d7c90330 Mon Sep 17 00:00:00 2001 From: "rhea-security[bot]" <301977876+rhea-security[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 11:16:33 +0000 Subject: [PATCH] fix(configuration): arcjet protection silently disabled when ARCJET_KEY is missing --- .env.example | 3 ++- DEPLOYMENT.md | 18 +++++++++++++++--- lib/arcjet.ts | 13 +++++++------ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/.env.example b/.env.example index 7e9817a..ce233f8 100644 --- a/.env.example +++ b/.env.example @@ -24,5 +24,6 @@ POLAR_ACCESS_TOKEN="" POLAR_SUCCESS_URL="http://localhost:3000/settings" POLAR_WEBHOOK_SECRET="" # Arcjet - get your key at https://arcjet.com -# Required if ARCJET_ENABLED=true in config.ts +# Required in production when appConfig.arcjet.enabled=true (default). +# Without it, the app throws on startup in production; local dev disables protection with a warning. ARCJET_KEY=ajkey_yourKeyHere diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 3d7d4a1..21bf9dc 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -44,7 +44,18 @@ Gridly uses the Vercel AI SDK and is configured to use Google's Gemini 2.0 Flash --- -## 4. Deploy to Vercel +## 4. Get your Arcjet Key (required for WAF / bot / rate limits) + +Gridly enables Arcjet by default (`appConfig.arcjet.enabled`). In production, **`ARCJET_KEY` is required** when that flag is true; the app will throw on startup if the key is missing so protection cannot fail open silently. + +1. Create an account at [Arcjet](https://arcjet.com) and create a site/key for your project. +2. Copy the key. You will need it as your `ARCJET_KEY` environment variable. + +If you intentionally want to run without Arcjet, set `appConfig.arcjet.enabled` to `false` in `config.ts` before deploying. + +--- + +## 5. Deploy to Vercel Now that you have your external services ready, it's time to push your code. @@ -61,6 +72,7 @@ Now that you have your external services ready, it's time to push your code. | `BETTER_AUTH_SECRET` | Your randomly generated string (from Step 2) | | `BETTER_AUTH_URL` | The URL Vercel will give you (e.g., `https://my-gridly-app.vercel.app`) | | `GOOGLE_GENERATIVE_AI_API_KEY` | Your Google API Key (from Step 3) | +| `ARCJET_KEY` | Your Arcjet API key (from Step 4; required when Arcjet is enabled) | *(Note: If you have set up OAuth providers like GitHub or Google, or Polar payments, add those API keys and Client IDs here as well).* @@ -70,7 +82,7 @@ Vercel will build the Next.js application. --- -## 5. Migrate your Database +## 6. Migrate your Database Vercel just deployed the frontend code, but your Neon database is still completely empty. Your app will crash if you try to log in right now because the users tables don't exist yet! @@ -87,7 +99,7 @@ Vercel just deployed the frontend code, but your Neon database is still complete --- -## 6. You're Live! 🚀 +## 7. You're Live! 🚀 Go to your Vercel URL. You should see the Gridly landing page. Click **Log in**, complete the sign-up flow, and enjoy your new blazing-fast SaaS stack. diff --git a/lib/arcjet.ts b/lib/arcjet.ts index c386802..dd38540 100644 --- a/lib/arcjet.ts +++ b/lib/arcjet.ts @@ -10,19 +10,20 @@ const arcjetKey = process.env.ARCJET_KEY?.trim(); type ArcjetRules = Parameters["withRule"]>[0]; -let hasWarnedMissingKey = false; - function shouldEnableArcjet() { if (!arcjetConfig.enabled) return false; + if (arcjetKey) return true; - if (!hasWarnedMissingKey) { - hasWarnedMissingKey = true; - console.warn( - "[Arcjet] ARCJET_KEY is missing; Arcjet protection is disabled. Set ARCJET_KEY or turn off appConfig.arcjet.enabled.", + if (process.env.NODE_ENV === "production") { + throw new Error( + "ARCJET_KEY is required when appConfig.arcjet.enabled=true in production", ); } + console.warn( + "[Arcjet] ARCJET_KEY missing; protection disabled in non-production.", + ); return false; }