OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 56 / 90
stack-analysis
CHAPTER 56 / 90
읽기 약 2
FUNCTION

환경 변수와 시크릿 관리


핵심 개념

.env 분리·dotenv·Doppler·AWS Secrets Manager — 시크릿 안전.

본문

.env 파일 계층

📋 코드 (5줄)
.env                 # 모든 환경 공통 (git ignore)
.env.local           # 로컬 우선 (git ignore)
.env.development     # 개발 (git에 들어갈 수도)
.env.production      # 프로덕션 (절대 commit X)
.env.example         # 템플릿 (git에 commit ✅)
BASH📋 코드 (12줄)
# .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.production

Zod로 환경 변수 검증

TYPESCRIPT📋 코드 (34줄)
// 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 — 시크릿 동기화

BASH📋 코드 (14줄)
# 셋업
brew install dopplerhq/cli/doppler
doppler login
doppler setup

# 로컬 실행 — 자동 환경변수 주입
doppler run -- pnpm dev

# 다른 사람이 변경한 시크릿 자동 반영
# .env 파일 공유 불필요


# CI/CD
doppler run -- pnpm test

AWS Secrets Manager

TYPESCRIPT📋 코드 (22줄)
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 환경 변수

📋 코드 (12줄)
Vercel Dashboard → Project → Settings → Environment Variables

분류:
- Production
- Preview (PR 미리보기)
- Development (vercel dev)


암호화:
- Vercel은 자동 암호화 저장
- 빌드 시 주입
- Edge Function에서 사용 가능

시크릿 회전 (Rotation)

📋 코드 (11줄)
주기적 회전 권장:
- DB password: 90일
- API keys: 90일~1년
- JWT secret: 1년 (또는 노출 시 즉시)


[회전 절차 - JWT secret]
1. 새 secret 발급 + 환경 변수 업데이트
2. 배포 — 새 토큰은 새 secret으로 서명
3. 그레이스 기간 — 양쪽 secret으로 검증
4. 옛 secret 제거 (모든 토큰 만료 후)

노출 감지

BASH📋 코드 (18줄)
# 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 알림

노출 시 대응

📋 코드 (14줄)
[즉시 - 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