본문으로 건너뛰기

SBOM 생성: syft와 cdxgen으로 소프트웨어 구성 명세 만들기

1. 이 챕터에서 하는 일

이 챕터에서는 syft와 cdxgen을 사용해 프로젝트의 CycloneDX 형식 SBOM(Software Bill of Materials)을 생성합니다. 두 도구 모두 Docker로 실행하므로 별도 설치가 필요 없으며, 명령어 몇 줄로 프로젝트의 전체 의존성 목록을 JSON 파일로 만들 수 있습니다.

생성된 SBOM은 이후 라이선스 분석(05-sbom-analyst)과 취약점 스캔(05-vulnerability-analyst)의 기반이 됩니다. SBOM이 정확할수록 컴플라이언스 리스크와 보안 취약점을 빠짐없이 파악할 수 있습니다.

SBOM · 취약점 분석 · SCA의 관계

SBOM(소프트웨어 부품 명세서)은 입력, 취약점 분석은 그 SBOM으로 위험을 찾는 산출 단계입니다. 이 둘을 CI에서 자동으로 묶어 돌리는 것이 SCA(소프트웨어 구성 분석)입니다 — 자동화는 DevSecOps → SCA에서 다룹니다.


2. 배경 지식

SBOM·CycloneDX·SPDX 등 낯선 약어는 용어집에서 쉬운 설명을 볼 수 있습니다.

ISO/IEC 5230과 18974 모두 SBOM 생성을 핵심 요구사항으로 규정합니다(G3B.1). SBOM이 무엇이고 왜 필요한지는 SBOM 기본: 소프트웨어 부품 명세서 입문에서 다룹니다. 이 챕터는 그 SBOM을 실제로 만드는 도구와 명령을 다룹니다.

사용 도구 소개

SBOM 생성에는 두 가지 접근 방식이 있습니다. Dependency 분석은 패키지 매니저 파일(pom.xml, package-lock.json 등)을 기반으로 선언된 의존성을 파악하고, 소스 코드 스캔은 코드 내에 직접 내장된 오픈소스를 파일 레벨에서 탐지합니다. 두 방식을 병행하면 패키지 선언 없이 복사·삽입된 코드 조각까지 포함한 더 완전한 SBOM을 만들 수 있습니다.

Dependency 분석 도구 (이 챕터에서 실습)

도구제작사특징적합한 상황
syftAnchore빠르고 가볍다, 단일 바이너리, 다양한 언어 지원Python, Node.js, Go
cdxgenCycloneDXCycloneDX 전용, 언어별 정밀 분석Java(Maven/Gradle), 정밀 분석 필요 시

두 도구 모두 CycloneDX JSON 형식으로 출력할 수 있으며, 이 챕터에서는 CycloneDX를 표준 포맷으로 사용합니다.

소스 코드 스캔 도구 (선택 사항)

도구운영주체특징적합한 상황
SCANOSSSCANOSS파일 단위 스니펫 스캔, 클라우드+온프레미스, API 통합, SBOM 생성소스 코드 직접 임베딩 탐지, 정밀 라이선스 식별

SCANOSS는 패키지 선언 없이 직접 복사·삽입된 오픈소스 코드 조각을 파일 레벨에서 탐지하는 데 강점이 있습니다. syft/cdxgen과 역할이 보완적이므로, 소스 레벨 정밀도가 필요한 경우 병행 사용을 권장합니다.

국내 통합 옵션 — BomLens (SK텔레콤)

여러 언어와 분석 대상을 한 번에 처리해야 한다면 BomLens가 편리합니다. 소스, 컨테이너 이미지, 바이너리와 RootFS, 펌웨어는 물론 이미 받은 SBOM 재평가와 HuggingFace 모델(ML-BOM)까지 입력으로 받아, CycloneDX SBOM과 고지문(NOTICE), 라이선스·보안 위험 리포트를 함께 만들어 줍니다. 내부적으로 syft, cdxgen, Trivy 를 래핑한 Apache-2.0 도구이고, 전 과정이 로컬(Docker)에서 실행되어 외부 전송이 없습니다. CLI 외에 웹 UI와 데스크톱 설치본도 제공합니다. 이 챕터의 메인 도구는 syft로 두고, 통합 실행이 필요할 때 대안으로 고려하세요.

