Skip to content

feat: encrypt injected env blob for secure serverless deployments#656

Open
theoephraim wants to merge 4 commits into
mainfrom
feat/encrypted-env-blob
Open

feat: encrypt injected env blob for secure serverless deployments#656
theoephraim wants to merge 4 commits into
mainfrom
feat/encrypted-env-blob

Conversation

@theoephraim
Copy link
Copy Markdown
Member

@theoephraim theoephraim commented Apr 24, 2026

Summary

Adds support for encrypting the resolved env blob that varlock injects into server-side build output. This protects secrets from leaking via sourcemaps or build artifact inspection on serverless platforms (Vercel, Netlify, Cloudflare Workers, etc.).

Encryption across all integrations

When _VARLOCK_ENV_KEY is set (or @encryptInjectedEnv decorator is enabled), the env blob is encrypted with AES-256-GCM before injection. At runtime, server-only init code decrypts it before initVarlockEnv() runs.

  • Vite / Astro / SvelteKit / TanStack Start — encrypted blob set on globalThis.__varlockEncryptedEnv, decrypted in virtual init module
  • Next.js — encrypted payload in process.env.__VARLOCK_ENV, decrypted by init-server/init-edge bundles
  • Cloudflare Workers — encrypted blob uploaded as CF secret, decrypted in worker init
  • Expo — no encryption needed (same-process)
  • auto-load — encrypts process.env.__VARLOCK_ENV in-place, sets parsed object on globalThis

Architecture

  • Decryption removed from env.ts entirely — no node:crypto dependency in client-bundleable code
  • New globalThis.__varlockEncryptedEnv separates encrypted blobs from parsed objects on __varlockLoadedEnv
  • crypto.ts uses top-level import instead of broken require in ESM output

New root decorators

  • @encryptInjectedEnv — declares encryption intent, supports forEnv(). Auto-generates key for dev servers and Cloudflare deploys, errors on production builds without key
  • @disableProcessEnvInjection — prevents injecting individual vars into process.env, forcing ENV proxy usage. Combined with encryption = zero plaintext secrets in process.env

CLI changes

  • varlock generate-key — fixed for ESM builds
  • varlock run --inject <all|vars|blob> — controls what gets injected into child process env (replaces deprecated --no-inject-graph)

Docs

  • New "Encrypted deployments" guide with platform-specific setup (Vercel, Netlify, Cloudflare)
  • Root decorator reference for both new decorators
  • Integration pages updated with concise notes linking to guide

Test plan

  • varlock generate-key works
  • Auto-load path encrypts/decrypts correctly
  • Auto-generates key when decorator set but no key provided
  • Vite SSR build with @encryptInjectedEnv produces encrypted output
  • Next.js build with _VARLOCK_ENV_KEY produces encrypted runtime files
  • Cloudflare varlock-wrangler deploy auto-generates key
  • @disableProcessEnvInjection prevents individual var injection
  • varlock run --inject blob only injects blob
  • Framework tests pass

@bumpy-bot
Copy link
Copy Markdown
Collaborator

bumpy-bot commented Apr 24, 2026

bumpy-frog

The changes in this PR will be included in the next version bump.

minor Minor releases

  • varlock 1.4.0 → 1.5.0

patch Patch releases

  • @varlock/astro-integration 1.0.3 → 1.0.4 (cascade)
  • @varlock/cloudflare-integration 1.1.4 → 1.1.5
  • @varlock/expo-integration 1.1.0 → 1.1.1
  • @varlock/nextjs-integration 1.1.2 → 1.1.3
  • @varlock/vite-integration 1.1.2 → 1.1.3

Bump files in this PR

Click here if you want to add another bump file to this PR


This comment is maintained by bumpy.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 24, 2026

Open in StackBlitz

varlock

npm i https://pkg.pr.new/varlock@656

@varlock/cloudflare-integration

npm i https://pkg.pr.new/@varlock/cloudflare-integration@656

@varlock/expo-integration

npm i https://pkg.pr.new/@varlock/expo-integration@656

@varlock/nextjs-integration

npm i https://pkg.pr.new/@varlock/nextjs-integration@656

@varlock/vite-integration

npm i https://pkg.pr.new/@varlock/vite-integration@656

commit: ef80c32

@theoephraim theoephraim changed the title feat: encrypt env blob with VARLOCK_ENV_KEY feat: encrypt env blob with _VARLOCK_ENV_KEY Apr 25, 2026
@theoephraim theoephraim force-pushed the feat/encrypted-env-blob branch from d467143 to 93ac514 Compare April 25, 2026 08:35
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 25, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
🔵 In progress
View logs
varlock-website 5978976 May 30 2026, 05:40 AM

When _VARLOCK_ENV_KEY (64-char hex) is set at build time, the resolved
env blob injected into build output is encrypted with AES-256-GCM.
At runtime, the init bundles detect the varlock:v1: prefix and decrypt
using the same key from the runtime environment.

This lets Vercel users set a single env var and have all other config
travel encrypted inside the deployment artifact.

- New crypto module with sync (node:crypto) and async (Web Crypto) paths
- All integration injection points (Next.js, Vite) encrypt when key is present
- _VARLOCK_ENV_KEY auto-excluded from injected blob and type generation
- varlock generate-key CLI command with --plain flag for piping
- Docs for Next.js and Vite integrations
- Framework tests for encrypted blob flow
@theoephraim theoephraim force-pushed the feat/encrypted-env-blob branch from 93ac514 to 5978976 Compare May 30, 2026 05:40
@theoephraim theoephraim changed the title feat: encrypt env blob with _VARLOCK_ENV_KEY feat: encrypted deployments with @encryptInjectedEnv + @disableProcessEnvInjection May 30, 2026
@theoephraim theoephraim changed the title feat: encrypted deployments with @encryptInjectedEnv + @disableProcessEnvInjection feat: encrypt injected env blob for secure serverless deployments May 30, 2026
@theoephraim theoephraim requested a review from philmillman May 30, 2026 05:54
The test was looking for `.next/server/**/*runtime*.js` which doesn't
match webpack output files. Changed to `.next/server/**/*.js` and
removed the prerendered HTML assertion since the page is dynamic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants