우리가 배포하는 컨테이너 이미지가 정말로 사내 빌드 시스템에서 만들어진 것일까요? 아니면 중간에 누군가 악성 코드를 심어놓지는 않았을까요? 소프트웨어 공급망 보안(Software Supply Chain Security)은 소스 코드부터 최종 사용자에게 전달되기까지의 전 과정을 보호하고 검증하는 일입니다
공급망 보안의 3대 요소
공급망 보안을 강화하기 위해 최근 업계에서 표준으로 자리 잡고 있는 세 가지 핵심 개념입니다
| 요소 | 설명 | 목적 |
|---|---|---|
| SLSA | 소프트웨어 제작 단계별 보안 등급 (L1~L4) | 빌드 무결성 보장 |
| SBOM | 소프트웨어에 포함된 모든 의존성 명세서 | 취약한 패키지 추적 |
| Signing | 결과물에 대한 디지털 서명 | 출처 및 변조 여부 확인 |
SBOM: 소프트웨어 자재 명세서
SBOM(Software Bill of Materials)은 요리 레시피의 성분표와 같습니다. 우리 앱이 어떤 오픈소스 라이브러리를 몇 버전으로 쓰고 있는지 상세히 기록합니다
- 표준 포맷: CycloneDX, SPDX가 주로 쓰입니다
- 활용: 새로운 CVE 취약점이 발표되었을 때, 사내의 어떤 이미지들이 영향을 받는지 즉시 찾아낼 수 있습니다
이미지 서명: Cosign과 Sigstore
빌드된 이미지가 신뢰할 수 있는 것인지 증명하기 위해 디지털 서명을 사용합니다. 최근에는 복잡한 키 관리가 필요 없는 Sigstore 생태계의 Cosign이 대세입니다
sequenceDiagram
participant CI as Build CI (GitHub Actions)
participant OIDC as OIDC Provider
participant REG as Registry
participant K8S as Kubernetes
CI->>CI: 이미지 빌드
CI->>REG: 이미지 푸시
CI->>OIDC: 신원 증명 요청
OIDC-->>CI: ID Token 발급
CI->>REG: Cosign으로 서명 데이터 푸시
K8S->>REG: 이미지 풀
K8S->>K8S: 서명 검증 (Kyverno/OPA)
K8S->>K8S: 검증 완료 후 실행
OIDC 연동을 통한 Keyless 서명을 사용하면 별도의 개인키를 관리할 필요 없이, 빌드 파이프라인의 신원(예: GitHub Actions 워크플로우 이름)으로 이미지를 신뢰할 수 있습니다
클러스터에서의 검증
서명된 이미지를 만드는 것만큼 중요한 것이 배포 시점의 검증입니다. 쿠버네티스의 어드미션 컨트롤러(Admission Controller)를 사용하여 서명되지 않은 이미지의 실행을 차단해야 합니다
- Kyverno: 정책 기반으로 이미지 서명을 검증하고, 서명이 없으면 Pod 생성을 거부합니다
- OPA/Gatekeeper: 더 복잡한 비즈니스 로직을 포함한 검증 정책을 세울 수 있습니다
핵심 인사이트: "Trust, but Verify"
사내 레지스트리에 있는 이미지라고 무조건 믿어서는 안 됩니다. "누가, 언제, 어떤 코드로" 만들었는지 기계적으로 확인할 수 있는 서명 체계가 갖춰져야만 진정한 제로 트러스트(Zero Trust) 보안을 실현할 수 있습니다
정리
- 공급망 보안은 소스 코드에서 배포까지의 무결성을 다룹니다
- SBOM을 통해 사내 소프트웨어의 투명성을 확보합니다
- Cosign을 활용하여 빌드 결과물에 대한 출처 증명을 자동화합니다
- 쿠버네티스 레벨에서 정책 기반 검증을 통해 보안을 강제합니다
다음 글에서는 파이프라인 곳곳에서 취약점을 찾아내는 SAST·DAST·의존성 스캔 도구들에 대해 알아봐요