FOSSLight, SW360, FOSSology 등 SCA·컴플라이언스 도구의 도입 및 활용 가이드는 KWG 오픈소스 가이드 — 도구를 참조하세요.

실제 Docker 실행 명령어, GitHub Actions CI/CD 설정, 샘플 프로젝트 실습은 Docker·CI/CD 실행 가이드 페이지를 참조합니다.

CycloneDX JSON 형식 주요 필드

JSON
{
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:1b2f3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"metadata": {
"timestamp": "2026-08-20T09:30:00Z",
"lifecycles": [{"phase": "build"}],
"tools": {
"components": [
{
"type": "application",
"author": "anchore",
"name": "syft",
"version": "1.51.1"
}
]
},
"component": {
"name": "my-app",
"version": "1.0.0",
"type": "application"
}
},
"components": [
{
"type": "library",
"name": "log4j-core",
"version": "2.14.1",
"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1",
"supplier": {"name": "Apache Software Foundation"},
"hashes": [
{
"alg": "SHA-256",
"content": "3a5f1b9f2c7d4e8a1b0c6d5e4f3a2b1c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a"
}
],
"licenses": [{"license": {"id": "Apache-2.0"}}]
}
]
}

주요 필드 설명:

필드설명
bomFormat, specVersionCycloneDX 포맷 식별자와 사양 버전. cdxgen 12.x 와 syft 1.51 이상이 1.7 을 기본으로 냅니다
metadata.timestampSBOM 생성 시각
metadata.tools.components[]SBOM을 만든 도구의 이름과 버전. CISA 2026 최소 요소의 "SBOM 생성 도구명"에 해당합니다
metadata.lifecycles[]SBOM을 만든 수명주기 단계. "생성 맥락"에 해당합니다
metadata.component분석 대상 소프트웨어 정보
components[].supplier컴포넌트 공급자
components[].hashes[]컴포넌트 파일의 해시. alg(SHA-256 등)와 content(16진수 값) 쌍으로 무결성을 확인합니다
components[].licenses[]컴포넌트 라이선스
components[].purlPURL(Package URL, 패키지를 고유하게 식별하는 표준 문자열)
signatureBOM 최상위의 서명 필드. JSON Signature Format(JSF)으로 SBOM 자체의 위·변조를 확인합니다
vulnerabilities[]취약점 정보 (있을 경우)

해시, 생성 도구명, 생성 맥락, 라이선스는 SBOM 기본: 소프트웨어 부품 명세서 입문의 CISA 2026 최소 요소에서 새로 필수가 되었거나 핵심 필드로 올라온 항목입니다. 실제로 어떤 필드가 채워지는지는 도구와 생태계에 따라 다릅니다.

필드syftcdxgen
metadata.tools채움 (name syft, author anchore)채움
metadata.lifecycles채우지 않음채움 (pre-build, build, post-build 등 자동 판정)
components[].hashes패키지 컴포넌트에는 채우지 않음lock 파일이나 아카이브에서 해시를 얻을 수 있을 때 채움
signature별도 서명 필요 (in-toto 증명 방식 제공)--generate-key-and-sign 으로 JSF 서명 생성

수명주기 단계나 해시가 필요한데 syft 출력에 비어 있다면 같은 프로젝트를 cdxgen으로 한 번 더 생성해 비교하세요. 사양 버전을 명시하려면 syft는 -o cyclonedx-json@1.7, cdxgen은 --spec-version 1.7 을 씁니다.

도구 최소 버전을 먼저 확인하세요

CycloneDX 1.7 은 syft 1.51 이상에서만 나옵니다. 그보다 낮은 syft 는 1.6 까지만 지원해 -o cyclonedx-json@1.7 을 주면 unsupported output format 으로 실패합니다. 스캔에 쓰는 grype 도 1.7 을 읽으려면 0.118 이상이 필요합니다. 낮은 grype 에 1.7 SBOM 을 주면 sbom format not recognized 로 끝납니다. syft versiongrype version 으로 먼저 확인하세요.

