Encrypted deployments
When deploying SSR applications to serverless platforms (like Vercel, Netlify, or Cloudflare Workers), varlock injects the fully resolved env data into your server-side build output so it’s available at runtime without needing the CLI or filesystem access. This is necessary because serverless environments don’t give you control over how the application boots.
By default, this blob is plaintext JSON. Since it only appears in server-side code, it’s generally safe — your secrets are not exposed to the client. However, encrypting the blob provides an extra layer of protection, particularly against secrets leaking via sourcemaps that may be uploaded to error tracking services.
Enabling encryption
Section titled “Enabling encryption”Add the @encryptInjectedEnv root decorator to your .env.schema:
# @encryptInjectedEnv# ---SECRET_KEY= # @sensitiveYou can also enable it conditionally for specific environments:
# @encryptInjectedEnv=forEnv(prod)# ---SECRET_KEY= # @sensitiveHow it works
Section titled “How it works”- At build time, varlock encrypts the serialized env graph with AES-256-GCM before injecting it
- The encrypted blob is prefixed with
varlock:v1:— you can verify encryption by inspecting your build output - At runtime,
initVarlockEnv()detects the encrypted prefix and decrypts using_VARLOCK_ENV_KEYfrom the runtime environment - The key is never baked into the build — it must always come from the runtime environment
Key management
Section titled “Key management”The encryption key (_VARLOCK_ENV_KEY) is managed differently depending on your platform:
Local development
Section titled “Local development”No setup needed — varlock auto-generates a temporary key when running dev servers. The key exists only in memory for the duration of the dev session.
Cloudflare Workers
Section titled “Cloudflare Workers”No setup needed — varlock-wrangler deploy auto-generates a key and uploads it alongside your encrypted env as a Cloudflare secret binding. The key persists across deploys.
Vercel, Netlify, and other platforms
Section titled “Vercel, Netlify, and other platforms”You must set _VARLOCK_ENV_KEY as an environment variable on your platform. The key must be available at both build time (for encryption) and runtime (for decryption).
-
Generate and set the key
Terminal window # set one key for previewvarlock generate-key --plain | vercel env add _VARLOCK_ENV_KEY preview --sensitive# set one key for productionvarlock generate-key --plain | vercel env add _VARLOCK_ENV_KEY production --sensitiveYou can use the same key for both
previewandproduction, but using separate keys is usually safer because it isolates environments and reduces blast radius if one key is exposed.Terminal window netlify env:set _VARLOCK_ENV_KEY $(varlock generate-key --plain) --secretGenerate a key and set it as a secret/env var on your platform:
Terminal window npm exec -- varlock generate-keyTerminal window pnpm exec -- varlock generate-keyTerminal window bunx varlock generate-keyTerminal window vlx -- varlock generate-keyTerminal window yarn exec -- varlock generate-key -
Deploy your app
The build will fail with a clear error if
@encryptInjectedEnvis enabled but_VARLOCK_ENV_KEYis not set.
Supported integrations
Section titled “Supported integrations”| Integration | How it works |
|---|---|
| Next.js | Encrypts the env blob injected into the webpack/turbopack build output |
| Vite | Encrypts the env blob when using ssrInjectMode: 'resolved-env' |
| Astro | Uses the Vite integration — encryption applies to SSR adapter builds |
| SvelteKit | Uses the Vite integration — encryption applies to SSR builds |
| TanStack Start | Uses the Vite integration — encryption applies to SSR builds |
| Cloudflare Workers | Encrypts the __VARLOCK_ENV secret binding uploaded at deploy time |
| Expo | Encrypts the env blob used by the Metro bundler for server routes |
Verifying encryption
Section titled “Verifying encryption”After building with encryption enabled, you can inspect your build output to confirm the blob is encrypted:
# Look for the encrypted prefix in build outputgrep -r 'varlock:v1:' dist/ .next/server/ 2>/dev/nullIf encryption is working, you’ll see varlock:v1: followed by a base64-encoded ciphertext instead of raw JSON.
Alternative: manual key without the decorator
Section titled “Alternative: manual key without the decorator”You can also enable encryption without the @encryptInjectedEnv decorator by simply setting _VARLOCK_ENV_KEY in your environment. When present, varlock will encrypt the blob — but it won’t enforce the key’s presence or auto-generate it.