CI/CD 파이프라인에서 시크릿 관리, 뭐부터 손대야 하나?

결론부터 말하면 저장 위치보다 노출 경로를 먼저 점검하는 쪽이 더 급했다. 2025년 3월 tj-actions/changed-files 공급망 공격은 시크릿을 어디에 "보관"했는지와 무관하게 워크플로 로그로 시크릿이 새어나가는 경로 때문에 23,000개 이상 저장소가 영향을 받았다출처. 판교에서 사내 파이프라인 몇 개를 운영하며 내린 판단은, 저장소 시크릿 스캔만으로는 부족하고 로그·아티팩트·캐시·서드파티 Action까지 점검 범위에 넣어야 한다는 것이었다.

  • 시크릿 노출의 57%는 하드코딩된 소스 코드, 25% 이상은 CI/CD 워크플로 자체에서 발생한다출처.
  • 단일 스캐너로는 다 못 잡는다 — Gitleaks와 ggshield의 진양성 중첩률은 18%에 그쳤다출처.
  • 정적 시크릿을 Vault 동적 시크릿이나 클라우드 OIDC로 바꾸면 유출 후 "쓸 수 있는 시간"을 줄이는 방향이다.
  • 서드파티 Action은 버전 태그가 아니라 커밋 SHA로 고정해야 한다는 게 tj-actions 사례의 교훈이다.
  • 배포 전략(블루그린·카나리)과 시크릿 로테이션 타이밍은 따로 설계하면 롤백이 실제로 작동하지 않을 수 있다.

시크릿은 CI 변수에 두나, Vault 동적 시크릿이나 OIDC로 가나?

수명이 긴 자격 증명일수록 중앙 관리자나 동적 발급으로 옮기는 편이 유리했다. CI 변수에 장기 DB 비밀번호나 클라우드 액세스 키를 고정해두면, 그 값이 로그나 아티팩트로 한 번만 새어도 로테이션 전까지 계속 쓸 수 있다. Vault는 요청 시점에 단기 자격 증명을 발급하는 동적 시크릿 기능을 제공하는데, 유출되더라도 사용 가능 시간 자체를 줄이는 쪽으로 작동한다출처.

AWS 단일 클라우드라면 Secrets Manager·SSM Parameter Store를 IAM 역할과 묶는 구성이, 멀티클라우드라면 Vault 같은 중앙 시크릿 관리자가 거론된다출처. 실무적으로 더 큰 변화는 OIDC 전환이었다. CI가 클라우드에 접근할 때 장기 액세스 키를 저장소에 박아두는 대신 OIDC 기반 연동을 쓰면 저장소에 고정된 클라우드 자격 증명 자체를 없앨 수 있다. 다만 신뢰 조건을 저장소·브랜치·배포 환경 단위로 구체적으로 제한해야 한다는 전제가 붙는다. 이 조건을 와일드카드로 느슨하게 설정하면 OIDC도 장기 키만큼 위험해질 수 있다는 건 감수해야 할 한계다. 저장소 한두 개, 팀이 작으면 CI 변수 + 스캔 조합으로 버틸 수 있지만, 저장소가 늘고 같은 시크릿을 여러 파이프라인이 공유하는 시점부터는 중앙 관리자로 옮기는 운영 비용과 유출 시 로테이션 범위 축소 이득을 저울질해야 한다.

서드파티 GitHub Action, SHA 고정이 정말 필요한가?

필요하다고 본다. 2025년 3월 14~15일 tj-actions/changed-files가 악성 커밋으로 변조되면서, 이 Action을 부동 태그로 참조하던 워크플로는 실행 시점에 바뀐 코드를 그대로 받아 실행했다. CVE-2025-30066으로 식별된 이 사건에서 CI/CD 시크릿이 워크플로 로그로 노출될 수 있었다출처. 대응은 세 가지였다 — 영향받은 Action 버전 제거, 해당 기간 로그 감사, 관련 시크릿 즉시 로테이션.

이 사건이 보여준 건 "시크릿을 어디에 저장했나"와 "그 저장소에서 실행되는 서드파티 코드를 얼마나 신뢰할 수 있나"가 별개의 위험 축이라는 점이다. 실무 대응은 외부 Action을 커밋 SHA로 고정하고, 워크플로 권한은 permissions: 블록으로 필요한 범위만 부여하는 것이다. 태그 고정은 최신 패치를 자동으로 받는 편의가 있지만, 그 편의가 바로 이번 공격의 통로였다. SHA 고정은 업데이트를 수동으로 가져와야 하는 불편을 감수하는 대신, 임의 시점에 코드가 바뀌는 경로를 차단한다. 번거로움은 Dependabot 같은 도구로 SHA 업데이트 PR을 자동 생성해 줄이는 방식이 실무에서 쓰인다.

블루그린·카나리 전환 시점에 시크릿 로테이션은 언제 끼워 넣나?

배포 전략과 시크릿 로테이션은 전환 타이밍에 맞춰 같이 설계해야 사고가 줄었다. 블루그린은 기존·신규 두 환경을 동시에 띄워두고 트래픽을 한 번에 전환한 뒤, 문제가 생기면 이전 환경으로 되돌리는 방식이다출처. 이 구조에서 배포와 동시에 시크릿을 로테이션하면, 새 환경은 새 시크릿을 쓰고 이전 환경은 여전히 옛 시크릿을 참조하는 상태가 한동안 공존한다. 롤백이 필요할 때 이전 환경이 이미 폐기된 옛 시크릿을 쓰고 있으면 복구가 안 될 수 있어, 로테이션 유예 기간을 두는 설계가 필요하다.

