Claude Code में Environment Variables: .env, Zod, Secrets और Production Deploy
Claude Code में env vars और Secrets सुरक्षित रखें: .env.example, Zod validation, CI/CD injection, redaction और rotation.
जब कोई beginner Claude Code से login, payment, webhook या AI integration बनवाता है, तो production में पहली बड़ी समस्या अक्सर UI में नहीं आती। समस्या configuration में आती है: database URL missing है, staging key production में चली गई, WEBHOOK_SECRET CI log में print हो गया, या असली API key GitHub में commit हो गई।
यह guide Claude Code के साथ environment variables और Secrets management का implementation-ready pattern देती है। Environment variable वह value है जो app को runtime पर मिलती है, जैसे PORT या APP_ORIGIN। Secret वह value है जो leak होने पर misuse हो सकती है, जैसे ANTHROPIC_API_KEY, DATABASE_URL, या WEBHOOK_SECRET। Secret भी environment variable के रूप में आ सकता है, लेकिन उसका treatment normal setting जैसा नहीं होना चाहिए।
Claude Code की अपनी configuration के लिए official Claude Code environment variables देखें। App-side validation के लिए हम Zod इस्तेमाल करेंगे। CI/CD और deploy के लिए official docs देखें: GitHub Actions secrets, Vercel environment variables, Cloudflare Workers variables and secrets, और Docker secrets। Platform बदल सकता है, principle नहीं: code में key names और validation rules रखें, secret values नहीं।
पूरा security context समझने के लिए Claude Code security best practices और Claude Code JWT authentication भी पढ़ें।
.env को contract की तरह देखें
.env useful है, लेकिन इसे हर developer की private notebook नहीं बनने देना चाहिए। Team को तीन layers चाहिए:
- Declaration:
.env.exampleमें required keys की list - Validation: Zod से startup पर missing या invalid value पकड़ना
- Operations: CI/CD और production में local
.envcopy नहीं, platform Secrets से injection
flowchart LR
Dev["local .env.local"] --> Schema["Zod schema"]
CI["GitHub Actions secrets"] --> Schema
Prod["Vercel / Cloudflare / Docker secrets"] --> Schema
Schema --> App["Type-safe app config"]
Schema --> Logs["Redacted logs"]
Example[".env.example"] --> Dev
मुख्य बात यह है कि हर entry point उसी schema से गुजरे। Claude Code को actual production secret नहीं देना है; उसे key names, validation rules और failure behavior देना है।
Practical use cases
| Use case | Typical values | Failure mode |
|---|---|---|
| Local development | APP_ORIGIN, DATABASE_URL, ANTHROPIC_API_KEY | App सिर्फ एक developer की machine पर चलती है |
| Webhook verification | STRIPE_WEBHOOK_SECRET, WEBHOOK_SECRET | Forged request accept हो सकती है |
| CI testing | CI_DATABASE_URL, TEST_API_KEY | PR pass, deploy fail |
| Production deploy | DATABASE_URL, SESSION_SECRET, APP_ORIGIN | गलत DB, cookie issue, credential leak |
| Secret rotation | ANTHROPIC_API_KEY_NEXT | Compromised old key बहुत देर तक valid रहती है |
Masa के ClaudeCodeLab workflow में सबसे उपयोगी change सिर्फ .env.example बनाना नहीं था। असली लाभ तब आया जब app incomplete config पर startup ही fail करने लगी। इससे deployment surprises pull request में reviewable failures बन गए।
1. Files को पहले separate करें
.env.example documentation है, real values नहीं। .env.local local machine के लिए है। .env.production.example production checklist है, इसमें भी real secrets नहीं होने चाहिए।
mkdir -p src/config
touch .env.example .env.local .env.production.example src/config/env.ts
# .gitignore
.env
.env.*
!.env.example
!.env.production.example
# Cloudflare local secrets
.dev.vars
.dev.vars.*
# .env.example
APP_ENV=local
NODE_ENV=development
PORT=3000
APP_ORIGIN=http://localhost:3000
DATABASE_URL=postgresql://app:app@localhost:5432/app
ANTHROPIC_API_KEY=replace-with-local-dev-key
WEBHOOK_SECRET=replace-with-32-plus-character-secret
PUBLIC_ANALYTICS_KEY=
LOG_LEVEL=info
# .env.production.example
APP_ENV=production
NODE_ENV=production
PORT=3000
APP_ORIGIN=https://example.com
DATABASE_URL=<set-in-platform-secret-store>
ANTHROPIC_API_KEY=<set-in-platform-secret-store>
WEBHOOK_SECRET=<set-in-platform-secret-store>
PUBLIC_ANALYTICS_KEY=<optional-public-key>
LOG_LEVEL=info
Placeholder safe defaults नहीं हैं। वे सिर्फ बताते हैं कि यह value कहीं और set करनी होगी।
2. Startup पर Zod validation लगाएं
Node.js में environment variables strings के रूप में आती हैं। PORT=3000 भी string है, इसलिए z.coerce.number() conversion और validation करता है।
npm install zod dotenv
npm install -D tsx typescript @types/node
// src/config/env.ts
import "dotenv/config";
import { z } from "zod";
const secretNamePattern = /(SECRET|TOKEN|PASSWORD|API_KEY|DATABASE_URL|DSN)/i;
function redactValue(key: string, value: unknown): string {
if (value === undefined || value === null || value === "") return "<empty>";
const text = String(value);
if (!secretNamePattern.test(key)) return text;
if (text.length <= 8) return "<redacted>";
return `${text.slice(0, 4)}...${text.slice(-4)}`;
}
const envSchema = z.object({
APP_ENV: z.enum(["local", "development", "staging", "production"]).default("local"),
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
PORT: z.coerce.number().int().min(1).max(65535).default(3000),
APP_ORIGIN: z.string().url(),
DATABASE_URL: z.string().url(),
ANTHROPIC_API_KEY: z.string().min(20, "ANTHROPIC_API_KEY is too short"),
WEBHOOK_SECRET: z.string().min(32, "WEBHOOK_SECRET must be at least 32 characters"),
PUBLIC_ANALYTICS_KEY: z.string().optional(),
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
});
const parsed = envSchema.safeParse(process.env);
if (!parsed.success) {
console.error("Environment validation failed:");
for (const issue of parsed.error.issues) {
const key = String(issue.path[0] ?? "unknown");
console.error(`- ${key}: ${issue.message}; current=${redactValue(key, process.env[key])}`);
}
process.exit(1);
}
export const env = Object.freeze(parsed.data);
export type AppEnv = typeof env;
export function isProduction(): boolean {
return env.APP_ENV === "production";
}
export function publicEnv() {
return {
APP_ENV: env.APP_ENV,
APP_ORIGIN: env.APP_ORIGIN,
PUBLIC_ANALYTICS_KEY: env.PUBLIC_ANALYTICS_KEY ?? "",
};
}
Local check:
cp .env.example .env.local
npx tsx src/config/env.ts
इसके बाद Claude Code से scattered process.env reads ढूंढवाएं:
इस repository में direct process.env reads ढूंढें।
सिर्फ src/config/env.ts को process.env directly read करना चाहिए।
बाकी files में env को src/config/env.ts से import करने का change propose करें।
Secrets को logs, errors या test snapshots में print न करें।
3. Logs में secrets redact करें
Secret leaks सिर्फ Git commits से नहीं होते। CI logs, debug output, error monitoring, screen recording और Claude Code prompts में pasted terminal output भी leak path बन सकते हैं।
// src/config/redact.ts
const sensitiveKeyPattern = /(SECRET|TOKEN|PASSWORD|API_KEY|DATABASE_URL|AUTH|COOKIE|PRIVATE)/i;
export function redactSecrets(input: Record<string, unknown>): Record<string, string> {
return Object.fromEntries(
Object.entries(input).map(([key, value]) => {
if (value === undefined || value === null || value === "") return [key, "<empty>"];
const text = String(value);
if (!sensitiveKeyPattern.test(key)) return [key, text];
return [key, text.length <= 10 ? "<redacted>" : `${text.slice(0, 4)}...${text.slice(-4)}`];
}),
);
}
import { env } from "./env";
import { redactSecrets } from "./redact";
console.info("Loaded config", redactSecrets(env));
Redaction अंतिम safety net है। बेहतर design यह है कि secret value log तक पहुंचे ही नहीं।
4. CI/CD में Secrets से values inject करें
GitHub Actions repository, environment या organization secrets workflow में दे सकता है। Normal PR tests के लिए production credentials reuse न करें। CI के लिए limited scope values बनाएं।
# .github/workflows/env-check.yml
name: env-check
on:
pull_request:
push:
branches: [main]
jobs:
validate-env:
runs-on: ubuntu-latest
env:
APP_ENV: development
NODE_ENV: test
PORT: 3000
APP_ORIGIN: http://localhost:3000
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
WEBHOOK_SECRET: ${{ secrets.WEBHOOK_SECRET }}
LOG_LEVEL: info
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- run: npm ci
- name: Mask runtime-only values
run: echo "::add-mask::$APP_ORIGIN"
- run: npx tsx src/config/env.ts
- run: npm test -- --runInBand
हर workflow को secrets मिलेंगे, यह assume न करें। Fork PR, reusable workflow और automated events अलग behave कर सकते हैं। Validation job explicit रखें और secrets generated files में न लिखें।
5. Docker, Vercel, Cloudflare notes
Docker में Dockerfile के अंदर ENV API_KEY=... मत लिखें। Local testing में env file ठीक है, लेकिन production में runtime secret store या orchestrator बेहतर है।
# local only
docker run --rm --env-file .env.local my-app:latest
अगर runtime secrets को files के रूप में mount करता है, तो NAME_FILE convention support करें:
// src/config/secret-file.ts
import fs from "node:fs";
export function readEnvOrFile(name: string): string | undefined {
const direct = process.env[name];
if (direct) return direct;
const filePath = process.env[`${name}_FILE`];
if (!filePath) return undefined;
return fs.readFileSync(filePath, "utf8").trim();
}
Vercel में Production, Preview और Development values अलग रखें। NEXT_PUBLIC_ जैसे browser-exposed prefixes पर खास ध्यान दें। Cloudflare Workers में values bindings, env parameter या platform Secrets से आ सकती हैं। किसी एक platform पर overclaim न करें; schema को source of truth बनाएं और platform-specific injection notes लिखें।
Vercel, Cloudflare और Docker environment setup review करें।
Real production values न पढ़ें और न मांगें।
Required key names, public vs secret boundary, build-time vs runtime usage, और rotation notes check करें।
6. Rotation playbook पहले लिखें
Secret rotation incident के समय improvisation नहीं होना चाहिए:
- Scope identify करें: service, environment, permissions, owner
- Minimum permission वाला नया value बनाएं
- Dual-running possible हो तो
*_NEXTके रूप में add करें - Short window में old और new दोनों accept करें
- Deploy करके health checks verify करें
- Old value revoke करें
- Git history, CI logs, monitoring logs और prompts में exposure search करें
.env.exampleऔर operations notes update करें
Webhook secret, API key और database password की rotation mechanics अलग होती हैं। हर type के लिए owner, window और rollback लिखें।
Common failures
| Failure | Cause | Fix |
|---|---|---|
.env commit हो गया | .gitignore late add हुआ | Keys तुरंत revoke करें; history cleanup काफी नहीं |
Secret NEXT_PUBLIC_ में गया | Public prefix समझ नहीं आया | Public/private naming rule अलग करें |
console.log(process.env) | Hurry में debugging | Redaction और log review |
| Production boot fail | Required key missing | CI में src/config/env.ts run करें |
| Local value production build में गया | Build-time/runtime confusion | Platform injection document करें |
| Real key Claude Code में paste हुई | Prompting और secret sharing mix हुआ | सिर्फ key names और rules share करें |
Copy-paste Claude Code prompt
इस project के लिए environment variable management implement करें।
Requirements:
- .env.example और .env.production.example बनाएं
- .env, .env.*, और .dev.vars* को Git से बाहर रखें
- src/config/env.ts में Zod schema add करें और missing/invalid values पर startup fail करें
- Direct process.env reads को src/config/env.ts में centralize करें
- Diagnostic logs में secrets redact करें
- Pull requests में env validation चलाने वाला GitHub Actions job add करें
- Vercel, Cloudflare और Docker के लिए short deployment notes लिखें
Real API keys या production database URLs न पढ़ें। सिर्फ key names और validation rules से काम करें।
निष्कर्ष
Claude Code से environment management करवाने का मतलब secrets chat में paste करना नहीं है। सही तरीका है contract implement कराना: .env.example keys declare करे, Zod startup पर validate करे, logs redact हों, CI/CD और platform real values inject करें, और team के पास rotation playbook हो।
ClaudeCodeLab Claude Code consulting, team training, repository security review, और authentication, payments, CI/CD, content operations templates देता है। अगर आपकी team Claude Code से fast delivery चाहती है लेकिन production keys leak नहीं करना चाहती, तो environment variable management सबसे पहले standardize करने लायक area है।
Masa के test repository में इस pattern ने deploy से पहले तीन issues पकड़े: missing production key, logs में जा सकने वाला Webhook secret, और पुराना .env.example। Zod startup validation simple है, लेकिन यह configuration को personal knowledge से enforceable team contract में बदल देता है।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code permission safety ladder: access धीरे-धीरे बढ़ाएं
read-only से limited edits, proof commands और deploy checks तक permission बढ़ाने की सुरक्षित ladder.
Claude Code Small PR Proof Pack: छोटे PR को review-ready बनाना
Claude Code PR के लिए diff, checks, public URL, CTA path और rollback वाला practical proof pack.
Claude Code Review Gate Before Commit: diff, test, public URL और CTA जांच
Claude Code से commit से पहले review gate बनाएं: diff, build, public URL, Gumroad, consultation, tests और unrelated files।