MCP 서버도 SBOM 에 담을 수 있습니다

AI 에이전트가 호출하는 MCP(Model Context Protocol, 에이전트가 외부 도구를 호출하는 프로토콜) 서버를 SBOM 에 등재하는 방법은 에이전트와 MCP 도구 거버넌스에서 다룹니다. 표준 기구의 공식 지침이 없어 기존 명세를 해석해 적용하는 영역입니다.


3. 셀프 스터디

셀프스터디 모드 (약 1시간 30분)

처음 실행 시 Docker 이미지 풀링으로 10-15분 추가 소요될 수 있습니다.

단계별 실습:

단계 1 — Docker Desktop 실행 확인

Bash
docker ps

오류 없이 실행되면 Docker가 준비된 것입니다.

Docker 없이 진행하는 경우

Docker를 설치하지 않았거나 실습 목적으로 빠르게 진행하려면, 아래 명령어로 미리 준비된 샘플 SBOM을 사용합니다.

Bash
mkdir -p output/sbom
cp output-sample/sbom/fixture-sample.cdx.json output/sbom/fixture-sample.cdx.json

샘플 SBOM에는 GPL-2.0 Copyleft 컴포넌트와 CVE 취약점이 있는 패키지가 포함되어 있어 이후 분석 실습이 가능합니다. 이 경우 SBOM을 직접 생성하는 단계 4~6(sbom-guide agent·스크립트 실행)을 건너뛰고 바로 **단계 7(라이선스 분석 실행)**로 이동합니다.

단계 2 — 분석할 프로젝트 선택

본인의 프로젝트를 사용할 수도 있고, 샘플을 사용할 수도 있습니다.

처음이라면 아래 샘플 중 하나를 선택합니다.

샘플 경로언어특징학습 포인트
samples/java-vulnerable/Java (Maven)Log4Shell(CVE-2021-44228) 포함Critical 취약점 탐지 실습
samples/python-mixed-license/Python (pip)GPL + MIT 혼용Copyleft 라이선스 충돌 실습
samples/nodejs-unlicensed/Node.js (npm)라이선스 미표기 패키지라이선스 미식별 처리 실습
권장 샘플

samples/java-vulnerable/ — Log4Shell 취약점을 직접 탐지하며 SBOM의 가치를 체감할 수 있습니다.

단계 3 — 출력 폴더 생성

Bash
mkdir -p output/sbom

단계 4 — sbom-guide agent 실행

실행 전 확인

현재 Claude 세션을 먼저 종료(/exit 또는 Ctrl+C)한 뒤, 새 터미널에서 아래 명령을 실행하세요.

Bash
cd agents/05-sbom-guide
claude

agent가 프로젝트 정보를 묻는 3가지 질문을 합니다.

  • 프로젝트 경로 (예: samples/java-vulnerable)
  • 주 언어 (예: Java)
  • 패키지 매니저 (예: Maven)

단계 5 — 생성된 스크립트 실행

agent가 output/sbom/sbom-commands.sh를 생성하면, 레포 루트로 돌아와(cd ../..) 실행합니다. 단계 6 이후의 확인 명령도 모두 레포 루트 기준입니다.

Bash
cd ../..
bash output/sbom/sbom-commands.sh

단계 6 — SBOM 파일 존재 확인