카나리는 일부 트래픽에 새 버전을 먼저 노출하고 지표를 보며 비율을 늘리는 방식으로, 공개 사례에서는 초기 트래픽을 1~10%로 둔 예가 제시됐다출처. 시크릿 로테이션을 카나리 단계와 겹치면 신버전 소수 인스턴스만 새 자격 증명을 쓰는 동안 장애가 나도 영향 범위가 제한된다는 장점이 있다. 다만 오류율 1% 초과가 2분 지속되거나 p95 지연시간이 500ms를 5분 넘기면 롤백하는 식의 SLO 기준은 서비스마다 달라야 하는 예시값이지 일반 규칙은 아니다출처. 결제·인증처럼 롤백 경로가 단순해야 하는 서비스는 블루그린 쪽이, 점진 검증과 인프라 비용 절감이 우선인 서비스는 카나리 쪽이 더 맞는 선택지였다.

시크릿 스캐너 비교, 숫자로 보면 어떻게 다른가?

2025년 NC State 연구가 공개한 SecretBench 데이터셋(818개 저장소, 97,479개 라벨링 사례)으로 비교한 결과를 보면 단일 도구로 충분하다고 말하긴 어려웠다출처.

도구 재현율 정밀도
Gitleaks 88% 46%
GitHub Secret Scanner 상대적으로 낮음 75%

Gitleaks는 재현율이 가장 높았지만 정밀도가 낮아 경보가 많이 울렸고, GitHub Secret Scanner는 정밀도가 가장 높은 대신 재현율이 낮았다. 도구 간 탐지 겹침도 크지 않아 ggshield와 Gitleaks의 진양성 중첩률은 18%였다. 이 수치가 말해주는 실무 함의는 단일 스캐너만으로는 누락이 생긴다는 것이다. 내가 쓰는 배치는 PR 단계에 변경 파일만 보는 빠른 스캐너를 두고, 야간이나 릴리스 빌드에는 다른 엔진으로 전체 저장소를 한 번 더 돈다. TruffleHog --only-verified 같은 옵션은 문자열이 실제로 유효한 자격 증명인지 확인해 비활성 패턴으로 인한 경보를 줄이는 데 썼다.

캐싱·병렬화로 줄인 시간, 스캔이 다시 까먹지 않나?

맞다, 이 부분이 가장 자주 놓치는 함정이었다. 한 2025년 CI/CD 사례에서는 전체 실행 시간이 약 27분이었고, 의존성 캐싱으로 실행당 30~60초, 독립 테스트를 3개 Node.js 버전×2개 운영체제로 병렬화해 순차 실행보다 약 15분을 줄였다고 보고했다출처. 이 값은 특정 프로젝트·러너 조건의 보고 사례이지 일반 보장값이 아니다. 캐시 키에 운영체제, 런타임 버전, lockfile 해시를 포함하지 않으면 다른 브랜치나 런타임 결과가 섞여 들어가는 함정도 있다.

더 중요한 함정은 시크릿 자체를 캐시에 올리는 실수다. 패키지 관리자 캐시나 빌드 레이어는 저장 기간이 길고 접근 주체가 넓어질 수 있어서, 인증 토큰·.env 파일·배포 설정 파일은 캐시 경로에서 명시적으로 제외해야 한다. 병렬화도 테스트 간 공유 상태가 없어야 한다는 전제가 있다 — 공용 데이터베이스나 고정 포트를 여러 워커가 같이 쓰면 속도 이득보다 플래키 테스트와 재실행 비용이 더 커질 수 있다. 보안 스캔을 파이프라인 맨 끝에만 두면 피드백이 느려지므로, 변경 파일 대상 빠른 검사는 앞단에, 전체 검사는 통합 테스트 뒤에 두는 배치가 현실적이었다.

결국 어떤 상황에 뭘 고르나?

규모와 실패 허용 범위에 따라 갈렸다. 2026년 기준으로 내가 정리한 선택지는 다음과 같다.

  • 소규모·단일 저장소: CI 변수 + 변경 파일 기반 스캔 + 야간 전체 스캔
  • 다중 저장소·클라우드 접근 빈번: OIDC + IAM 역할로 장기 키 제거
  • 멀티클라우드·여러 팀 공유: Vault 같은 중앙 시크릿 관리자, 동적 시크릿 발급
  • 서드파티 Action 의존도 높음: SHA 고정 + 최소 권한 permissions
  • 결제·인증처럼 즉시 롤백이 중요: 블루그린 + 로테이션 유예 기간
  • 점진 검증·비용 절감 우선: 카나리 + SLO 기반 자동 롤백 기준

Vault, AWS Secrets Manager, GitHub Actions 조합을 동일 조건에서 비교한 1차 벤치마크는 아직 충분히 공개돼 있지 않다. 처리량·메모리 수치를 단정하기보다, 같은 러너·같은 시크릿 크기·같은 동시 요청 수로 직접 재현해보는 편이 더 믿을 수 있는 결론을 준다.

핵심 정리

  • 시크릿 노출 경로의 25% 이상은 CI/CD 워크플로 자체이고, 57%는 하드코딩이다 — 저장 위치만 바꿔서는 부족하다출처.
  • 단일 스캐너의 한계는 수치로 드러난다 — Gitleaks 재현율 88%/정밀도 46%, 도구 간 진양성 중첩 18%출처.
  • 서드파티 Action은 SHA 고정, 최소 권한 부여가 tj-actions 사건 이후의 현실적 방어선이다출처.
  • 캐시·병렬화로 줄인 시간을 전체 스캔이 다시 까먹을 수 있다 — 변경 파일 우선 검사와 정기 전체 검사를 분리한다.
  • 배포 전략(블루그린/카나리)과 시크릿 로테이션 타이밍은 함께 설계해야 롤백이 실제로 작동한다.