고지문·보안·위험 보고서 생성¶
BomLens는 SBOM 생성에 더해 오픈소스 고지문(NOTICE)과 보안 취약점 보고서를 한 번에 만듭니다. 이 문서는 그 산출물을 생성하는 방법을 다룹니다. 읽고 해석하는 방법은 보고서 읽는 법을 참고하세요.
Quickstart (5분)¶
처음이라면 이것만 따라 하면 됩니다. Docker 엔진이 실행 중인 상태에서 SBOM과 고지문, 보안보고서를 한 번에 만듭니다. 브라우저로도, CLI로도 됩니다.
브라우저 UI (명령어 불필요)¶
UI를 실행하고 프로젝트 이름과 버전을 입력한 뒤 스캔 대상을 골라 실행하면, 고지문과 보안보고서를 내려받을 수 있습니다.
./scripts/scan-sbom.sh --ui # http://localhost:8080 (포트 충돌 시 UI_PORT=9090 ./scripts/scan-sbom.sh --ui)
# Windows: scripts\sbom-ui.bat 더블클릭
CLI¶
스캔할 프로젝트 폴더에서 실행합니다.
cd /path/to/your-project
/path/to/bomlens/scripts/scan-sbom.sh --project MyApp --version 1.0.0 --all --generate-only
Windows에서는 scripts\scan-sbom.bat(Git Bash)를 쓰거나 WSL2에서 그대로 실행합니다. 설치는 시작하기를 참고하세요.
끝나면 같은 폴더에 생긴 MyApp_1.0.0_NOTICE.html과 MyApp_1.0.0_security.html을 브라우저로 열어 결과를 바로 확인하세요. 더 자세한 옵션은 아래를 참고하세요.
사전 준비¶
- Docker 엔진 20.10 이상. 무료로는 WSL2 + docker-ce나 Rancher Desktop을 쓰면 되고, Docker Desktop은 조직 사용 시 유료입니다.
- 스캐너 이미지 pull:
- 모든 예시는 스캔할 프로젝트 루트에서 실행합니다.
옵션 플래그는
--generate-only(로컬 저장)와 함께 쓰는 것을 권장합니다. 외부 시스템(Dependency-Track 서버나 TRUSCA) 자동 업로드를 함께 쓰려면 생략하세요. 대상은UPLOAD_TARGET으로 고릅니다.
한 번에 모두 생성하기 (--all)¶
--all은 --notice --security --spdx의 단축형입니다. SBOM과 고지문, 보안보고서, 그리고 SBOM의 SPDX 사본을 한 번의 스캔으로 만듭니다.
웹 UI와 데스크톱 앱에서는 고지문과 보안보고서가 새 스캔 화면의 생성 옵션이고, SPDX 사본은 스캔이 끝난 뒤 결과 화면에서 내보냅니다.
생성 파일:
MyApp_1.0.0_bom.json # SBOM (CycloneDX 1.6)
MyApp_1.0.0_NOTICE.txt # 고지문 (텍스트)
MyApp_1.0.0_NOTICE.html # 고지문 (HTML)
MyApp_1.0.0_security.json # 보안보고서 (Trivy 원본)
MyApp_1.0.0_security.md # 보안보고서 (요약)
MyApp_1.0.0_security.html # 보안보고서 (시각화)
MyApp_1.0.0_risk-report.md # 오픈소스위험분석보고서 (요약)
MyApp_1.0.0_risk-report.html # 오픈소스위험분석보고서 (시각화)
오픈소스위험분석보고서(
_risk-report)는 모든 분석 모드에서 기본 생성됩니다(라이선스+취약점 집계, 대응 기한 포함). 생략하려면--no-report를 쓰세요. 6가지 입력 형태별 처리는 시나리오별 가이드를 참고하세요.
산출물 종류 전체 목록은 산출물 레퍼런스를, 웹 UI로 만들려면 웹 UI를 참고하세요.
오픈소스 고지문 (--notice)¶
SBOM의 components[].licenses 정보를 모아 라이선스별로 컴포넌트를 묶은 고지문을 생성합니다.
_NOTICE.txt— 배포물에 동봉하기 좋은 표준 텍스트._NOTICE.html— 브라우저로 보기 좋은 형식. 모든 패키지 메타데이터는 HTML escape되어 안전합니다.- 라이선스 정보가 없는 컴포넌트는
NOASSERTION으로 분류됩니다.
라이선스 정규화와 전문 번들 동작은 보고서 읽는 법을 참고하세요.
예시(텍스트):
보안 취약점 보고서 (--security)¶
생성된 SBOM을 Trivy로 스캔해 알려진 취약점(CVE)을 보고합니다. (NVD + OSV + GHSA DB)
_security.json— Trivy 원본 JSON. CI나 기계 처리용._security.md— severity별 집계 표와 CVE 목록. PR/이슈에 붙이기 좋습니다._security.html— severity 배지와 표가 포함된 시각적 보고서.
보고서는 취약점이 있어도 스캔을 실패시키지 않습니다(report-only). 게이트가 필요하면 _security.json을 후처리하세요.
심각도, CVSS, EPSS, KEV 우선순위 신호와 후속 조치 해석은 보고서 읽는 법을 참고하세요.
정밀 CVE 대조 (--deep-cve)¶
Trivy는 패키지 식별자(PURL) 기준으로 취약점을 대조하므로 생태계 보안 권고 데이터베이스는 잘 다룹니다. 하지만 오래된 Java 라이브러리의 일부 CVE는 NVD에만 CPE 식별자로 기록되어 있어 PURL 기반 스캔으로는 닿지 않습니다. --deep-cve는 Maven 컴포넌트에 두 번째 대조를 더합니다. BomLens가 각 컴포넌트의 groupId로부터 NVD 대조가 가능한 CPE를 만들어 주고, grype가 그 CPE를 내장 NVD 데이터베이스와 대조합니다.
--deep-cve는--security를 자동으로 켭니다. 추가로 찾은 결과는 같은 보안 보고서(_security.json/.md/.html)에nvd:cpe출처 표시와 함께 합쳐집니다.- 스캔은 grype와 데이터베이스를 내장한 opt-in 이미지
ghcr.io/sktelecom/bomlens-deep-cve:latest로 실행되며, 플래그를 켜면 자동으로 내려받습니다(SBOM_DEEP_CVE_IMAGE로 지정 가능). 기본 이미지 모드(소스, 이미지, 바이너리, rootfs, SBOM 분석)에 적용되고, 펌웨어와 AI 모델 스캔에서는 경고를 출력한 뒤 grype 없이 진행합니다. - CPE 대조는 PURL 대조보다 느슨합니다. NVD의 버전 범위가 대략적으로 기록된 경우가 있기 때문입니다. 기본값은 오프라인 동작이라 그런 결과를 버리지 않고 보고서에 버전 미검증으로 표시합니다(단검 기호와 각주). 어느 행이 느슨한 버전 대조로 인한 오탐일 수 있는지 읽는 사람이 알 수 있습니다. 더 조이려면
NVD_API_KEY와 함께SECURITY_NVD_VERIFY=true를 설정하세요. 각 결과를 NVD 실시간 버전 범위와 대조해 범위 밖 오탐을 걸러냅니다. 이 검증은 네트워크가 필요하고 수 분이 더 걸립니다.
SECURITY_NVD_VERIFY=true NVD_API_KEY="your-key" \
./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --deep-cve --generate-only
정밀 라이선스 탐지 (--deep-license)¶
기본 고지문은 의존성(3rd-party)의 라이선스를 다룹니다. --deep-license는 scancode-toolkit으로 프로젝트 자체 소스코드(1st-party)의 라이선스 헤더까지 탐지합니다.
웹 UI에서는 정밀 라이선스 탐지가 생성 옵션 중 하나로 제공됩니다. 어느 쪽이든 scancode에 의존하는데, scancode는 무겁고 느리며(대형 저장소는 수 분~수십 분) 기본 이미지에는 포함되지 않습니다. 쓰려면 scancode가 포함된 이미지로 실행해야 합니다.
추가 산출물: MyApp_1.0.0_scancode.json
배포 라이선스 충돌 (--license)¶
프로젝트를 배포하는 라이선스를 선언해, 각 의존성을 그 기준으로 판정하게 합니다. 소스 스캔으로는 알아낼 수 없는 값이라(cdxgen이 maven과 gradle에서 루트 라이선스를 비워 둡니다) 지정하지 않으면 판정하지 않습니다.
./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --license Apache-2.0 --all --generate-only
선언한 값은 SBOM 루트 컴포넌트에 기록되고, 위험분석보고서에 충돌 절이 생깁니다. SBOM에 이미 있는 루트 라이선스(공급사가 선언한 값)는 덮어쓰지 않습니다. 판정을 읽는 방법은 보고서 읽는 법을 참고하세요.
결정론적 출력 (--byte-stable)¶
같은 입력이면 항상 동일한 바이트의 SBOM을 생성합니다. CI에서 의미 없는 diff(타임스탬프, 랜덤 ID, 정렬 차이)를 제거하고 재현성을 확보합니다.
적용 내용: metadata.timestamp를 1970-01-01T00:00:00Z로 고정, 랜덤 serialNumber 제거, components를 purl 기준 정렬, 키 정렬.
SBOM 서명 (--sign)¶
cosign으로 SBOM에 detached 서명을 만들어 공급망 신뢰를 확보합니다. 오프라인 키 기반 서명(--tlog-upload=false)이라 네트워크나 OIDC가 필요 없습니다.
# 1) 키 생성 (최초 1회). 무비밀번호 키는 COSIGN_PASSWORD="" 로 생성
docker run --rm -v "$PWD":/keys -w /keys -e COSIGN_PASSWORD="" \
--entrypoint cosign ghcr.io/sktelecom/bomlens:latest generate-key-pair
# 2) 서명하며 스캔 (COSIGN_KEY=개인키 경로, COSIGN_PASSWORD=키 비밀번호)
COSIGN_KEY="$PWD/cosign.key" COSIGN_PASSWORD="" \
./scripts/scan-sbom.sh --project MyApp --version 1.0.0 --sign --generate-only
# 3) 검증
docker run --rm -v "$PWD":/w -w /w --entrypoint cosign \
ghcr.io/sktelecom/bomlens:latest \
verify-blob --key cosign.pub --signature MyApp_1.0.0_bom.json.sig \
--insecure-ignore-tlog MyApp_1.0.0_bom.json
개인키는 컨테이너에 읽기 전용으로 마운트됩니다. 추가 산출물: MyApp_1.0.0_bom.json.sig
트러블슈팅¶
| 증상 | 원인 / 해결 |
|---|---|
trivy not installed ... skipping |
구버전 이미지. docker pull로 최신 이미지를 받으세요. |
--deep-license requested but scancode not in image |
--build-arg SBOM_DEEP_LICENSE=true로 이미지를 빌드하세요. |
UI에서 Docker is not running |
Docker 엔진(Rancher Desktop/Docker Desktop 등)을 시작한 뒤 다시 실행하세요. |
고지문에 NOASSERTION이 많음 |
의존성에 라이선스 메타데이터가 없는 경우입니다. --deep-license로 보완하거나 수동 확인하세요. |
포트 충돌(--ui) |
UI_PORT로 다른 포트를 지정하세요. |