Bash
ls -lh output/sbom/*.cdx.json

파일이 존재하고 크기가 0보다 크면 정상입니다. 이어서 최소 요소가 채워졌는지 확인합니다.

Bash
jq '{specVersion, timestamp: .metadata.timestamp, tool: .metadata.tools, lifecycles: .metadata.lifecycles, components: (.components | length), withHash: ([.components[] | select(.hashes)] | length), withLicense: ([.components[] | select(.licenses)] | length)}' output/sbom/*.cdx.json

specVersion, timestamp, tool, components 는 값이 있어야 합니다. lifecycleswithHash 는 위 도구별 비교표대로 syft 출력에서 비어 있을 수 있습니다. jq가 없으면 파일을 열어 같은 항목을 눈으로 확인합니다.

단계 7 — 라이선스 분석 실행

실행 전 확인

현재 Claude 세션을 먼저 종료(/exit 또는 Ctrl+C)한 뒤, 새 터미널에서 아래 명령을 실행하세요.

Bash
cd agents/05-sbom-analyst
claude

단계 8 — 분석 결과 확인

Bash
ls output/sbom/license-report.md output/sbom/copyleft-risk.md

막혔을 때:

output/sbom/[project].cdx.json이 비어있으면 lock 파일 존재 여부를 먼저 확인합니다 (package-lock.json, requirements.txt, pom.xml 등). lock 파일이 없으면 cdxgen으로 전환하여 재시도합니다.

Bash
docker run --rm \
-v "$(pwd)":/app \
-w /app \
ghcr.io/cyclonedx/cdxgen:latest \
-o /app/output/sbom/java-vulnerable-cdxgen.cdx.json \
/app/samples/java-vulnerable

각 단계 예상 결과:

단계 완료 후예상 결과
4번 (sbom-guide)output/sbom/sbom-commands.sh 생성됨
5번 (스크립트 실행)output/sbom/[project].cdx.json 생성됨 (components 항목 있어야 정상)
7번 (sbom-analyst)output/sbom/license-report.md, output/sbom/copyleft-risk.md 생성됨
충족되는 표준 요구사항

이 실습을 완료하면 아래 요구사항이 충족됩니다.

5230 §3.3.1, §3.3.2, §3.4.1 · 18974 §4.3.1

각 항목의 자체 인증 체크리스트 문항 원문과 입증자료는 요구사항 상세 대조표에 있습니다.


4. 완료 확인 체크리스트

아래 항목을 모두 확인한 후 다음 단계로 넘어갑니다.

  • output/sbom/[project].cdx.json 생성됨
  • SBOM 파일에 components 배열이 비어있지 않음
  • specVersion1.7 임 (낮은 값이면 syft 를 1.51 이상으로 올린 뒤 다시 생성)
  • metadata.timestampmetadata.tools 에 생성 시각과 생성 도구명이 기록됨
  • components[] 각 항목에 purl 이 있음
  • 컴포넌트 해시(hashes)와 라이선스(licenses) 상태를 확인함 (도구에 따라 비어 있을 수 있으며, 비어 있으면 cdxgen 출력과 비교)
  • 외부에 공유할 SBOM이면 서명 여부를 결정함
  • output/sbom/sbom-commands.sh 생성됨
  • output/sbom/license-report.md 생성됨
  • output/sbom/copyleft-risk.md 생성됨

java-vulnerable 샘플 실습 시 예상 결과:

  • log4j-core 2.14.1 컴포넌트 탐지 (syft 기준 components 4개)
  • CVE-2021-44228 (Log4Shell) 취약점 플래그 예상
  • 라이선스 식별: 도구 출력의 licenses 필드는 이 샘플처럼 패키지에 라이선스 선언이 없으면 비어 있을 수 있습니다. Apache-2.0 식별은 단계 7의 05-sbom-analyst가 보완해 license-report.md에 기록합니다.

이 단계는 ISO/IEC 5230 3.3.1, 3.3.2, 3.4.1 및 ISO/IEC 18974 4.3.1 요구사항을 충족합니다.

산출물 예시

SBOM 산출물 Best Practice에서 생성된 파일의 실제 형식을 확인할 수 있습니다.


5. 다음 단계

SBOM 생성과 라이선스 분석이 완료되면, SBOM 관리 체계를 수립하는 단계로 넘어갑니다.

실행 전 확인

현재 Claude 세션을 먼저 종료(/exit 또는 Ctrl+C)한 뒤, 새 터미널에서 아래 명령을 실행하세요.

Bash
cd agents/05-sbom-management
claude

또는 SBOM 관리: 만들고 끝이 아니라 관리가 시작이다로 이동하여 가이드를 확인합니다.

취약점 분석을 먼저 진행하려면:

실행 전 확인

현재 Claude 세션을 먼저 종료(/exit 또는 Ctrl+C)한 뒤, 새 터미널에서 아래 명령을 실행하세요.

Bash
cd agents/05-vulnerability-analyst
claude

완료 후 output/progress.md를 업데이트하여 진행 상황을 기록합니다.