API 키·DB 비밀번호·웹훅 시크릿이 깃 커밋·프론트 번들·CI 로그·프리뷰에 새는 경로를 막고, .env·gitignore·공개 접두사·Actions Secrets·시크릿 스캔·런타임 주입·로테이션·유출 15분 대응까지 약 40항목으로 점검하는 보안 체크리스트. 개발자·백엔드·데브옵스 팀이 배포 게이트와 월간 감사에 바로 쓰는 실무 가이드.
프로덕션 API 키·DB 비밀번호·웹훅 시크릿이 깃허브 커밋·프론트 번들·프리뷰 로그에 한 번이라도 들어가면, 그 순간부터 서비스는 “이미 노출됐을 수 있는 상태”로 취급해야 합니다. 복구 비용은 로테이션·토큰 폐기·접근 로그 감사까지 포함해 수 시간에서 수일이 걸립니다.
이 체크리스트는 로컬 .env → CI 시크릿 → 런타임 주입 → 스캔·로테이션 → 사고 대응 순서로 약 40개 항목을 나눕니다. 배포 직전 30분 점검, PR 템플릿 고정 게이트, 분기 1회 전수 감사에 그대로 쓸 수 있습니다. AI API 키 전용 가이드와 겹치지 않게, 일반 백엔드·프론트·데브옵스 공통 시크릿 운영에 초점을 둡니다.
시크릿이 새는 다섯 지점 — 커밋·번들·로그·프리뷰·채팅
유출은 “해커가 뚫었다”보다 일상 워크플로 실수에서 더 자주 납니다. 가장 흔한 다섯 지점은 다음과 같습니다.
깃 히스토리 — .env를 커밋하거나, 예제 파일에 실키를 남김
클라이언트 번들 — NEXT_PUBLIC_·Vite VITE_ 접두 변수에 서버 전용 키를 넣음
CI 로그 — echo $SECRET, 디버그 플래그, 실패한 curl 본문에 토큰 출력
프리뷰·스테이징 — 운영 DB URL·결제 라이브 키를 미리보기 환경에 연결
슬랙·이슈·스크린샷 — 에러 메시지·대시보드 캡처에 키 일부 노출
아래 표로 “어디에 둬야 하는지”를 먼저 고정하세요. 저장 위치가 애매하면 체크리스트를 돌려도 같은 사고가 반복됩니다.
시크릿은 단계마다 저장소가 달라야 한다 — 한 파일을 전 환경에 복사하는 순간 유출 면적이 커진다
로컬·저장소 체크리스트 — .env·gitignore·예제 파일
로컬 실수가 히스토리에 남으면, 이후 프라이빗 저장소로 바꿔도 클론·포크·CI 캐시에 키가 남을 수 있습니다. 저장소 루트 규칙을 먼저 고정하세요.
이미 커밋했다면 파일만 삭제하고 끝내지 마세요. 히스토리 rewrite(필터 브랜치/BFG) 또는 키 즉시 폐기·재발급이 우선입니다. rewrite는 협업 브랜치를 깨뜨리므로, 공개 노출이 의심되면 키 무효화가 더 빠릅니다.
클라이언트 번들 체크리스트 — 공개 접두사와 서버 전용 분리
Next.js의 NEXT_PUBLIC_*, Vite의 VITE_*, Create React App의 REACT_APP_*는 빌드 결과물에 문자 그대로 들어갑니다. 브라우저 개발자 도구 Network·Sources에서 누구나 읽을 수 있습니다. “프론트에서 슈퍼베이스 서비스 롤 키를 쓰면 편하다”는 선택이 가장 비싼 실수입니다.
규칙은 단순합니다. 브라우저가 알아도 되는 값만 공개 접두사를 붙입니다. 사이트 URL, 공개 API 베이스, 애널리틱스 측정 ID, 공개 익명 키 정도입니다. DB 접속 문자열, 어드민 키, 웹훅 시크릿, 결제 시크릿, LLM 서버 키는 서버·엣지 함수·BFF 뒤에만 둡니다.
깃허브 Actions·버셀·기타 CI에 넣는 시크릿은 “저장은 됐는데 로그에 찍히는” 사고가 많습니다. 워크플로 작성 규칙과 권한(least privilege)을 체크리스트에 고정하세요.
CI 로그에 토큰이 한 줄이라도 보이면 해당 키는 즉시 폐기 대상으로 본다
시크릿 스캔 체크리스트 — 커밋 전·PR·원격 히스토리
사람이 리뷰만으로 키 패턴을 다 잡기는 어렵습니다. 커밋 전 훅 + PR 스캔 + 원격 푸시 후 플랫폼 스캔 3단이 현실적인 최소 구성입니다. 도구는 팀이 이미 쓰는 스택에 맞추면 됩니다. gitleaks, trufflehog, 깃허브 secret scanning, GitLab secret detection 등이 대표적입니다.
스캔은 “한 번 돌려보기”가 아니라 차단 게이트여야 합니다. 경고만 하고 머지되는 설정은 사실상 없는 것과 같습니다. 오탐이 많으면 allowlist를 문서화한 뒤 패턴을 좁히고, 진짜 키 형식(AWS AKIA, 깃허브 PAT, 슬랙 토큰 등)은 높은 심각도로 유지합니다.
앱이 떠 있는 동안 시크릿은 프로세스 환경 변수나 메모리에 존재합니다. Dockerfile에 ENV API_KEY=...를 박거나, 이미지 빌드 인자로 키를 넘기면 레이어 캐시에 남습니다. 런타임에 플랫폼이 주입하거나, 기동 시 시크릿 매니저에서 읽어 오는 쪽이 안전합니다.
이미지나 저장소가 아니라 런타임 주입 경로를 짧게 유지할수록 유출 면적이 줄어든다
로테이션·접근 권한 체크리스트 — 누가·언제·왜
키가 “한 번도 안 새도” 영구 불변 키는 위험합니다. 퇴사자 계정, 예전 CI 토큰, 테스트용으로 만든 광범위 키가 수개월 방치되는 경우가 많습니다. 로테이션 주기를 서비스 등급별로 정해 두면 사고가 났을 때도 절차가 손에 익습니다.
유출 의심 시 대응 체크리스트 — 15분·1시간·24시간
채팅에 키가 붙었거나, 공개 이슈에 토큰이 올라왔거나, 스캐너가 Critical을 냈을 때 “나중에 로테이션”은 답이 아닙니다. 시간 박스별로 행동을 고정해 두면 패닉 중에도 순서가 유지됩니다.
공개 저장소에 키가 올라간 경우 커밋 삭제만으로 안전하지 않습니다. 포크·미러·봇 클론·검색 엔진 캐시를 가정하고, 키 자체를 죽은 것으로 간주하는 편이 맞습니다.
팀 운영 방법 — 매 배포 게이트와 월간 감사
40개 항목을 매 배포마다 손으로 다 돌리면 금방 형식만 남습니다. 역할을 나누세요.
매 PR: 시크릿 스캔 CI 통과, 공개 접두사 변수 diff 리뷰
매 배포: 프로덕션 env 목록 diff 확인, 프리뷰≠프로덕션, fail-fast 기동
월 1회: 인벤토리 표 갱신, 만료 임박 키 로테이션, 히스토리 스캔 샘플링
분기 1회: 유출 대응 리허설, 퇴사자 토큰 감사, 클라우드 IAM 장기 키 전수
1인 개발자는 “스캔 CI + 공개 접두사 금지 + 유출 시 즉시 폐기” 세 가지만 고정 게이트로 두고, 인벤토리 표는 월 1회로 줄여도 사고 확률을 크게 낮출 수 있습니다. AI로 생성한 코드에 키가 박히는 패턴은 바이브코딩 프로덕션 체크리스트와 함께 보시면 됩니다. 배포 후 이상 징후는 센트리 도입 사례처럼 에러·릴리즈 게이트와 연결해 두면 조기 발견에 유리합니다.
아니요. 프라이빗이어도 협업자·CI·유출된 토큰·잘못된 미러·퇴사자 클론을 통해 키가 복사될 수 있습니다. 저장소에는 예제만 두고, 실값은 시크릿 저장소나 호스팅 env에 두며, 유출 가능성을 전제로 로테이션 가능한 구조를 유지하세요.
NEXT_PUBLIC_ 키는 아예 쓰면 안 되나요?
공개돼도 되는 값에는 씁니다. 문제 되는 것은 서버 전용 비밀을 공개 접두사에 넣는 경우입니다. 애널리틱스 ID, 공개 익명 키, 사이트 URL처럼 브라우저가 어차피 알 값만 접두사를 붙이고, 나머지는 서버·BFF 뒤로 옮기면 됩니다.
시크릿 스캐너 오탐이 많아서 CI를 못 막겠어요.
처음 1~2주는 warn 모드로 패턴을 다듬고, 고위험 형식(클라우드 액세스 키, PAT, 슬랙 봇 토큰 등)만 먼저 fail로 올리는 단계 도입이 현실적입니다. allowlist는 만료일과 승인자 없이 무한 추가하지 마세요. 오탐 감소 후 전체 fail 게이트로 올립니다.
이미 깃 히스토리에 키가 있는데 rewrite가 부담됩니다.
공개 노출이 가능하거나 이미 푸시된 경우, rewrite보다 키 폐기·재발급이 우선입니다. rewrite는 모든 클론·포크를 따라오지 않으면 잔존본이 남습니다. 폐기 후 신규 키로 서비스 전환이 끝난 뒤에, 필요하면 히스토리 정리를 별 프로젝트로 진행하세요.
시크릿 매니저(AWS·GCP·Vault 등)까지 꼭 써야 하나요?
소규모·단일 앱이면 호스팅 플랫폼 env + CI Secrets + 스캔 게이트만으로도 실무 수준에 도달하는 경우가 많습니다. 키가 수십 개로 늘고, 다중 환경·다중 서비스·감사 로그가 필요해지면 매니저 도입 비용이 이득을 넘습니다. “키 개수·교체 빈도·감사 요구” 세 가지로 결정하면 됩니다.
프리뷰 배포에 운영 DB를 잠깐 연결하는 건 어떤가요?
비추천입니다. 프리뷰 URL·로그·협업자 범위가 운영보다 넓고, 실수로 마이그레이션·삭제가 실행될 수 있습니다. 프리뷰는 마스킹된 스테이징 데이터 또는 별도 샌드박스 DB를 쓰고, 운영 자격 증명은 프로덕션 환경 보호 규칙 뒤에만 두세요.