Proactive Defense: Hardening Code Pipelines and CI/CD Infrastructure
선제적 방어: 코드 파이프라인과 CI/CD 인프라 강화
Mandiant가 개발자 단말부터 저장소, 아티팩트, CI/CD, 배포 환경까지 소프트웨어 개발 수명주기 전반의 공급망 보안 수칙을 정리했습니다. 짧은 수명의 최소 권한 인증, 불변 다이제스트 검증, 격리된 빌드와 지속적인 서명·취약점 검사를 강조합니다.
- 주제
AI 요약
최근 공격자는 보안 도구와 개발 유틸리티, AI 개발 도구의 높은 권한을 노립니다. 개발자 단말에서 토큰과 암호화 키를 훔치거나, GitHub Actions 캐시를 오염시키고 OIDC 토큰을 탈취하며, 변경 가능한 액션 태그를 바꿔 정상적인 출처 증명을 갖춘 악성 패키지를 배포하는 식입니다. Mandiant는 개별 단계만 따로 보호해서는 부족하다며 소프트웨어 개발 수명주기(SDLC) 다섯 영역에 걸친 방어 지침을 제시합니다.
개발자 단말과 저장소
개발자 단말에는 저장소, 파이프라인, 클라우드에 접근하는 권한이 모입니다. 커밋 전 비밀정보 검사와 짧은 만료 시간(TTL)을 적용한 세분화된 Personal Access Token(PAT)을 사용하고, Endpoint Detection and Response(EDR)로 IDE 프로세스의 비정상 파일 접근과 프로세스 실행, 외부 통신을 살펴야 합니다. 검증된 IDE와 확장 프로그램만 허용하고, 개발 환경은 컨테이너나 전용 가상 머신(VM)으로 격리합니다. AI 도구는 승인된 모델만 쓰며, .env 파일이 모델 입력에 들어가지 않도록 하고 AI 생성 코드는 사람이 확인해야 합니다.
저장소에서는 다중 인증(MFA)과 기기 상태 확인으로 계정을 보호합니다. 기본 브랜치에 직접 푸시하지 못하게 하고, 동료 검토와 자동 CI 검사를 통과해야 병합하도록 설정합니다. 개발자 인증은 하드웨어 보안 키를 활용한 SSH 방식으로 옮기고, 자동화에는 서비스 계정 PAT 대신 만료 시간이 짧고 권한 범위가 제한된 GitHub App 토큰을 권장합니다. 의존성 버전은 정확히 고정하고 잠금 파일을 검증합니다. 정적 분석(SAST), 소프트웨어 구성 분석(SCA), 소프트웨어 자재 명세서(SBOM), SLSA Level 2 이상 출처 증명도 빌드 절차에 포함합니다.
아티팩트와 의존성
새 공개 패키지에는 최소 7일의 대기 기간을 두는 방안을 제시합니다. 악성 패키지가 공개된 뒤 커뮤니티가 이를 발견하고 제거할 시간을 확보하려는 목적입니다. 외부 패키지와 컨테이너 이미지는 중앙 프록시를 거쳐 검사하고, 새 구성 요소는 격리 상태에서 보안 판정을 받은 뒤 내부 신뢰 저장소로 승격합니다. 취약점 검사는 저장소와 실행 단계에서 이어가며, 실제 코드 경로에서 쓰이는지 분석하고 CISA KEV와 VEX 정보를 활용해 대응 우선순위와 경보량을 조절합니다.
패키지와 컨테이너에는 서명을 붙이고, 서명 검증은 배포 승인 단계에서 강제해야 합니다. 검증 대상은 태그가 아니라 불변 다이제스트여야 합니다. 컨테이너 이미지와 서드파티 액션도 변경 가능한 버전 이름 대신 SHA 다이제스트나 전체 커밋 해시로 고정합니다. 공개 저장소에 배포하는 인증 정보는 장기 토큰 대신 특정 빌드 워크플로에 묶인 단기 토큰으로 바꾸는 방향을 권합니다.
CI/CD와 배포 환경
CI/CD 작업은 매번 새로 만든 일회용 러너에서 실행하고 작업이 끝나면 폐기합니다. 자체 호스팅 러너는 사전 승인한 저장소와 API로만 통신하도록 네트워크를 제한합니다. 검증되지 않은 풀 리퀘스트 코드는 관리자 승인 전까지 비밀정보나 배포 권한이 있는 러너에 접근하지 못하게 해야 합니다. 공유 빌드 캐시는 브랜치 권한별로 나누고, 인증되지 않은 포크가 캐시에 쓰지 못하게 막습니다.
파이프라인 자동화에는 영구 비밀정보 대신 OIDC 기반 단기 자격 증명을 사용합니다. 러너 권한은 기본적으로 읽기 전용 또는 무권한으로 두고, 중첩 워크플로에 인증 정보가 자동 상속되지 않게 합니다. 서드파티 플러그인과 패키지 설치 스크립트도 통제하며, 코드 검사와 비밀정보 탐지, 컨테이너 검사, 동적 분석(DAST), 인프라 코드(IaC) 검사를 각 단계에 배치합니다. SBOM은 CycloneDX나 SPDX 형식으로 빌드 중 생성하고, 아티팩트 다이제스트에 연결해 서명합니다.
배포 시에는 유효한 서명이 없거나 불필요한 루트 권한을 요구하는 컨테이너를 차단합니다. 읽기 전용 루트 파일시스템과 강화된 기본 이미지를 사용하고, 서비스 간 통신을 허용된 경로로 제한합니다. 운영 환경의 설정은 버전 관리 중인 IaC와 지속적으로 대조하며, 로그와 지표, 감사 이벤트를 모아 침해 징후를 추적합니다. 글은 코드 커밋부터 운영 배포까지 검증과 정책 적용을 자동화하고, 침해가 발생해도 다른 시스템으로 번지지 않도록 격리하는 것을 목표로 제시합니다.
Reddit 반응
- @u/SugarvetFounder — 나쁘지 않은 체크리스트입니다. 저희도 아직 적용하지 않은 항목이 몇 가지 있습니다. 의존성 대기 기간은 어떻게 봐야 할지 모르겠습니다. 저희는 소스 코드 의존성, Kubernetes를 쓰지 않는 환경, 개발자 단말의 업데이트를 모두 제로데이처럼 다루지만, 관리 부담이 적다는 이유로 단순하게 세운 정책입니다. 언젠가는 상류 의존성 가운데 하나가 오염될 수 있다고 보는 편이 안전합니다. 어느 쪽을 골라도 어려운 상황입니다.
원문: Mandiant / 번역·요약: Trawling