Development

CI 시크릿 만료 사고 대응 플레이북: 배포 중단 40분에서 8분으로 줄인 운영 절차

Mike발행일 2026년 3월 13일읽는 시간 약 3

💡 Key Takeaways

  • 시크릿 사고는 장애 원인보다 탐지 지연이 더 큰 비용을 만든다.
  • 런북을 슬롯 단위(탐지-격리-복구-검증)로 고정하면 야간 온콜에서도 실수율이 줄어든다.
  • 로테이션 자동화보다 먼저 권한 경계와 실패 시 롤백 경로를 명확히 해야 한다.

CI 시크릿 만료 사고 대응 플레이북

월요일 오전 릴리스를 앞두고 GitHub Actions가 연속으로 실패했는데, 에러 로그 첫 줄은 단순한 401 Unauthorized였습니다. 처음 10분은 API 서버 권한 문제인지, 네트워크 정책 변경인지, 혹은 배포 스크립트 회귀인지 팀 채널에서 추측만 오갔고 그 사이 운영 배포 창은 계속 줄어들었습니다. 실제 원인은 더 단순했습니다. 결제 연동에 쓰던 서드파티 토큰이 전날 밤 만료됐고, 스테이징 파이프라인은 캐시된 자격 증명으로 겨우 통과했지만 프로덕션 잡은 새 컨테이너에서 즉시 실패했습니다. 여기서 배운 점은 “시크릿 이슈는 기술 난이도보다 판단 순서가 승부를 가른다”는 사실이었습니다. 누가 어떤 로그를 먼저 보고, 어떤 범위를 멈추고, 어떤 키부터 교체할지를 5분 내에 정하지 못하면 복구 시간이 두 배로 늘어납니다. 그래서 이후에는 사고를 원인 중심이 아니라 의사결정 슬롯 중심으로 다뤘습니다. 문제 정의를 인증 실패 + 배포 차단 + 원인 미확정으로 고정하고, 원인 분석은 병렬로 돌리되 릴리스 영향 최소화 결정을 먼저 내리는 구조로 바꿨습니다.

제가 팀에 적용한 첫 기준은 “영향 면적을 즉시 줄일 수 있느냐”였습니다. CI 실패가 보이면 먼저 최근 3회 워크플로를 비교해 동일 단계에서 터지는지 확인하고, 동일 지점이면 코드 변경 검토보다 자격 증명 경로를 우선 점검합니다. 이때 흔한 실수는 모든 시크릿을 한 번에 교체하는 것인데, 그러면 어느 키가 원인이었는지 추적이 끊기고 권한 범위가 불필요하게 넓어집니다. 대신 서비스 계정 키, 외부 API 토큰, 패키지 레지스트리 토큰을 분리해 만료 시점과 소유 팀을 붙여 관리해야 합니다. 우리 팀은 여기서 한 번 더 사고를 냈습니다. 키를 교체해도 실패가 계속됐는데 알고 보니 저장소 환경(production)과 조직 시크릿 이름이 달랐고, 배포 액션은 환경 시크릿만 읽고 있었습니다. 그 뒤로는 “키 값 확인”보다 “참조 경로 확인”을 체크리스트 상단으로 올렸습니다. 판단 기준을 정리하면 세 가지입니다. 첫째, 실패 단계가 인증 단계에 고정되는가. 둘째, 실패 대상이 특정 환경에 한정되는가. 셋째, 키 교체 이후 동일 런에서 권한 검증 로그가 바뀌는가. 이 세 질문에 답하면 원인 후보를 15분 안에 절반 이하로 줄일 수 있습니다.

실행 절차는 탐지, 격리, 복구, 검증 네 슬롯으로 고정했습니다. 탐지 단계에서는 워크플로 실패 알림에 run_id, environment, secret_ref를 함께 붙여 슬랙으로 보내고, 온콜은 최근 성공 배포와의 차이를 3분 내 요약합니다. 격리 단계에서는 자동 재시도를 잠시 꺼서 불필요한 실패 로그 확산을 막고, 릴리스 매니저가 “핫픽스 유지/배포 동결”을 명시합니다. 복구 단계에서는 문제 시크릿만 우선 재발급하고 TTL을 기록한 뒤, GitHub 환경 시크릿 반영 후 드라이런 잡으로 인증 단계만 먼저 통과시킵니다. 전체 배포를 바로 돌리지 않는 이유는, 인증 외 단계에서 또 실패하면 사고 타임라인이 엉키기 때문입니다. 검증 단계에서는 동일 커밋으로 전체 파이프라인을 재실행하고, 성공 후 30분 동안 관련 API 에러율과 배포 롤백 지표를 함께 봅니다. 실제로 이 절차를 적용한 뒤 같은 유형의 만료 사고에서 MTTR이 40분에서 8분으로 줄었습니다. 핵심은 자동화 도구가 아니라 사람이 동일한 순서로 움직이게 만드는 운영 문서였습니다. 새 팀원이 들어와도 슬롯만 따라가면 최소한의 복구 품질을 확보할 수 있었고, 야간 대응에서 가장 취약했던 “누가 결정하나” 문제도 릴리스 매니저 단일 책임으로 정리됐습니다.

운영 체크리스트는 과하게 길 필요가 없습니다. 대신 놓치면 치명적인 항목만 남겨야 합니다. 시크릿마다 소유자와 만료일, 사용 워크플로를 한 줄로 연결하고, 만료 7일 전 경고를 온콜 채널로 보내며, 로테이션 후에는 반드시 “이전 키 폐기 완료” 이벤트를 남기세요. 주의할 점도 분명합니다. 첫째, 로테이션 자동화를 급하게 붙이면 권한 스코프가 커져 사고 반경이 더 넓어질 수 있습니다. 둘째, 테스트 환경만 통과한 상태에서 프로덕션 교체를 강행하면 환경별 참조 차이로 같은 장애를 반복합니다. 셋째, 감사 로그를 나중에 보겠다고 미루면 다음 분기 보안 점검에서 재현 근거가 사라집니다. 저는 분기마다 30분짜리 “시크릿 만료 모의훈련”을 꼭 넣고, 실패 시나리오를 일부러 섞어 팀이 당황하지 않게 만듭니다. 문서는 정답집이 아니라 행동 순서를 고정하는 장치라는 점을 기억하면, 시크릿 사고는 충분히 예측 가능한 운영 이슈로 바꿀 수 있습니다.

함께 읽으면 좋은 글

Development

Kubernetes HPA 스래싱 진정 플레이북: 점심 피크 장애를 3일 만에 멈춘 운영 절차

2026-03-14
Development

온콜 인수인계에서 SLO 알림 튜닝까지: 새벽 장애를 줄인 운영 플레이북

2026-03-12

본문 작성/검수 원칙은 편집 원칙에서 확인할 수 있습니다.

← 목록으로 돌아가기