Skip to content

[flags] precompute without FLAGS_SECRET via the deployment key - #597

Draft
luismeyer wants to merge 2 commits into
luismeyer/kms-flags-discoveryfrom
luismeyer/precompute-deployment-key
Draft

luismeyer wants to merge 2 commits into
luismeyer/kms-flags-discoveryfrom
luismeyer/precompute-deployment-key

Conversation

@luismeyer

@luismeyer luismeyer commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Stacked on #589 (luismeyer/kms-flags-discovery). Draft: it depends on an open platform question, see Before this can ship.

What / why

Precompute is the last v4 feature which throws without FLAGS_SECRET. With this change, the precompute functions fall back to a key derived from VERCEL_DEPLOYMENT_KEY when there is no secret.

  • New lib/precompute-secret.ts: deploymentPrecomputeSecret() derives 32 bytes with HKDF-SHA-256 (Web Crypto, so it works in the Edge runtime) and the info flags:precompute:v1. The derived key is not the deployment key itself, so precompute does not share a key with other users of VERCEL_DEPLOYMENT_KEY.
  • Order: the secret argument, then FLAGS_PRECOMPUTE_SECRET (new, the name which standard uses), then FLAGS_SECRET, then the deployment key. With a secret argument or only FLAGS_SECRET, nothing changes.
  • A secret of the user is before the deployment key, so that the build and the runtime agree when only one of them has the deployment key (e.g. vercel build with --prebuilt).
  • The default of the secret parameters in Next.js is now undefined and not process.env.FLAGS_SECRET. The functions read the variables themselves.
  • Next.js: serialize, deserialize, getPrecomputed, generatePermutations (and thus precompute).
  • SvelteKit: precompute, generatePermutations and the read of a precomputed flag, through getPrecomputeSecret in sveltekit/env.ts. The handle fills a missing secret with FLAGS_SECRET, so a secret equal to FLAGS_SECRET does not count as passed: FLAGS_PRECOMPUTE_SECRET wins over it, also when the app passes FLAGS_SECRET to createHandle.
  • Without a secret and without VERCEL_DEPLOYMENT_KEY, the functions throw the same errors as before.

Why a key per deployment is enough

A code is created by the build (generatePermutations) and by the middleware, and read by the pages of the same deployment. Vercel writes VERCEL_DEPLOYMENT_KEY with one value to the build environment and to the runtime environment of a deployment (get-deployment-env-context.ts in vercel/api), so all three use the same key. HS256 is deterministic, so the build and the middleware create the same code for the same values. This is the same reasoning as the build secret of withFlags on standard.

Before this can ship

  • VERCEL_DEPLOYMENT_KEY is behind the workflow feature flag in vercel/api today, and only set when the project exposes the system environment variables. Flags needs it for all projects, or its own variable. No change in vercel/api is part of this PR.
  • vercel build with --prebuilt is not covered: the deployment does not exist at build time, so the build has no key and throws. Such projects must keep FLAGS_SECRET.
  • Local development is not covered: next dev and vite dev have no deployment key and still need FLAGS_SECRET.
  • A code is not valid in another deployment or project. Apps which need that must set FLAGS_SECRET.
  • Not tested on a real deployment, in particular that the Edge middleware can read the variable.

Tests

packages/flags: pnpm test (19 files, 276 tests passed), pnpm type-check, pnpm check and pnpm build are ok.

New tests: the derivation (stable, 32 bytes, different per deployment key, not the key itself), Next.js and SvelteKit without FLAGS_SECRET (the build and the middleware create the same code, a page reads it, a code of another deployment is rejected, the order of the secrets, throws without any key).

🤖 Generated with Claude Code

Co-Authored-By: Claude Code <noreply@anthropic.com>
@vercel

vercel Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
flags-playground Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-dev Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-flagsmith Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-growthbook Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-launchdarkly Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-openfeature Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-posthog Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-reflag Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-snippets Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-statsig Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
flags-sdk-sveltekit-snippets Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
shirt-shop Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC
shirt-shop-api Ready Ready Preview, v0 Nov 11, 2026 1:29pm UTC

Co-Authored-By: Claude Code <noreply@anthropic.com>

This branch was successfully deployed

14 active deployments
Preview – flags-sdk-dev — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-sveltekit-snippets — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-snippets — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-playground — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-launchdarkly — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – shirt-shop — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-growthbook — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-vercel — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-posthog — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-flagsmith — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-reflag — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-statsig — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – flags-sdk-openfeature — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Preview – shirt-shop-api — 602f34d6 Deployed Nov 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant