SBOM
포털은 가장 최근 성공 스캔으로부터 Software Bill of Materials(SBOM) 산출물을 생성합니다. 4가지 교환 포맷과 attribution NOTICE 파일을 지원합니다.
이 페이지는 TRUSCA가 스캔으로부터 생성한 SBOM을 내보내는(export) 방법을 다룹니다. 반대로 고객 도구가 이미 만든 SBOM(CycloneDX 또는 SPDX)을 업로드해 TRUSCA가 CVE를 매칭하고 적합성을 채점하게 하려면 SBOM 업로드와 스캔 → SBOM 업로드을 참고하세요.

릴리스를 출고하는 엔지니어, 산출물을 제출하는 컴플라이언스 리드, EO 14028에 따라 SBOM 요청을 처리하는 고객. 팀 멤버십 기반 읽기 권한.
지원 포맷
| 포맷 | 쿼리 값 (format=) | MIME | 사용 사례 |
|---|---|---|---|
| CycloneDX 1.6 (JSON) | cyclonedx-json | application/vnd.cyclonedx+json | SCA 도구의 사실상 표준. VEX 포함. |
| CycloneDX 1.6 (XML) | cyclonedx-xml | application/vnd.cyclonedx+xml | 동일 데이터; 레거시 도구를 위한 XML. |
| SPDX 2.3 (JSON) | spdx-json | application/spdx+json | NTIA 최소 요소; 규제 산업에서 폭넓게 수용. |
| SPDX 2.3 (Tag-Value) | spdx-tv | text/spdx | 원래의 SPDX 라인 기반 포맷. |
두 포맷 모두 동일한 내부 모델에서 생성되므로 컴포넌트 목록은 (포맷별 필드 제외) 동일합니다.
컴포넌트별 포함 내용
각 컴포넌트는 이름, 버전, 패키지 URL(PURL), 그리고 탐지된 라이선스를 담습니다.
- 라이선스 — 스캔의 라이선스 finding에서 채웁니다. CycloneDX는 컴포넌트
licenses배열을 사용하고(concluded → declared → detected 우선순위), SPDX는licenseDeclared·licenseConcluded를 SPDX license expression으로 채웁니다. 탐지된 라이선스가 없거나 SPDX 식별자가 없는 라이선스(ORTLicenseRef-*)는 SPDX에서 스펙 sentinelNOASSERTION으로 출력됩니다 (CycloneDX는 라이선스 이름을 그대로 담음).copyrightText는 현재 항상NOASSERTION입니다. - 최상위 버전 —
metadata.component.version은 스캔된 릴리스를 반영합니다. 스캔 제출 시release라벨(예:v1.2.3)이 지정됐으면 그 값을, 없으면 스캔 id를 안정적 fallback으로 사용합니다.
Byte-stable 출력
4가지 내보내기 모두 byte-stable입니다 — 같은 스캔을 다시 내보내면 동일 바이트가 생성됩니다. diff·서명·캐싱이 단순해집니다.
byte-stability 달성 방법:
- 컴포넌트를
purl(사전식)로 정렬. - 각 컴포넌트 내 라이선스 표현을 알파벳순 정렬.
serialNumber(CycloneDX) /documentNamespace(SPDX)를(project_id, scan_id)기반 결정적 값으로 고정.- 본문에서 타임스탬프를 제외(SBOM 메타데이터에는 스캔 종료 시각이 기록되며 스캔당 안정적).
UI에서 다운로드
- 프로젝트 열기.
- SBOM 탭 클릭.
- 4개 포맷 버튼 중 하나(CycloneDX JSON, CycloneDX XML, SPDX JSON, SPDX Tag-Value)를 클릭하여 다운로드.

