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

83 lines
5.4 KiB
Markdown

# 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-alpine``eclipse-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](../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에 그 대조를 실행해 **네 항목 모두 판독과 일치함을 확인했다.**
```bash
./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-sdk`
`jakarta.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`에 등장하는지 구조 점검을 통과시켰다.