Files
service-catalog/doc/sbom-pipeline.md
T
wbsong111 d6e3d0af79 docs(sbom): add pipeline image Dockerfile + cross-reference from workflow
.github/workflows/sbom.yml 의 SBOM_PIPELINE_IMAGE 로 사용하는 실행 이미지
Dockerfile 을 doc/scripts/Dockerfile 로 추가(debian/glibc + helm/trivy/python3/git).
워크플로·sbom-pipeline.md 에서 상호 참조하도록 갱신.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:26:04 +09:00

6.1 KiB

Helm 카탈로그 SBOM 생성 파이프라인

manifests/helm/ 정적 카탈로그의 모든 컨테이너 이미지에 대한 SBOM(CycloneDX)과 취약점 리포트를 결정론적으로 생성하는 파이프라인. helm/trivy/python3 가 설치된 리눅스 컨테이너 안에서 실행한다.

왜 필요한가

GitHub Dependency-Graph SBOM(예: paasup_dip-catalog_199087.json)은 pypi 등 소스 매니페스트만 담고 Helm 차트가 참조하는 컨테이너 이미지는 하나도 포함하지 못한다(Helm 미지원 + 이미지 미스캔). 이 파이프라인이 그 공백을 메운다 — helm template 렌더로 실제 배포 이미지를 뽑고, 각 이미지의 SBOM 과 취약점을 생성한다.

아키텍처 (SBOM-first)

이미지를 한 번만 pull 해서 SBOM 을 만들고, 취약점은 그 SBOM 에서 오프라인으로 뽑는다.

