stack-analysis
CHAPTER 56 / 90
읽기 약 2분
FUNCTION
환경 변수와 시크릿 관리
핵심 개념
.env 분리·dotenv·Doppler·AWS Secrets Manager — 시크릿 안전.
본문
.env 파일 계층
.env # 모든 환경 공통 (git ignore)
.env.local # 로컬 우선 (git ignore)
.env.development # 개발 (git에 들어갈 수도)
.env.production # 프로덕션 (절대 commit X)
.env.example # 템플릿 (git에 commit ✅)# .env.example (commit OK)
DATABASE_URL=postgresql://localhost/myapp
REDIS_URL=redis://localhost:6379
JWT_SECRET=replace-with-strong-secret
STRIPE_SECRET_KEY=sk_test_...
# .gitignore
.env
.env.local
.env.*.local
.env.productionZod로 환경 변수 검증
// env.ts
import { z } from 'zod';
import 'dotenv/config';
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'test']),
PORT: z.coerce.number().int().default(3000),
DATABASE_URL: z.string().url(),
REDIS_URL: z.string().url(),
JWT_ACCESS_SECRET: z.string().min(32),
JWT_REFRESH_SECRET: z.string().min(32),
STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
STRIPE_WEBHOOK_SECRET: z.string().startsWith('whsec_'),
AWS_REGION: z.string().default('ap-northeast-2'),
S3_BUCKET: z.string(),
});
const parsed = envSchema.safeParse(process.env);
if (!parsed.success) {
console.error('❌ Invalid env vars:', parsed.error.flatten().fieldErrors);
process.exit(1);
}
export const env = parsed.data;
// 사용 — 타입 안전
import { env } from '@/env';
const db = new Prisma({ datasources: { db: { url: env.DATABASE_URL } } });Doppler — 시크릿 동기화
# 셋업
brew install dopplerhq/cli/doppler
doppler login
doppler setup
# 로컬 실행 — 자동 환경변수 주입
doppler run -- pnpm dev
# 다른 사람이 변경한 시크릿 자동 반영
# .env 파일 공유 불필요
# CI/CD
doppler run -- pnpm testAWS Secrets Manager
import {
SecretsManagerClient,
GetSecretValueCommand,
} from '@aws-sdk/client-secrets-manager';
const client = new SecretsManagerClient({ region: 'ap-northeast-2' });
async function getSecret(name: string) {
const cmd = new GetSecretValueCommand({ SecretId: name });
const res = await client.send(cmd);
return JSON.parse(res.SecretString!);
}
// 사용
const dbCreds = await getSecret('prod/db');
// { username: '...', password: '...', host: '...' }
// 자동 회전 (rotation)
// AWS 콘솔에서 30일마다 자동 회전 설정
// → 코드는 항상 최신 시크릿 사용Vercel 환경 변수
Vercel Dashboard → Project → Settings → Environment Variables
분류:
- Production
- Preview (PR 미리보기)
- Development (vercel dev)
암호화:
- Vercel은 자동 암호화 저장
- 빌드 시 주입
- Edge Function에서 사용 가능시크릿 회전 (Rotation)
주기적 회전 권장:
- DB password: 90일
- API keys: 90일~1년
- JWT secret: 1년 (또는 노출 시 즉시)
[회전 절차 - JWT secret]
1. 새 secret 발급 + 환경 변수 업데이트
2. 배포 — 새 토큰은 새 secret으로 서명
3. 그레이스 기간 — 양쪽 secret으로 검증
4. 옛 secret 제거 (모든 토큰 만료 후)노출 감지
# git-secrets — commit 전 검사
git secrets --register-aws
git secrets --add 'sk_live_[A-Za-z0-9]+'
git secrets --add 'whsec_[A-Za-z0-9]+'
# pre-commit hook
.husky/pre-commit:
git secrets --scan
# truffleHog — 히스토리 검사
trufflehog git file://. --since-commit HEAD~10
# GitHub Secret Scanning
- 무료 (모든 public repo)
- AWS·Stripe·Slack 등 자동 감지
- 노출 시 즉시 revoke 알림노출 시 대응
[즉시 - 1시간 내]
1. 해당 시크릿 즉시 revoke
2. 새 시크릿 발급
3. 모든 환경에 배포
[24시간 내]
4. 로그 확인 — 의심 활동 추적
5. 사용자 알림 (필요 시)
6. 보안팀 보고
[1주 내]
7. 사후 분석 — 노출 경로 파악
8. CI 시크릿 스캔 자동화
9. 회전 정책 강화다음 챕터
CH.57 "도메인 + SSL + CDN 설정".
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 코드의 시크릿 관리 부분을 분석해서 실전 분석 + 개선 우선순위를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
시크릿 관리 관련 인기 라이브러리/패턴 5개를 비교 분석해서 패턴 추출를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 프로젝트 전체에서 시크릿 관리 최적화 가능 위치를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 백엔드 시장의 시크릿 관리 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
환경 변수와 시크릿 관리는 이 3가지만 확실히 잡으세요
1..env.example만 commit + .env는 절대 commit X — git-secrets 자동화
2.Zod로 환경 변수 검증 — 잘못된 값 시 부팅 실패 (fail fast)
3.Doppler/Secrets Manager로 팀 동기화 + 자동 회전
공유하기
진행도 56 / 90