AWS access key, DB password, OAuth client secret, third-party API token — production 의 모든 service 가 secret 들의 소비자. 그런데 어디에 두나? .env? git? 환경변수? Vault? rotation 은 어떻게? 이 가이드는 secret leak 의 1순위 원인부터 modern dynamic credential 까지 정리한다.
Secret Leak 의 1순위 — git commit
흔한 사례:
1. .env 파일에 AWS key 박음
2. .gitignore 에 .env 추가 잊음
3. git add . → commit → push
4. GitHub 자동 스캐너 (Amazon, Google) 가 5 분 안에 발견
5. Amazon: "당신 key leak 됨, 즉시 revoke" 메일
6. 그 사이 attacker 도 봤음 → bitcoin miner 가 가동, $10K 청구서
위험성:
- git history 는 영원 — squash 머지 후에도 reflog 남음
- public repo 면 GitHub crawl bot 들이 매시간 스캔
- private repo 라도 employee 누가 leak 가능
방어:
1. .gitignore 에 .env / *.pem / *.key 미리
2. pre-commit hook (gitleaks, talisman) 으로 자동 스캔
3. PR review 의 필수 항목
4. 이미 leak 됐다면: 즉시 revoke + rotate, repo 정리만으로 안 됨레벨 1 — 환경변수 (.env)
.env (git 에 X)
DATABASE_URL=postgres://...
AWS_ACCESS_KEY_ID=AKIA...
application:
process.env.DATABASE_URL
장점: 단순, 모든 언어 지원, 개발 친화
단점:
- 모든 process 가 모든 secret 봄 (least privilege X)
- log 에 dump 시 leak (process.env 통째로 print)
- container env 가 docker inspect 로 노출
- rotation 시 restart 필요레벨 2 — Cloud Secrets Manager
AWS Secrets Manager / GCP Secret Manager / Azure Key Vault.
application:
const secret = await secretsClient.getSecretValue({SecretId: "db-password"});
장점:
- 중앙 관리 + IAM 기반 권한 (어떤 role 만 어떤 secret 접근)
- rotation 자동 (어떤 secret 은 cloud 가 직접 갱신)
- audit log (누가 언제 어떤 secret read 했나)
- versioning (이전 secret 으로 fallback)
- KMS encryption at rest
단점:
- 비용 ($0.4/secret/month + API call)
- cloud lock-in
- application 마다 SDK + IAM 설정레벨 3 — HashiCorp Vault
open-source, self-host. multi-cloud / on-prem.
기능:
- secret storage (cloud Secrets Manager 와 같은)
- dynamic credentials: DB user / IAM credential 을 요청 시 생성, 단기 만료
- transit encryption (encryption as a service)
- PKI (자체 CA, 인증서 발급)
- 다양한 backend (KMS, AWS, GCP, Azure 연동)
dynamic DB credential 예:
app → Vault 요청
Vault → DB 에서 임시 user 생성 (read 권한, TTL 1h)
→ app 에 username/password 반환
app → 1h 동안 그 credential 사용
TTL 만료 → Vault 가 DB 에서 user 삭제
→ 영구 credential X. leak 돼도 1h 후 만료.Envelope Encryption — secret 의 secret
secret 을 어디 저장하든 — 그 storage 자체가 leak 되면?
→ 저장된 secret 들도 모두 leak.
해결: envelope encryption.
1. 각 secret 은 random data key (DEK) 로 encrypt
2. DEK 는 master key (KEK, KMS 가 보관) 로 encrypt
3. encrypted secret + encrypted DEK 같이 저장
decrypt 시:
1. KMS 에 encrypted DEK 보냄 → plain DEK 받음
2. plain DEK 로 secret decrypt
3. plain DEK 즉시 메모리에서 삭제
이점:
- storage leak → encrypted secret 만 노출 (decrypt 불가)
- KMS leak → 모든 encrypted DEK 풀 수 있음 (worst case)
- 둘 다 leak 해야 진짜 위험
→ KMS 의 master key 가 hardware HSM 안에 있어 leak 거의 불가능.Rotation — downtime 없이
기존:
password 변경 → application 재배포 → downtime
방법 1 — Dual secret 기간:
step 1: 새 password 생성 → app 이 둘 다 (old + new) 시도
step 2: 모든 client 가 new 로 전환
step 3: old 폐기
방법 2 — Dynamic credential (Vault):
application 이 늘 fresh credential 요청
→ rotation 이 backend 만의 일, application 영향 0
방법 3 — Rolling restart:
cloud Secrets Manager 의 새 version 활성
→ application 들이 차례로 restart 하며 새 secret pick
→ 어떤 방법이든 application 의 "secret 변할 수 있다" 가정 필수.Secret Scanning — 사후 발견
| 도구 | 모드 | 비고 |
|---|---|---|
| gitleaks | pre-commit + CI | OSS, 빠름, 패턴 기반 |
| truffleHog | pre-commit + CI + repo scan | entropy 기반 (random-looking string) |
| GitHub Secret Scanning | GitHub 자동 | partnered vendors 의 token 자동 detect → 즉시 revoke 요청 |
| GitGuardian | SaaS | 모든 git 활동 모니터링 + 알람 |
흔한 함정
- secret 을 docker image 에 박음 — docker history / layer 로 추출 가능. multi-stage build + runtime mount.
- process.env 통째로 log — error 시 모든 env 박힘. redaction middleware 필수.
- cloud-init / startup script 에 secret — EC2 metadata 에서 사후 노출. cloud Secrets Manager 호출이 정석.
- granular permission 없음 — 한 IAM role 이 모든 secret read. per-service role + secret-specific resource ARN.
- rotation 안 함 — leak 가정. 90 일 / 180 일 주기 강제.
마무리
Secrets management 의 진화 — env file → cloud Secrets Manager → Vault 의 dynamic credential. 단계 올라갈수록 leak 영향 ↓ + operational cost ↑.
실용 시작 — git pre-commit hook (gitleaks) + .gitignore strict + cloud Secrets Manager (AWS/GCP/Azure 중 native) + 90 일 rotation 주기. Vault 는 multi-cloud 또는 on-prem 필요 시.