extract-helm-images.sh          generate-sbom.sh                    scan-sbom.sh
manifests/helm/**  ──helm template──▶ images_final.tsv ──trivy image──▶ sbom/*.cdx.json ──trivy sbom──▶ trivy-summary.md
                    (오프라인·결정론)      (이미지 1회 pull, 인증 필요)  (CycloneDX)   (오프라인·인증 불필요)  + trivy-reports/
  • 레지스트리 pull·인증은 SBOM 생성 단계 1곳으로 집중. 취약점 스캔은 네트워크·인증 없이 빠르게 반복 가능 (CVE DB 갱신 시 재pull 없이 재스캔).
  • 스캔 대상 이미지는 trivy 가 원격에서 받아 분석 후 폐기하므로 호스트/이미지 스토어에 남지 않는다.

실행 환경 요구사항

스크립트는 컨테이너 내부에 설치된 바이너리를 직접 호출한다. 실행 이미지에 다음이 있어야 한다.

도구 사용 스크립트
helm (v3) extract-helm-images.sh
trivy generate-sbom.sh, scan-sbom.sh
python3, bash, git 공통

이 이미지는 doc/scripts/Dockerfile 로 빌드한다(debian/glibc 기반 — CI container: 안에서 node 기반 액션 호환). 빌드·푸시 후 태그를 .github/workflows/sbom.yml 의 Repo Variable SBOM_PIPELINE_IMAGE 에 지정한다. amd64 필수(GitHub 러너 아키텍처).

스크립트 (doc/scripts/)

스크립트 입력 출력
extract-helm-images.sh manifests/helm/ images_final.tsv (chart⇥version⇥image), render_status.tsv
generate-sbom.sh images_final.tsv sbom/<img>.cdx.json, sbom-index.tsv, sbom-gen.log
scan-sbom.sh sbom/ + sbom-index.tsv trivy-summary.{tsv,md}, trivy-reports/, trivy-run.log

로컬/컨테이너 실행

# 도구가 설치된 이미지 안에서 (예: <pipeline-image> = helm+trivy+python3 보유 이미지)
docker run --rm -v "$PWD:/repo" -w /repo -e TRIVY_CACHE_DIR=/repo/sbom-out/cache <pipeline-image> bash -c '
  bash doc/scripts/extract-helm-images.sh manifests/helm sbom-out
  bash doc/scripts/generate-sbom.sh sbom-out/images_final.tsv sbom-out   # DOCKER_CONFIG/TRIVY_USERNAME 로 인증
  bash doc/scripts/scan-sbom.sh sbom-out
'

주요 환경변수: PARALLEL(동시 처리), LIMIT(대상 상한, 디버그용), SEVERITY(기본 HIGH,CRITICAL), TRIVY_CACHE_DIR(캐시 디렉토리), MERGE=1(generate 시 catalog.cdx.json 병합, cyclonedx CLI 필요). 사설 레지스트리 인증은 trivy 네이티브: TRIVY_USERNAME/TRIVY_PASSWORD(단일) 또는 DOCKER_CONFIG(다중).

CI (.github/workflows/sbom.yml)

  • 트리거: schedule(주 1회, 전체) / pull_request(manifests/helm/** 변경 시, 변경 차트만 증분) / workflow_dispatch.
  • 컨테이너: vars.SBOM_PIPELINE_IMAGE (helm+trivy+python3 보유 이미지)에서 실행.
  • 시크릿: DOCKERHUB_TOKEN/DOCKERHUB_USER(rate limit), NGC_API_KEY(nvcr.io), 필요 시 paasup 사설 레지스트리.
  • 아티팩트: sbom/(+catalog.cdx.json), trivy-summary.* 업로드 + Job Summary 표시. 산출물은 커밋하지 않는다(.gitignore).
  • 스캔 주기 원칙: 인벤토리·SBOM 은 차트 변경 시에만 바뀌지만 취약점은 새 CVE 로 계속 변하므로 스케줄 전체 스캔이 필수. PR 은 변경 차트만(빠른 게이트), 스케줄은 전체.

렌더 함정 (extract 단계, 스크립트에 내장)

플래그 이유
--set global.security.allowInsecureImages=true bitnamilegacy/* 오버라이드가 Bitnami common 의 insecureImages 가드에 걸려 렌더 실패하는 것 방지
--kube-version 1.31.0 일부 차트의 kubeVersion 상한 제약 회피 (예: rancher < 1.32)

trivy 병렬 실행 시 공유 캐시 bolt 잠금 충돌을 피하려 워커는 --cache-backend memory --skip-db-update, 메인은 시작 시 trivy image --download-db-only 로 DB 를 1회 워밍한다.

산출물

  • sbom/<img>.cdx.json — 이미지별 CycloneDX SBOM (bomFormat CycloneDX). catalog.cdx.json(선택) = 전체 병합.
  • sbom-index.tsv — chart⇥version⇥image⇥status⇥sec⇥sbom_file (차트↔이미지↔SBOM 매핑).
  • trivy-summary.md / .tsv — 이미지별 CRITICAL/HIGH 집계 (차트 컬럼 포함), 총계·소요시간.
  • trivy-reports/<img>.json — 이미지별 원본 취약점 결과.

운영 노트 — :latest/무태그 이미지 digest 고정

태그가 고정돼 있어도 내용물이 바뀌는 :latest/무태그 이미지는 재현성 저해 + 증분 스캔의 사각지대다. 정기 전체 스캔 대상에 항상 포함하고, 가능하면 구체 버전 또는 digest(@sha256:...)로 고정한다.

적용된 고정(2026-07-08 기준):

  • mlflow@1.9.0 postgresql → bitnamilegacy/postgresql@sha256:42a8200d... (legacy 에 v18 버전 태그 부재, latest 내용 digest 고정)
  • vllm@0.0.11 vllm-openai → vllm/vllm-openai:v0.24.0

digest 고정은 재현성을 보장하지만 자동 보안 패치는 멈춘다. → 정기 스캔으로 새 CVE 를 감지하고 필요 시 digest 를 갱신한다. bitnamilegacy/* 는 미유지 이미지이므로 중기적으로 legacy 탈피(대체 이미지)를 검토한다.