feat: server delivery SBOM — layered scan, --merge, rootfs UI input#161
Merged
Conversation
Add a --merge mode that combines two or more CycloneDX SBOMs into one, dedupes components by purl, and stamps the root component with --project/--version. It is built for layered server delivery: an OS rootfs layer, an application layer, and a static-link layer are each scanned separately, then merged when a submission system needs a single product BOM. Each component keeps a bomlens:layer property so layer provenance survives the merge; dependencies trees are dropped (their bom-ref namespaces collide across inputs). merge-sbom.sh passes components between jq steps via files (jq -s / --slurpfile), not argv, so a real server SBOM with hundreds/thousands of components does not overflow ARG_MAX. Also stamp the ROOTFS root component: syft names a dir: scan after the scan path (/target), which is meaningless and leaks the container mount path into the SBOM. ROOTFS now gets the caller's --project/--version, the same fix stamp-metadata.sh already applied to cdxgen scans.
Add a "Directory path" (rootfs-dir) input to the web UI so an OS rootfs or any subfolder under the launch folder can be scanned as a directory (MODE=ROOTFS), not just the fixed current folder. safe_scan_dir() resolves the user path with realpath and forces it inside /src (the only mounted root), rejecting ../ traversal, absolute paths, and symlink escapes. The allowed-root boundary is a list, so a future `--ui --mount <host-path>` can extend it without touching the check.
Document how a supplier builds a server SBOM: scan the OS rootfs, the application, and the static-link dependencies as three layers, verify each, and submit them separately. Submitting the layers separately is the default — it keeps each layer reviewable and preserves per-layer dependency graphs. Merging into one product BOM with --merge is an optional step for when a submission system requires a single file. Also note the static-link detection limits (binary/firmware mode plus hand-recorded build sources, with BDBA as SKT's complementary check) and the rejection causes (hand-written SBOMs, pkg:generic, raw-directory scans, scanning before the build). Document --merge in the CLI reference and expand --target to mention rootfs/staging targets.
| real = os.path.realpath(os.path.join(SRC_DIR, rel)) | ||
| for root in ALLOWED_SCAN_ROOTS: | ||
| r = os.path.realpath(root) | ||
| if (real == r or real.startswith(r + os.sep)) and os.path.isdir(real): |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
배경
CentOS 기반 서버를 납품하는 공급사의 서버 SBOM 제출을 지원한다. 서버 SBOM은 세 층(OS rootfs, 애플리케이션, 정적 링크 의존성)으로 나뉘는데, 한 층만 스캔하면 나머지가 빠져 반려된다. 도구·문서에 두 빈틈이 있었다: 층별 SBOM을 합치는 기능 부재, UI에서 임의 rootfs 디렉터리를 스캔할 수단 부재.
변경
scanner —
--merge--project/--version으로 기재.bomlens:layer속성으로 출처(층)를 보존.dependencies트리는 bom-ref 충돌로 병합하지 않음.jq -s/--slurpfile)로 전달해 실제 서버 규모(수백~수천 컴포넌트)에서 ARG_MAX를 넘지 않음.dir:스캔을 마운트 경로(/target)로 명명해 내부 경로가 노출되던 문제를--project값으로 교정.ui — rootfs-dir 입력
/src하위 rootfs나 임의 하위 폴더를 ROOTFS 모드로 스캔.safe_scan_dir()가 realpath +/src경계 강제로../traversal·절대경로·심볼릭 링크 탈출을 차단. 허용 경계는 목록이라 후일--mount확장이 쉬움.docs — 서버 납품 가이드
docs/guides/server-delivery.{md,ko.md}신규. 층별 분리 제출을 기본으로, 병합은 제출 시스템이 단일 BOM을 요구할 때의 선택 단계로 안내. 정적 링크 한계와 반려 사유 포함.cli.{md,ko.md}에--merge문서화,--target설명 확장.by-input상호 링크, mkdocs nav 등록.검증
실제 rpm rootfs(UBI9) 대상으로
scan-sbom.shCLI end-to-end 실측.pkg:rpmpurl.--merge로 128개(rpm 110 + apk 16) 병합, 층 라벨mms-relay-os/alpine보존./target경로 노출 두 버그를 발견·수정.tsc/vite build통과, server.pypy_compile통과.