Skip to content

Varlock Setup ​

Varlock is a tool for AI-safe .env files that provides:

  • Schemas - Declarative configuration that serves as single source of truth
  • Validation - Catch misconfiguration errors early with clear messages
  • Type-safety - Auto-generated TypeScript types from your schema
  • Secret management - Securely fetch secrets from password managers via exec() commands
  • Runtime protection - Redact sensitive values from logs, detect leaks

Quick Start ​

Nuxt / Frontend ​

bash
# Validate environment variables
bun env:check

Python / Backend ​

bash
# Install varlock (one-time setup)
curl -sSfL https://varlock.dev/install.sh | sh

# Validate environment (includes varlock scan)
make check

# Start dev server with env validation
make dev

Secrets ​

We use the varlock Proton Pass Plguin to inject secrets from Proton Pass.

Nuxt / Frontend ​

Validation ​

Run bun env:check to validate environment variables. This command:

  1. Logs into pass-cli
  2. Runs varlock load to validate against schema

Vite Plugin ​

The project uses @varlock/vite-integration for seamless integration:

typescript
// nuxt.config.ts
import { varlockVitePlugin } from '@varlock/vite-integration';

export default defineNuxtConfig({
  vite: {
    plugins: [varlockVitePlugin({ ssrInjectMode: "resolved-env" })],
  }
});

Build vs Runtime ​

For production Docker builds, we separate buildtime and runtime variables using different schemas:

SchemaPurpose
.env.schemaMain schema, imports buildtime/runtime conditionally
.env.buildtime.schemaVariables needed at build time
.env.runtime.schemaVariables needed at runtime

Control validation with APP_MODE:

APP_MODEValidates
devAll variables (buildtime + runtime)
ciAll variable (buildtome + runtime)
buildBuildtime variables only
prodRuntime variables only

INFO

The ci mode will disable automaticaly set some variables, for example it can enable the DUMMY Mode, so testing works on CI.

Example from .env.schema:

bash
APP_MODE=dev

# Calculate which schema to validate
IS_RUNTIME=not(eq($APP_MODE, build))
IS_BUILDTIME=not(eq($APP_MODE, prod))

Docker Integration ​

The Dockerfile uses varlock as entrypoint for runtime validation. The varlock binary is not copied from a separate image anymore — it is assembled into /runtime by the shared assemble-runtime script on the mise base image:

dockerfile
# Runtime stage
ENV APP_MODE=prod
ENV PATH="/runtime/varlock:/app/.venv/bin:$PATH"
COPY --from=build --chown=app:app /runtime /runtime
ENTRYPOINT ["/bin/sh", "-c", "varlock load && varlock run -- uvicorn text_mate_backend.app:app --host 0.0.0.0 --port \"${PORT:-8090}\" --no-access-log"]

For Nuxt/node apps the npm varlock package is assembled into /runtime/varlock and run directly with the runtime node:

dockerfile
ENV PATH="/runtime/node/bin:$PATH"
COPY --from=build --chown=node:node /runtime /runtime
ENTRYPOINT ["node", "/runtime/varlock/bin/cli.js", "run", "--", "node", "./server/index.mjs"]

This ensures env vars are validated before the app starts. See the Shared Docker Images page for the full templates.

Type Generation ​

Varlock auto-generates TypeScript types in env.d.ts:

typescript
// Auto-generated - do not edit
type CoercedEnvSchema = {
  API_URL: string;
  LOG_LEVEL: string;
  // ...
};

The generated types can then be access via

typescript
import { ENV } from 'varlock/env';

console.log(import.meta.env.SOMEVAR); // 🆗 still works
console.log(ENV.SOMEVAR);             // ✨ recommended

See also Accessing environment variables


Python / Backend ​

Installation ​

Install the varlock standalone binary (required for Python projects):

bash
# Homebrew
brew install dmno-dev/tap/varlock

# Or via cURL
curl -sSfL https://varlock.dev/install.sh | sh

See Varlock standalone installation for more options.

Makefile Integration ​

Varlock is integrated via Makefile:

makefile
# Run validation and leak scanning
check:
    @varlock scan

# Start dev server with env injection
dev:
    @varlock run -- uv run fastapi dev ./src/app.py --port 8000
  • make check - Runs varlock scan to validate and detect secret leaks
  • make dev - Wraps the server with varlock run for env injection

Schema Example ​

bash
# .env.schema
# @env-spec
# @defaultRequired=infer
# @defaultSensitive=false

# @type=enum(development, staging, production)
ENVIRONMENT=development

# @type=url @required
API_URL=

# @sensitive @type=string
AZURE_CLIENT_SECRET=exec(`./scripts/get-secret.sh pass://Vault/Secret`)

Further Reading ​

Developed with ❤️ by the DCC. Documentation released under the MIT License.