Files
dap-was-dapms/docs/sbom/README.md
koseokmin cb29b192b4 docs를 저장소로 되돌리고 계약 예제를 복원한다
5cfb8a1이 .gitignore에 docs/를 넣고 68개 파일을 지웠다. 그런데
AgentBuilderContractExampleTest, ToolBundleContractExampleTest,
ArchitectureDocumentContractTest는 docs/ 아래 계약 예제와 architecture
문서를 입력으로 직접 읽는다. 그 결과 clean clone에서 테스트 10건이
입력을 찾지 못해 실패했다.

제외 범위를 원래 의도대로 좁힌다. 에이전트 산출물(AGENTS.md, .agents/,
.codex/, docs/superpowers/)은 계속 제외하고 저장소 문서는 추적한다.

문서는 삭제 직전 상태(3de052a)를 기준으로 복원하고, 그 위에 main 코드와
대조해 어긋난 부분을 고쳤다.

- ADR-0007을 Superseded로 바꾸고 ADR-0013을 새로 쓴다. route당 Tool
  Service N개가 최종안이며, PortalToolRegistryClient가 이미 route별로
  N개를 유지하고 있는데 ADR-0007은 "bundles는 항상 한 항목"을 Accepted
  상태로 주장하고 있었다. ADR-0009 결정 4도 부분 대체한다.
- ADR-0008 파일 헤더가 Accepted였으나 ADR-0009가 이미 대체한 상태였다.
- 6078852의 endpoint 소유권 반전이 반영되지 않은 서술을 계약 v0.2,
  bundle 설정 예제, Tool 적재 안내에서 고친다.
- Portal registry 계약 v0.1과 route key 규약을 새로 문서화한다. 둘 다
  구현은 있는데 계약 문서가 없었다.
- MCP SDK 2.0.0 SBOM을 추가한다.

번호 주석: ADR-0011과 0012는 feature/mcp-integration이 Tool inputSchema
정책에 쓰고 있어 비워 둔다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 23:27:56 +09:00

5.4 KiB

SBOM — AXHUB MCP&Tool Service

  • 산출물: AXHUB_MCP_Tool_Service_SBOM_CycloneDX1.5.json (CycloneDX 1.5 정본), AXHUB_MCP_Tool_Service_SBOM_CycloneDX1.5.xlsx (검토용)
  • 대상: AXHUB MCP Server와 Tool Service의 공통 스택 (Java 21 / Spring Boot 3.5.11)
  • 산출 기준 빌드: ax-hub-mcp-server@0.1.0
  • 생성 기준일: 2026-08-18

대상 범위

MCP Server와 Tool Service는 같은 기술 스택과 같은 MCP SDK를 쓰므로 이 SBOM을 공통으로 적용한다. build.gradle이 직접 선언한 오픈소스는 io.modelcontextprotocol.sdk:mcp-json-jackson2:2.0.0 하나이며, 이 SBOM은 그 런타임 전이 의존 전체빌드 환경을 담는다. Spring Boot starter 계열(web / validation / data-redis / actuator)은 glow f/w가 제공하는 플랫폼 구성이라 범위 밖이다.

다만 목록은 MCP Server 빌드(ax-hub-mcp-server@0.1.0) 하나에서 산출했다. Tool Service가 이 스택 밖의 의존(예: DB 드라이버, 연계 라이브러리)을 추가하면 그만큼은 이 SBOM에 없으므로, 해당 빌드에서 다시 산출해 합쳐야 한다.

구분 개수 내용
런타임 의존성 (scope: required) 12 실행 산출물 classpath에 올라가는 라이브러리
빌드 환경 (scope: optional) 2 JDK 21, Gradle 8.14.3
합계 14

라이선스는 Apache-2.0 9건, MIT 3건, MIT-0 1건, GPL-2.0 with Classpath Exception 1건(JDK)이다. 라이브러리 12건은 모두 permissive이고, copyleft는 JDK 하나뿐이다. JDK는 Classpath Exception이 있어 이 JDK로 실행하는 애플리케이션에 소스 공개 의무가 생기지 않는다.

