Secret Management Plan
Scope:
membloc-app-engine,membloc-developer-portal, deployment infrastructure Last updated: 2026-04-11
1. 목적
이 문서는 Phase 3 이후 운영을 전제로, 어떤 값을 secret으로 취급해야 하는지와 어디에 저장하고, 누가 접근하고, 언제 회전하고, 사고 시 어떻게 대응할지를 정리한다.
핵심 원칙은 아래 3개다.
- public config와 real secret을 구분한다.
- secret은 코드 저장소에 넣지 않는다.
- rotation, audit, incident response를 처음부터 설계한다.
2. 분류 기준
Public Config
브라우저에 노출되어도 되는 값.
예시:
NEXT_PUBLIC_FIREBASE_API_KEYNEXT_PUBLIC_FIREBASE_AUTH_DOMAINNEXT_PUBLIC_FIREBASE_PROJECT_IDNEXT_PUBLIC_FIREBASE_APP_IDNEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_IDNEXT_PUBLIC_FIREBASE_STORAGE_BUCKETNEXT_PUBLIC_HOMB_ENGINE_URL
주의:
- Firebase web config는 공개되어도 되는 값이다.
- 다만 “공개 가능”과 “아무나 바꿔도 됨”은 다르다.
- 따라서 source-of-truth는 Vercel environment와
.env.local로 관리하고, repo에는.env.example만 둔다.
Real Secret
노출되면 인증 위조, 데이터 유출, 인프라 남용, 비용 손실로 이어지는 값.
예시:
DATABASE_URLTOKEN_SECRET- PostgreSQL password
- Firebase service account JSON 또는 private key
- Vercel token
- GitHub Actions deployment secrets
- webhook signing secret
- future module API key secret material
3. 현재 시스템 기준 관리 대상
membloc-app-engine
Required secrets
DATABASE_URL- 운영 DB 연결 정보
TOKEN_SECRET- module token / runtime scoped token 서명 키
Non-secret config
PORTFIREBASE_PROJECT_ID
설명:
- 현재
FIREBASE_PROJECT_ID는 ID token verification을 위한 프로젝트 식별자 역할이라 secret이 아니다. - 하지만 future admin SDK write workflow가 들어오면 service account secret이 별도 필요하다.
membloc-developer-portal
Public config
- 모든
NEXT_PUBLIC_FIREBASE_* NEXT_PUBLIC_HOMB_ENGINE_URL
Future secrets
- server-side upload signing key가 생기면 secret 취급
- portal backend/API route가 생기면 해당 서버 전용 key 분리 필요
설명:
- 현재 포털은 브라우저 직접 Firebase Auth/Storage를 쓰므로 public env 위주다.
- 그래서 portal repo에서 진짜 핵심 secret은 아직 거의 없다.
- 대신 잘못된 public env를 production에 넣는 운영 리스크가 더 크다.
Infrastructure / CI
Real secrets
- GitHub Actions secrets
- Vercel project env (private env)
- domain provider credentials
- cloud database credentials
4. 저장 위치 원칙
Local Development
Backend
- 사용 파일
.env.env.example
- 원칙
.env는 로컬 전용- 실제 운영 secret은 넣지 않는다
- 개발용
TOKEN_SECRET은 dev scope로만 사용
Portal
- 사용 파일
.env.local.env.example
- 원칙
.env.local은 항상 gitignore 유지- public Firebase values만 저장
- production endpoint를 로컬 파일에 하드코딩하지 않는다
CI/CD
- GitHub Actions
- deploy, migration, release용 secret 저장소
- Vercel
- preview / production env 분리
- Database provider
- master credential는 운영 담당자만 접근
Repo Policy
- 금지
- 실제 secret 값 commit
- 예제 파일에 production credential 복붙
- PR description / issue / comment에 secret 직접 기록
- 허용
.env.example- placeholder
- secret 이름, 목적, rotation 정책 문서화
5. 권한 모델
접근 최소화
- engineer 전원에게 production DB master credential을 주지 않는다.
- portal/frontend 작업자는 public Firebase config만 알아도 되게 유지한다.
- runtime token signing key(
TOKEN_SECRET)는 backend 운영 담당자만 변경 가능하게 둔다.
역할 분리
- product/dev
- local dev env 접근
- preview env 접근
- release owner
- production Vercel env 수정
- GitHub Actions deploy secret 수정
- infra owner
- production DB secret
- domain/provider credential
감사 가능성
- secret 수정은 가능한 한
- GitHub Actions secret audit
- Vercel env change history
- password manager record 로 추적 가능해야 한다.
6. Rotation 정책
즉시 rotation 대상
TOKEN_SECRET- 사고 발생 시 가장 먼저 rotation
- DB password
- 외부 공유/노출 의심 시 즉시 변경
- webhook signing secret
- consumer compromise 시 개별 rotation
정기 rotation 권장
- production DB credential
- 90일 또는 분기 단위
- deploy token
- 반기 단위
- service account key
- 생성 최소화, 있으면 분기 단위 검토
Rotation 방식
- old + new 동시 허용이 가능한 secret은 transition window 제공
- 불가능한 secret은 maintenance window에서 교체
- rotation 시 변경 순서 문서화
예:
- new secret 발급
- preview/staging 반영
- production 반영
- health check
- old secret 폐기
7. 서비스별 관리 포인트
TOKEN_SECRET
중요도: 매우 높음
리스크:
- module runtime token 위조
- family/module scope 우회 가능성
관리 포인트:
- dev / staging / prod 분리
- 최소 32 bytes 이상 랜덤 문자열 사용
.env.example에는 placeholder만 두고 실제 값은 secret store로 이동- future task:
- key id(
kid) 기반 다중 서명 키 체계 고려 - graceful rotation 지원
- key id(
DATABASE_URL
중요도: 매우 높음
리스크:
- 데이터베이스 직접 접근
- PII/운영 데이터 노출
관리 포인트:
- 로컬 dev와 production 완전 분리
- production connection string은 CI 또는 secret manager에서만 주입
- app-level read/write role 분리 검토
Firebase Web Config
중요도: 낮음
리스크:
- 직접 침해보다는 잘못된 프로젝트 연결 리스크가 큼
관리 포인트:
- public env로 취급
- project mismatch 방지
- authorized domains 관리가 더 중요
Firebase Storage
중요도: 중간
리스크:
- 규칙 misconfig 시 무단 업로드/다운로드
관리 포인트:
- storage rules로 publisher asset 경로 제한 필요
- 업로드 용량/확장자 제한 필요
- orphan asset cleanup job 필요
Webhook Secrets
중요도: 높음
리스크:
- forged callback validation
- replay / signature bypass
관리 포인트:
- module 별 secret 개별 발급
- plaintext 저장 대신 hash 또는 encrypted-at-rest 고려
- delivery log에는 secret 자체를 남기지 않음
Future Module API Keys
중요도: 높음
리스크:
- third-party module impersonation
관리 포인트:
- hash only 저장
- one-time reveal
- last-used timestamp 기록
- revoke flow 우선 구현
8. 포털/운영 UI에 반영할 관리 기준
포털에서 보여야 하는 것
- 어떤 값이 public config인지
- 어떤 값이 server-only secret인지
- 어떤 값이 missing이면 배포/심사가 막히는지
포털에서 보여주면 안 되는 것
- 실제 secret value
- 전체 connection string
- private key raw content
Admin tooling에 필요한 것
- webhook secret rotate 버튼
- module API key revoke 버튼
- 마지막 사용 시간
- 누가 언제 생성/회전했는지 audit log
9. Incident Response
secret 노출 의심 시 공통 절차:
- 노출 범위 판단
- repo commit
- CI log
- browser bundle
- screenshot/share
- 영향받는 secret 식별
- 우선순위 높은 secret부터 rotation
TOKEN_SECRET- DB credential
- deploy token
- 관련 세션/키 폐기
- audit 확인
- 재발 방지책 추가
특히 다음 경우는 즉시 대응:
TOKEN_SECRET가 외부로 노출됨- production
DATABASE_URL이 로그/PR에 노출됨 - GitHub Actions secret이 fork/로그에 남음
10. 바로 실행할 개선 항목
우선순위 순서:
membloc-app-engine/.env.example의TOKEN_SECRET을 placeholder 형태로 바꾸고 실제 운영값은 secret store로 이동membloc-developer-portal의 public env/public config 문서화- Vercel env를 preview / production으로 분리
- Firebase Authorized Domains에
developer.membloc.com반영 - Firebase Storage rules를 publisher asset 경로 기준으로 제한
- future webhook/API key secret rotation 설계 추가
11. 결정
- Firebase web config는 secret으로 취급하지 않는다.
DATABASE_URL,TOKEN_SECRET, deploy credential은 real secret으로 취급한다.- repo에는 예제 파일만 남기고 실제 운영값은 GitHub/Vercel/secret manager로 이동한다.
- secret rotation과 audit를 기능 설계 초기에 포함한다.