파일명은 sbom-<project-slug>.<ext>.
API에서 다운로드
API는 SBOM을 CycloneDX JSON으로 제공합니다:
…그리고 SPDX JSON으로도 제공합니다(같은 엔드포인트, format만 다름):
# CycloneDX JSON
curl -sS -L -OJ \
-H "Authorization: Bearer ${TRUSTEDOSS_API_KEY}" \
"https://trustedoss.example.com/v1/projects/${PROJECT_ID}/sbom?format=cyclonedx-json"
# SPDX JSON
curl -sS -L -OJ \
-H "Authorization: Bearer ${TRUSTEDOSS_API_KEY}" \
"https://trustedoss.example.com/v1/projects/${PROJECT_ID}/sbom?format=spdx-json"
format 허용값: cyclonedx-json, cyclonedx-xml, spdx-json, spdx-tv.
엔드포인트는 항상 가장 최근에 성공한 스캔(latest succeeded) 의 SBOM을 내보냅니다. 특정 과거 스캔 ID로 고정하는 기능은 로드맵 항목입니다.
SBOM 내보내기는 항상 최신 성공 스캔을 반영합니다. 외부 감사관은 보통 특정 릴리스 시점의 SBOM 을 요청합니다(예: "2026-01-15 에 출고된 것은 무엇인가?"). 과거 스캔 고정() 이 적용되기 전까지는 각 릴리스 경계에서 SBOM 산출물을 캡처하여 릴리스 아카이브에 보관하세요. 포털은 현재 SBOM 으로 다루되 과거 SBOM 의 출처로 보지 마세요.
정책 프로파일
기본 내보내기는 가공하지 않은 컴포넌트 목록입니다. 선택적 정책 프로파일은 팀의 라이선스 정책을 내보내기에 적용해, 배포용 SBOM이 조직의 기준을 반영하게 합니다.
- 정책 주석(policy annotated) — 위반 컴포넌트를 제거하지 않고 그 자리에
표시합니다. CycloneDX 컴포넌트에는
trusca:policy:category/trusca:policy:spdxproperties가, SPDX 패키지에는REVIEWannotation이 추가됩니다. 금지뿐 아니라 조건부 컴포넌트도 함께 표시되므로, 검토자가 SBOM 안에서 각 컴포넌트가 왜 문제인지 바로 볼 수 있습니다. - 정책 필터(policy filtered) — 금지 컴포넌트를 내보내기에서 제외하고
(그 컴포넌트를 참조하던 취약점 항목도 함께 제거), 제외한 개수를 문서에
기록합니다(
trusca:policy:excluded_count또는 문서 annotation).
팀·조직 정책이 설정돼 있지 않으면 내장 분류 카탈로그로 대체 판정하므로, 금지 GPL은 그래도 표시됩니다.
SBOM 탭에서 프로파일을 선택하거나 API에 profile을 전달합니다.
curl -sS -L -OJ \
-H "Authorization: Bearer ${TRUSTEDOSS_API_KEY}" \
"https://trustedoss.example.com/v1/projects/${PROJECT_ID}/sbom?format=cyclonedx-json&profile=policy-annotated"
profile 허용값: policy-annotated, policy-filtered. 프로파일 내보내기는
파일명이 구분되게 지정되어(sbom-<project>-<profile>.<ext>) 표준 내보내기와
혼동되지 않습니다.
cosign 서명은 기본 SBOM —
스캔 시점에 생성된 정확한 바이트 — 에만 적용됩니다. 정책 프로파일은 요청 시점에
생성되므로 서명이 없으며, 프로파일 내보내기에 대해 cosign verify-blob을
실행하면 실패합니다. 검증 가능한 서명 산출물이 필요하면 기본 내보내기를 쓰고,
프로파일 내보내기는 검토·배포용 편의로 취급하십시오.
NOTICE 파일
Apache-2.0 §4(d)와 유사한 attribution 의무 이행을 위해 포털은 프로젝트 최신 스캔으로부터 NOTICE attribution 본문을 자동 생성합니다.
파일 내용:
- 프로젝트 이름과 생성 타임스탬프 헤더.
- 검출된 라이선스별 섹션 하나씩 — 해당 라이선스의 컴포넌트(
name @ version) 목록과 컴포넌트별 저작권 라인 포함. - 각 라이선스 섹션의 attribution 의무(예: attribution, no-endorsement)와 짧은 설명, 정책 참조 링크.
- 문서 말미의 License Texts 섹션 — 프로젝트에 등장한 모든 라이선스의 전문 수록.
- 라이선스에 AI 특화 제약 플래그(행동 사용 또는 비상업)가 붙은 컴포넌트를 나열하는 License review needed 섹션 — AI 라이선스 검토 플래그 참고.
저작권 라인
각 컴포넌트 항목에는 스캔 SBOM에 기록된 저작권 문구가 표시됩니다(cdxgen이 패키 지
메타데이터에서 읽어 옵니다). SBOM에 저작권자가 기록되지 않았으면 라인을 공란으로
두지 않고, 저작권자가 수록되지 않았다는 안내와 함께 컴포넌트의 레지스트리 URL을
대신 표시합니다 — 원 소스에서 저작권 문구를 확인할 수 있습니다. 컴포넌트 드로어의
수동 오버라이드는 로드맵에 있습니다.
라이선스 전문
문서는 프로젝트에 등장한 각 라이선스의 정식 전문을 담은 License Texts 섹션으로
끝납니다. 포털은 잘 알려진 32종 라이선스의 SPDX(Software Package Data Exchange)
전문을 번들로 포함합니다 — MIT, Apache-2.0, 그리고 BSD·GPL·LGPL·AGPL·MPL·EPL·CDDL
계열 등. 전문이 번들에 없는 라이선스는 조용히 누락되지 않고 정식 전문으로 연결되는
reference URL 링크로 대체됩니다. 이 섹션 덕분에 NOTICE 산출물 자체가 카탈로그의
license_text_inclusion_required 의무를 충족합니다 —
의무사항 카탈로그 참고.
지원 포맷
NOTICE 엔드포인트는 format 쿼리 값을 받습니다(기본 text).
| 포맷 | 쿼리 값 (format=) | MIME | 확장자 | 사용 사례 |
|---|---|---|---|---|
| 일반 텍스트 | text | text/plain | .txt | 릴리스 tarball의 NOTICE 파일로 그대로 사용. 기본값. |
| Markdown | markdown | text/markdown | .md | 문서 사이트나 PR 설명에 렌더링. |
| HTML | html | text/html | .html | attribution 페이지용 self-contained 문서(인라인 <style>, 스크립트 없음). |
출력은 동일 스캔·동일 포맷에 대해 내보내기 간 byte-stable이며 릴리스 간 diff가 가능합니다.
다운로드
-
UI: 프로젝트 → Obligations 탭 → 포맷 선택(text 또는 HTML) → Download NOTICE. 브라우저가
NOTICE-<project>.<ext>로 저장합니다. markdown 변형은 API에서 제공됩니다. -
API:
# 일반 텍스트(기본)curl -sS -L -OJ \-H "Authorization: Bearer ${TRUSTEDOSS_API_KEY}" \"https://trustedoss.example.com/v1/projects/${PROJECT_ID}/notice?format=text&download=true"# HTMLcurl -sS -L -OJ \-H "Authorization: Bearer ${TRUSTEDOSS_API_KEY}" \"https://trustedoss.example.com/v1/projects/${PROJECT_ID}/notice?format=html&download=true"format허용값:text,markdown,html.download=true를 전달하면 응답에Content-Disposition: attachment가 설정되고-OJ가 서버 제공 파일명(NOTICE-<project>.<ext>)으로 저장합니다. 생략하면 본문을 인라인으로 스트리밍합니다.
VEX 내보내기
CycloneDX SBOM은 모든 결과의 프로젝트 VEX 상태를 포함합니다. SPDX는 native VEX 표현이 없으므로 SPDX 내보내기는 결과별 상태를 생략합니다. 다운스트림 소비자가 기대하면 SPDX 내보내기와 별도 CycloneDX VEX 문서를 함께 제공하세요.
SBOM의 vulnerabilities[] 배열 각 항목은 CVE id, 출처 데이터베이스, VEX 분석,
그리고 같은 문서 안에서 영향받는 컴포넌트의 bom-ref를 가리키는 affects[].ref를
담습니다(소비자가 PURL을 파싱하지 않고도 결과와 컴포넌트를 연결할 수 있습니다).
VEX 상태는 CycloneDX analysis.state로 매핑되고, 분석가의 자유 텍스트 노트(있는
경우)는 analysis.detail에 담깁니다:
| 포털 상태 | CycloneDX VEX state | analysis.detail |
|---|---|---|
New | in_triage | (없음) |
Analyzing | in_triage | 분석가 노트 |
Exploitable | exploitable | 분석가 노트 |
Not affected | not_affected | 분석가 노트 |
False positive | false_positive | 분석가 노트 |
Suppressed | not_affected | 분석가 노트 |
Fixed | resolved | 분석가 노트 |
닫힌 CycloneDX analysis.justification enum(code_not_present 등)은 절대
내보내지 않습니다. 이 enum의 항목은 자유 형식의 분석가 서술로는 추론할 수 없는
정밀한 의미를 가지므로, 노트는 analysis.detail에 유지됩니다.