공급사 SBOM 검증 가이드¶
협력사나 다른 팀에서 받은 SBOM(JSON)이 요구사항을 충족하는지 검증하는 방법을 설명합니다. 검증에 이어 라이선스와 취약점을 분석하고, 위험 보고서까지 만듭니다. 소스 코드가 없어도 SBOM 파일 하나만 있으면 됩니다.
언제 쓰나¶
협력사나 다른 팀이 소스 대신 SBOM 파일을 전달했고, 그 SBOM이 품질 기준을 갖췄는지 확인한 뒤 라이선스와 취약점을 점검해야 할 때 씁니다. 입력은 CycloneDX와 SPDX(JSON, Tag-Value) 모두 가능하며, 내부에서 CycloneDX로 변환해 분석합니다.
검증 기준은 SBOM이 의존성 점검에 쓸 만한 품질을 갖췄는지를 보는 항목들입니다. 조직마다 요구사항이 다를 수 있으니, 참고 사례로 SK텔레콤 공급망 보안 가이드의 SBOM 요구사항을 둘 수 있습니다.
| 구분 | 기준 |
|---|---|
| 포맷 | CycloneDX v1.3~1.6 또는 SPDX v2.2~2.3 |
| 필수 메타데이터 | timestamp, 생성 도구 정보, 최상위 컴포넌트 이름과 버전 |
| 필수 컴포넌트 필드 | name, version, 표준 pkg:type/name@version 형식의 PURL(pkg:generic 금지) |
| 완전성 | 직접 의존성과 추이적(transitive) 의존성 모두 포함 |
| 권장 | supplier, 라이선스(SPDX ID), hash |
위 허용 포맷 범위는 SK텔레콤 제출 기준의 기본값입니다. 조직이 다른 범위를 허용한다면
CYCLONEDX_SPEC_VERSIONS,AI_CYCLONEDX_SPEC_VERSIONS(AI SBOM),SPDX_SPEC_VERSIONS환경 변수(공백으로 구분한 목록)로 덮어쓸 수 있습니다. 목록은 Docker 이미지 환경 변수에 있습니다.
한 번에 실행하기¶
웹 UI에서¶
웹 UI를 열고 SBOM 업로드를 골라 받은 파일을 올린 뒤, 프로젝트 이름과 버전을 입력하고 스캔을 실행합니다. Yocto SPDX 2.2 빌드는 문서가 아니라 <image>.spdx.tar.zst를 건네는데, 그 빌드가 만드는 유일한 SBOM이므로 이 아카이브도 그대로 올릴 수 있습니다.
Java(Maven) 비중이 큰 SBOM이라면 스캔 옵션에서 심층 CVE 매칭 (maven, NVD)을 켜세요. 오래된 Maven 라이브러리를 NVD 전용 취약점까지 대조해 다른 출처가 놓치는 항목을 찾아내며, 대신 스캔이 더 오래 걸립니다. 이 옵션은 SBOM 업로드에서만 나타나고, 처음 실행할 때 deep-cve 이미지를 한 번 내려받습니다. CLI의 --deep-cve와 같은 매칭입니다.
설치는 시작하기를 참고하세요.
CLI에서¶
스캐너 이미지를 한 번 받아 두고(docker pull ghcr.io/sktelecom/bomlens:latest), 받은 SBOM 파일을 --analyze에 넘깁니다.
./scripts/scan-sbom.sh --project supplier-app --version 2.0.0 \
--analyze "./supplier-sbom.json" \
--generate-only
--analyze는 고지문과 보안 분석을 자동으로 켜므로 --all을 따로 붙일 필요가 없습니다. --generate-only는 산출물만 현재 디렉터리 아래 {Project}_{Version}/ 하위 폴더에 남기고 임시 작업본은 정리합니다. 나머지 옵션은 CLI 레퍼런스를 참고하세요.
산출물 4종¶
| 산출물 | 파일 | 의미 |
|---|---|---|
| 적합성 보고서 | {Project}_{Version}_conformance.{json,md,html} |
품질 기준 충족 여부와 누락 항목 |
| SBOM(변환본) | {Project}_{Version}_bom.json |
SPDX 입력은 CycloneDX 1.6으로 변환, CycloneDX 입력은 원본 spec 버전 유지 |
| 오픈소스 고지문 | {Project}_{Version}_NOTICE.{txt,html} |
라이선스별 구성요소 고지문 |
| 위험분석보고서 | {Project}_{Version}_risk-report.{md,html} |
적합성·취약점·라이선스 종합과 대응 기한 |
자체 생성 SBOM과 달리, 받은 SBOM에는 적합성 보고서가 추가로 생성되고 위험분석보고서 1절에 그 요약이 들어갑니다.
적합성 보고서 읽기¶
적합성 보고서는 받은 SBOM이 품질 기준을 갖췄는지 항목별로 점검한 결과입니다. 검증은 변환 전 원본을 기준으로 하므로, SPDX를 넣어도 원본 SPDX의 필드를 그대로 확인합니다.
- 필수 항목이 하나라도 미달이면
fail입니다. 필수 항목은 언제 쓰나의 기준 표와 같습니다 — 스펙 버전 범위(CycloneDX v1.3~1.6, SPDX v2.2~2.3), timestamp, 도구 정보, 최상위 컴포넌트, name/version 커버리지, PURL 커버리지와 문법(표준pkg:type/name@version형식,pkg:generic금지), 추이적 의존성. AI SBOM은 AIBOM 도구가 산출하는 CycloneDX 1.7도 허용합니다. - 권장 항목이 미달이면
warn이며,fail로 보지는 않습니다. 라이선스와 hash 커버리지 외에, 규제 기준선이 요구하는 컴포넌트별 권고 필드도 여기에 포함됩니다 — SHA-512 체크섬 커버리지, 컴포넌트 작성 주체, 컴포넌트 파일명, 소스·배포 URI, 전달 파일 속성(스캔으로 확인할 수 없으면 검토 필요로 표시). - HTML 보고서 상단 카드에 적합/부적합과 누락 목록이 표시됩니다.
- 규제 기준선과 대응되는 검사에는 행 아래에 참고 규정이 붙고, 크로스워크 절이 프레임워크별 충족 현황을 집계합니다 — BSI TR-03183-2(EU 사이버복원력법을 위한 독일 기술지침)와 미국 NTIA 최소 요소입니다. 크로스워크는 참고 자료이며 준수 판정을 하지 않습니다. 동작 방식은 AI 모델 SBOM 가이드에서 설명합니다.
fail이 나오면 SBOM을 보낸 쪽에 어떤 필드가 빠졌는지 알려 보완을 요청합니다. 가장 흔한 미충족 항목은 PURL 누락, pkg:generic 사용, 추이적 의존성 누락(직접 의존성만 포함)입니다.
위험분석보고서 읽기¶
위험분석보고서(_risk-report)는 새로 스캔하지 않고 위의 산출물을 재집계해 만든 문서입니다. 네 부분으로 구성됩니다.
- 요구사항 충족 — 적합성 결과 표.
fail이면 미충족 항목을 명시합니다. - 취약점 집계와 대응 기한 — 심각도별 집계와 함께 권고 대응 기한(Critical 7일, High 30일 이내 대응 계획이나 위험 정당화 마련)을 표로 정리합니다.
- 라이선스 요약 — 고지문과 라이선스 커버리지.
- 다음 단계 — 대응 계획 안내.
SPDX 입력¶
SPDX(JSON, Tag-Value)를 넣으면 내부에서 syft convert로 CycloneDX로 바꾼 뒤 동일한 파이프라인으로 분석합니다. 적합성 검증은 변환 전 SPDX 원본을 기준으로 합니다. 변환 과정에서 timestamp나 도구, 추이적 의존성 같은 메타데이터가 정규화되거나 사라질 수 있기 때문입니다. SPDX의 라이선스 표현 일부는 CycloneDX로 옮기면서 단순화될 수 있습니다.
Yocto 이미지¶
Yocto 빌드는 자체 SPDX SBOM을 만들 수 있고, BomLens는 이를 일반 SPDX 경로가 아니라 전용 파서로 읽습니다. Yocto 문서에는 일반 경로가 잃어버리는 정보가 두 가지 들어 있기 때문입니다.
SBOM을 만들려면 local.conf에 다음을 넣고 평소대로 빌드합니다.
어떤 SPDX 버전을 만들 수 있는지는 릴리스마다 다릅니다.
| 릴리스 | 기본 SPDX | create-spdx-3.0 사용 |
|---|---|---|
| 4.0 Kirkstone (LTS) | 2.2 | 불가 — 이 릴리스에는 해당 클래스가 없습니다 |
| 5.0 Scarthgap (LTS) | 2.2 | 가능 |
| 5.1 Styhead 이후 | 3.0 | 가능(기본값) |
Kirkstone에서는 위 설정을 쓸 수 없습니다. 그 빌드는 SPDX 2.2를 만들고, 아래에 적은 방식으로 읽습니다.
그다음 빌드 디렉터리를 그대로 스캔 대상으로 지정합니다. 빌드가 SBOM을 어디에 두었는지 알 필요가 없습니다.
빌드 디렉터리로 인식하고, 빌드가 만든 이미지 SBOM인 tmp/deploy/images/<machine>/<image>.rootfs.spdx.json(OpenEmbedded 빌드는 tmp-glibc/…)을 분석합니다. 빌드 트리 자체는 훑지 않습니다. 디렉터리로 스캔하면 이미지에 들어가지 않는 sysroot와 빌드용 도구까지 결과에 섞이기 때문입니다.
머신이나 이미지를 여럿 빌드해 SBOM이 여러 개면 가장 최근에 쓰인 것을 분석하고 후보 전체를 로그에 남깁니다. 다른 것을 고르려면 --analyze <파일>로 직접 지정합니다. DEPLOY_DIR를 옮겨 이미지를 완전히 다른 위치에 쓰는 빌드도 이 방법으로는 찾지 못하니 같은 방식으로 지정합니다. SBOM 파일 하나만 받은 경우에는 그 파일을 웹 UI에 올리거나 --analyze로 넘기면 됩니다.
웹 UI도 같은 폴더를 읽습니다. 디렉터리 입력으로 그 폴더를 고르면 됩니다(--ui --mount ~/poky/build로 먼저 마운트하거나 데스크톱 앱의 폴더 추가 사용). 감지는 명령줄과 똑같이 동작합니다.
SPDX를 전혀 만들지 않은 빌드¶
create-spdx를 켜는 것은 빌드 설정을 바꾸는 일이라, 완료된 빌드 디렉터리만 가진 사람은 그렇게 하지 못할 수 있습니다. 빌드는 SPDX가 없어도 무엇을 넣었는지 기록해 두므로, 그 기록을 대신 읽습니다.
| 파일 | 위치 | 얻는 정보 |
|---|---|---|
| 이미지 패키지 매니페스트 | tmp/deploy/images/<machine>/<image>.manifest |
설치된 패키지와 버전 |
| 라이선스 매니페스트 | tmp/deploy/licenses/**/license.manifest |
패키지별 라이선스와 출처 레시피 |
| cve-check 보고서 | tmp/log/cve/cve-summary.json |
CVE별로 레시피가 패치했는지, 해당 없다고 판정했는지, 남았는지 |
세 가지 입력 중 가장 약한 경로이며, 이유를 알아 둘 만합니다. CPE가 없어 취약점 매칭이 패키지 이름과 버전에만 기댑니다. CVE 판정도 그 빌드가 실행한 cve-check 범위까지만 정확합니다(cve-check를 돌리지 않은 빌드는 판정이 없다고 보고하며, 없는 판정을 지어내지 않습니다). 적합성 보고서도 만들지 않습니다. 적합성은 누군가 보낸 문서를 제출 기준과 대조하는 것인데 여기에는 그 문서가 없기 때문입니다. 위의 local.conf 두 줄을 넣고 다시 빌드하는 편이 여전히 낫습니다.
Yocto 빌드 디렉터리인데 SPDX 문서도 이미지 매니페스트도 없으면 디렉터리 스캔으로 넘어가지 않고 스캔을 멈춘 뒤 위 설정 두 줄을 안내합니다. 그대로 스캔하면 이미지 내용과 다른 결과가 나오기 때문입니다.
일반 SBOM 스캔과 결과가 두 가지 면에서 다릅니다.
구성 목록에는 이미지에 설치된 패키지만 담깁니다. Yocto 문서에는 빌드가 사용한 소스 압축 파일도 전부 기록되는데, 출처를 따질 때는 쓸모가 있지만 제품에 실제로 들어간 것과는 다릅니다. 그래서 목록에서 뺍니다.
취약점은 빌드가 판정한 결과를 그대로 씁니다. Yocto는 빌드하면서 CVE 분석을 돌리고 항목마다 판정을 기록하므로 레시피가 패치를 적용했는지 압니다. 그 판정을 빌드에서 패치한 것, 해당 없다고 판정한 것, 아직 남은 것 세 가지로 나눠 보여주고 남은 것만 발견 항목으로 셉니다. 기준 이미지인 core-image-minimal에서는 이 차이가 취약점 12255건을 보고하느냐 한 건도 없다고 보고하느냐를 가릅니다. 전부 빌드에서 이미 닫혔기 때문입니다.
시작하기 전에 알아 둘 한계가 두 가지 있습니다.
SPDX 2.2도 읽지만 담기는 정보가 적습니다. Yocto 4.0 Kirkstone과 5.0 Scarthgap은 기본값이 SPDX 2.2인데, 이 형식은 문서 하나가 아닙니다. deploy 디렉터리에는 <image>.spdx.tar.zst 하나만 놓이고, 그 안에 이미지 문서와 설치 패키지별 문서, 레시피별 문서가 들어 있습니다. BomLens는 이 아카이브를 직접 읽습니다. 공개된 Yocto 5.0.14 core-image-minimal로 확인한 결과, 이미지 매니페스트가 나열한 36개 패키지를 라이선스와 CPE까지 그대로 얻었습니다.
없는 것은 빌드의 CVE 판정입니다. 레시피가 어떤 CVE를 패치했는지는 SPDX 3.0에만 기록되므로, 취약점은 다른 SBOM과 마찬가지로 CPE로 매칭합니다. 그래서 빌드가 이미 패치한 CVE가 열린 것으로 보일 수 있습니다. 아카이브에서 이미지 문서만 꺼내 따로 올리면 결과가 거의 비는데, 이때는 깨끗한 스캔처럼 보이게 두지 않고 그 사실을 알려 줍니다. 빌드 디렉터리에 두 형식이 함께 있으면 2.2 쪽이 더 최근이더라도 SPDX 3.0 문서를 분석합니다. 적합성 보고서는 이 경우 만들지 않습니다. 아카이브는 제출된 문서가 아니라 문서 묶음이라, 제출 기준과 대조할 대상이 아니기 때문입니다.
PURL에 기대는 적합성 항목은 실패합니다. Yocto는 패키지를 PURL이 아니라 CPE로 식별하므로 PURL 적용률과 거기서 파생되는 항목은 통과할 수 없습니다. 보고서에는 몇 개가 CPE로 식별됐는지 함께 적히고, 그 행 아래에 두 식별자를 모두 인정하는 기준(BSI TR-03183-2, NTIA 최소 요소)이 표시됩니다. 즉 이 판정은 기준이 아니라 제출 요구사항의 것입니다. 기본 취약점 매칭이 PURL을 키로 쓰기 때문에 여기서는 PURL을 요구합니다.
필수 항목 하나가 더 실패하는데, 도구가 아니라 문서 쪽 사정입니다. 최상위 컴포넌트가 버전이 없어 실패합니다. bitbake가 이미지 패키지에 이름만 쓰고 software_packageVersion을 넣지 않습니다(기준 이미지 core-image-minimal에서 확인).
업로드 크기는 100MB까지 받습니다. 참고로 기준 이미지인 core-image-minimal 문서는 설치 패키지 35개에 15.8MB입니다. --target으로 빌드 디렉터리를 스캔할 때는 디스크에서 파일을 읽으므로 이 제한이 적용되지 않습니다.
보완 요청하기¶
검증과 분석이 끝나면 위험분석보고서(_risk-report.html)를 SBOM을 보낸 쪽에 전달하고 다음을 요청합니다.
- 적합성
fail항목 보완 후 SBOM 재전달. - Critical 취약점은 7일, High 취약점은 30일 이내에 대응 계획이나 위험 정당화 마련(권고 대응 기한).
대응 추적, 예외 승인, 이력 관리는 이 도구의 범위가 아니라 별도의 취약점·위험 관리 시스템의 몫입니다. 이 도구는 로컬에서 단일 SBOM을 검증하고 분석해 보고서를 만드는 데까지 담당합니다.
한계¶
- 검증은 필수 필드의 존재와 커버리지를 기준으로 합니다. PURL이 실제 패키지를 정확히 가리키는지, 버전이 진짜인지 같은 의미적 정확성까지는 보장하지 못합니다.
- 추이적 의존성 포함 여부는 의존성 그래프의 edge 유무로 추정하며, 그래프가 완전하다는 증명은 아닙니다.
- 취약점과 라이선스 분석의 정확도는 입력 SBOM의 품질, 특히 PURL과 버전 정확성에 직접 좌우됩니다.
관련 문서: 시작하기 | 시나리오 가이드 | 고지문·보안 보고서 가이드