JDK 배포판은 표준가이드가 정한 Eclipse Temurin (openjdk21u-jdk_x64_windows_hotspot_21.0.5)이고, 이 SBOM은 그 환경에서 산출했다. 컨테이너 빌드와 실행도 같은 계열인 eclipse-temurin:21-jdk-alpineeclipse-temurin:21-jre-alpine을 쓴다.

다만 현재 build.gradle의 toolchain은 languageVersion만 지정하고 vendor를 고정하지 않는다. 로컬 빌드는 설치된 아무 JDK 21이나 잡을 수 있으므로, 이 SBOM의 JDK 항목은 산출 시점 환경의 기록이지 빌드가 강제하는 값이 아니다. 배포 산출물은 Dockerfile이 Temurin 이미지를 고정하므로 영향이 없다.

제외 항목

제외 항목과 사유는 엑셀 Exclusions 시트가 정본이다. 요약하면 다음과 같다.

  • test scope와 annotationProcessor — 선언 4건. 산출물에 포함되지 않는다.
    • spring-boot-starter-test, com.squareup.okhttp3:mockwebserver:4.12.0, org.junit.platform:junit-platform-launcher (test scope)
    • org.springframework.boot:spring-boot-configuration-processor (annotationProcessor)
  • joni, graal-js, graal-sdk — json-schema-validator의 optional. ECMA262 정규식 검증을 쓰지 않아 해석되지 않으므로 약 50MB가 빠진다.
  • jakarta.servlet-api:6.1.0 — mcp-core의 provided. 산출물에 포함되지 않고 서블릿 컨테이너가 제공한다.
  • mcp:2.0.0(aggregate), mcp-json-jackson3:2.0.0 — Jackson 3 경로를 쓰지 않아 선언하지 않는다. 자세한 배경은 mcp-java-sdk-adoption.md 참고.

산출 방법과 한계

버전과 해시는 build.gradle 선언에서 출발해 Gradle 로컬 캐시의 실제 pom을 따라가 그래프를 만들고, 캐시된 실제 jar 바이너리에서 SHA-512 / SHA-1을 직접 계산했다. Gradle 배포본의 SHA-256은 wrapper의 distributionSha256Sum 값을 그대로 옮겼다.

최초 산출 시점에는 gradle daemon이 뜨지 않아(Unable to establish loopback connection) gradlew dependencies 대조를 하지 못했고, 버전 정렬은 pom과 Spring Boot BOM 판독에만 근거했다. 2026-08-22에 그 대조를 실행해 네 항목 모두 판독과 일치함을 확인했다.

./gradlew dependencies --configuration runtimeClasspath
컴포넌트 pom 요청 버전 수록 버전 근거 실측
jackson-databind 2.20.1 (mcp-json-jackson2) 2.19.4 Spring Boot 3.5.11 → jackson-bom 2.19.4 2.20.1 -> 2.19.4 확인
jackson-databind 2.18.3 (json-schema-validator) 2.19.4 위와 동일 2.18.3 -> 2.19.4 확인
reactor-core 3.7.0 (mcp-core) 3.7.16 Spring Boot 3.5.11 → reactor-bom 2024.0.15 3.7.0 -> 3.7.16 확인
slf4j-api 2.0.16 (mcp-core) 2.0.17 Spring Boot 3.5.11 관리 버전 2.0.16 -> 2.0.17 확인

같은 실행에서 mcp-json-jackson2의 전이 트리가 이 SBOM의 런타임 12건과 정확히 일치하는 것도 확인했다. jackson-bom은 BOM이라 컴포넌트가 아니며, 제외 항목으로 적은 joni / graal-js / graal-sdkjakarta.servlet-api는 실제로 runtimeClasspath에 나타나지 않았다.

가장 확인이 필요한 항목은 jackson-databind다. SDK가 요청한 2.20.1이 io.spring.dependency-management에 의해 2.19.4로 내려가므로, initialize / tools/list / tools/call 직렬화 계약 테스트로 동작을 확인한다. (2026-08-22 기준 전체 테스트 159건 통과)

CycloneDX 1.5 공식 JSON Schema 원본 대조는 폐쇄망이라 수행하지 않았다. 대신 생성 시점에 dependencies의 모든 ref / dependsOn이 실재하는 bom-ref를 가리키는지, 컴포넌트가 빠짐없이 dependencies에 등장하는지 구조 점검을 통과시켰다.