# REP — Runtime Environment Protocol | Secure Runtime Env Vars for Frontend Apps > Inject environment variables into browser apps at container runtime — not build time. AES-256 encryption, secret detection, hot reload. Build once, deploy anywhere. Source: https://rep-protocol.dev/

Same frontend image, different environment, dynamic variables — no rebuild, no redeploy.

## The Problem Every frontend framework resolves environment variables at **build time** — `process.env.API_URL` becomes a hardcoded string in your JavaScript bundle. This creates problems that compound in production: **One build per environment** Your staging bundle can't be promoted to production. You rebuild for every environment, breaking the container promise of "build once, run anywhere." **No security model** All variables are treated equally. API keys, analytics tokens, and public URLs all end up as plaintext strings in your bundle — visible to anyone who opens View Source. **Config changes require redeployment** Need to rotate an API key or flip a feature flag? Rebuild, re-test, redeploy. Even if your backend can hot-swap config, your frontend can't. **Secrets leak into build logs** CI/CD pipelines pass secrets as build args. They appear in Docker layer history, build logs, and cached artifacts — creating supply chain risk. ## What REP Does REP is an open protocol and reference implementation that **decouples environment variables from the build process entirely**. A lightweight gateway reads variables at startup, classifies them by security tier, encrypts sensitive values, and injects them into HTML responses — whether you're running containers, static builds, or local development. **Three Security Tiers** **PUBLIC** — plaintext, synchronous access. **SENSITIVE** — AES-256-GCM encrypted, decrypted on demand. **SERVER** — never sent to the browser. Classification by naming convention eliminates ambiguity. **Encryption + Integrity** Sensitive variables are encrypted with ephemeral keys generated at startup. Every payload carries an HMAC-SHA256 integrity token and SRI hash to detect tampering in transit. **Secret Detection Guardrails** Entropy analysis and known-format matching (AWS keys, JWTs, Stripe keys, GitHub tokens) catch misclassified secrets before they reach the browser. Strict mode makes warnings into hard failures. **Hot Reload via SSE** Config changes push to every connected browser via Server-Sent Events. No page reload, no redeployment. Edit an env file or rotate a ConfigMap — the UI updates live. ## Works Everywhere REP operates at the **infrastructure layer** in production — no build-tool plugin required, no framework coupling. It works with any frontend stack that produces HTML. Optional dev-time plugins exist purely for local DX (see below). **Containers** Reverse proxy mode sits in front of nginx, caddy, or any upstream. Embedded mode serves static files directly from a `FROM scratch` image. **Static Builds** Build your app once with `npm run build`. The gateway injects config into the static HTML at serve time — same artifact for every environment. **Local Development** Install the [Vite](/reference/plugins/vite/) or [Next.js](/reference/plugins/next/) plugin for zero-config `dev` support, or the CLI wraps the gateway to proxy any dev server with hot reload. **Any Framework** First-party adapters for React, Vue, and Svelte. A zero-dependency TypeScript SDK works with anything — Angular, vanilla JS, or your custom setup. ## Compared to Existing Solutions | Approach | Security Tiers | Encrypted Vars | Integrity Check | Hot Reload | Standalone Binary | |---|:---:|:---:|:---:|:---:|:---:| | `envsubst` / `sed` on bundles | -- | -- | -- | -- | -- | | Fetch `/config.json` at runtime | -- | -- | -- | -- | -- | | `window.__ENV__` via shell script | -- | -- | -- | -- | -- | | Build-tool plugins (dotenv, etc.) | -- | -- | -- | -- | -- | | **REP** | **3-tier** | **AES-256-GCM** | **HMAC + SRI** | **SSE** | **~7MB Go** | ## Quick Example **SDK Usage** ```typescript import { rep } from '@rep-protocol/sdk'; // Synchronous — no loading state needed const apiUrl = rep.get('API_URL'); const flags = rep.get('FEATURE_FLAGS'); // Encrypted — decrypted on demand via session key const key = await rep.getSecure('ANALYTICS_KEY'); // Hot reload — react to config changes live rep.onChange('FEATURE_FLAGS', (newValue) => { console.log('Flags updated:', newValue); }); ``` **Docker Compose** ```yaml # Same image, different config — true build-once, deploy-anywhere services: frontend-staging: image: myapp:latest environment: REP_PUBLIC_API_URL: "https://api.staging.example.com" REP_SENSITIVE_ANALYTICS_KEY: "UA-XXXXX-staging" REP_SERVER_INTERNAL_SECRET: "never-reaches-browser" frontend-prod: image: myapp:latest # SAME IMAGE environment: REP_PUBLIC_API_URL: "https://api.example.com" REP_SENSITIVE_ANALYTICS_KEY: "UA-XXXXX-prod" REP_SERVER_INTERNAL_SECRET: "also-never-reaches-browser" ``` **Variable Tiers** ```bash # PUBLIC — plaintext in page source, rep.get() REP_PUBLIC_API_URL=https://api.example.com # SENSITIVE — AES-256-GCM encrypted, await rep.getSecure() REP_SENSITIVE_ANALYTICS_KEY=UA-12345-1 # SERVER — never leaves the gateway process REP_SERVER_DB_PASSWORD=never-reaches-browser ``` ## Project Components **Gateway** Go binary (~7MB). Zero dependencies. `FROM scratch` compatible. Proxy or embedded mode. **SDK** TypeScript. Zero runtime deps. ~1.5KB gzipped. Synchronous `get()`, async `getSecure()`. **CLI** `rep validate`, `rep typegen`, `rep lint`, `rep dev`. Full development workflow. **Adapters** First-party React, Vue, and Svelte adapters with hot-reload-aware hooks and stores. **Build-Tool Plugins** Vite (`repPlugin()`) and Next.js (`RepScript`) plugins inject the same payload during `npm run dev` — no gateway needed locally. **Codemod** `npx @rep-protocol/codemod` automates migration from Vite, CRA, or Next.js `process.env`/`import.meta.env` reads to `rep.get()`. ## Specification Status | Document | Status | |---|---| | [REP-RFC-0001](/spec/rfc-0001/) | Active | | [Security Model](/spec/security-model/) | Active | | [Conformance](/spec/conformance/) | Active | Current versions and the versioning policy are on the [specification overview](/spec/). Specification documents are licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Code is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).