This document outlines the Software Bill of Materials (SBOM) architecture in GoClaw, supported standards, distribution mechanisms, and Information Security (InfoSec) placement controls.
Enterprise and pilot customers (e.g. banking, fintech, government, and telecommunications) require a verifiable Software Bill of Materials (SBOM) to comply with cybersecurity frameworks such as ISO/IEC 27001, PCI-DSS, NIST SP 800-218 (SSDF), and US Executive Order 14028.
GoClaw's SBOM infrastructure satisfies the following objectives:
net/http DoS vectors) emerge.h1: module checksum the build actually linked, in the same form go.sum stores it — so an auditor can verify the inventory against the module graph with go mod verify. The SBOM files themselves are covered by SHA-256 digests in checksums.json.NOASSERTION, and CycloneDX leaves the license field out. See "License data" below.Exposing software dependency inventories naively can introduce security risks. GoClaw implements a 3-tier placement and access model to mitigate these threats:
flowchart LR
subgraph SBOM["GoClaw SBOM Architecture"]
direction LR
T1["<b>1. Release / Supply Chain</b><br/>• goclaw.ulab.mn/releases/<br/>• Current release only<br/>• SHA256 in checksums.json<br/>• CycloneDX 1.5 + SPDX 2.3"]
T2["<b>2. Live Gateway</b><br/>• /api/admin/sbom<br/>• AuthMiddleware<br/>• Token Protected<br/>• Anti-Recon"]
T3["<b>3. Offline CLI</b><br/>• goclaw sbom<br/>• Zero Network<br/>• Binary Built-in<br/>• Pipe to Grype"]
end
GET /api/admin/sbom (and /api/sbom, the same handler), guarded by AuthMiddleware.401 Unauthorized./admin/ path segment is naming, not a second privilege tier. Anyone who can open the dashboard can read the SBOM, so treat the token as the control boundary.checksums.json, a JSON object that maps each asset name to its digest. It is not in sha256sum format, so sha256sum -c cannot read it: compare the digest as in Release Distribution & Checksum Verification.checksums.json is served from the same host as the files it covers, so a match shows that a download is complete and uncorrupted, not who produced it. The SBOMs and checksums.json are not signed. The macOS binaries are code-signed when the release has a signing certificate configured; build provenance attestations for the binaries are optional and off unless enabled for the repository.goclaw sbom CLI command extracts the SBOM directly from the Go binary's embedded runtime metadata (runtime/debug.ReadBuildInfo()). It requires zero internet access and executes in milliseconds.GoClaw's own license is declared in both formats: CycloneDX carries it as the
metadata component license, SPDX as LicenseRef-GoClaw-Binary-License with a matching
hasExtractedLicensingInfos entry.
Per-dependency licenses are not asserted. Go's build metadata
(runtime/debug.ReadBuildInfo) carries module paths, versions and checksums, but no
license information, and GoClaw does not ship a license database to infer it. In SPDX
every dependency therefore reports NOASSERTION, which is the SPDX term for "not
evaluated" — it is not a claim that a component is unlicensed. In CycloneDX a
dependency has no licenses field at all.
For license review, use the SBOM as the authoritative component inventory and pair it
with THIRD_PARTY_NOTICES.md, or run a dedicated license scanner over the module graph.
An exhaustive per-release license bundle is available from security@ulab.mn.
Each dependency carries the h1: value recorded in go.sum — as the go:mod:h1
property in CycloneDX, and as an OTHER external reference in SPDX. This is a Go
dirhash (a hash over the module's file listing), not the SHA-256 of a downloadable
artifact, so it is deliberately not published under a SHA-256 label that no verifier
could reproduce. It is checkable directly against go.sum and go mod verify.
| Format | Specification | Primary Use Case | Media Type |
|---|---|---|---|
| CycloneDX 1.5 | OWASP Standard | Vulnerability scanning (Grype, Trivy, Snyk, Dependency-Track) | application/vnd.cyclonedx+json |
| SPDX 2.3 | ISO/IEC 5962:2021 | Procurement documentation, dependency inventory for legal review | application/spdx+json |
| Summary | Human-Readable Text / JSON | Operator inspections, terminal review, Web UI dashboard | application/json / text/plain |
# View human-readable dependency summary
goclaw sbom
# Export CycloneDX 1.5 JSON for vulnerability scanners
goclaw sbom --format cyclonedx --output goclaw-sbom.cdx.json
# Export SPDX 2.3 JSON
goclaw sbom --format spdx --output goclaw-sbom.spdx.json
# Pipe directly into Anchore Grype for instant scanning (zero-file workflow)
goclaw sbom -f cyclonedx | grype
# Scan using Aqua Trivy
goclaw sbom -f cyclonedx -o sbom.json && trivy sbom sbom.json
On a running gateway instance, operators or automated compliance agents can retrieve the SBOM with a bearer token:
# Download CycloneDX 1.5 JSON
curl -H "X-Goclaw-Token: <GATEWAY_AUTH_TOKEN>" \
"http://localhost:8080/api/admin/sbom?format=cyclonedx" \
-o goclaw-sbom.cdx.json
# Download SPDX 2.3 JSON
curl -H "X-Goclaw-Token: <GATEWAY_AUTH_TOKEN>" \
"http://localhost:8080/api/admin/sbom?format=spdx" \
-o goclaw-sbom.spdx.json
# Direct browser download with attachment header
http://localhost:8080/api/admin/sbom?format=cyclonedx&download=1
Only the current release is served at https://goclaw.ulab.mn/releases/<version>/;
/releases/latest.json names it (for example {"version":"v0.0.96",…}). A request
for an earlier version's files there returns 404. Every release from v0.2.2 on also
stays at https://storage.googleapis.com/goclaw-releases/releases/<version>/, the
same files and checksums.json, so the commands below work there with that
BASE_URL. The files of releases before that are available from security@ulab.mn.
VERSION=$(curl -fsSL https://goclaw.ulab.mn/releases/latest.json \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')
BASE_URL="https://goclaw.ulab.mn/releases/${VERSION}"
SBOM="goclaw-${VERSION}-linux-amd64-sbom.cdx.json"
# Download SBOM and checksums manifest
curl -fsSL "${BASE_URL}/${SBOM}" -o "${SBOM}"
curl -fsSL "${BASE_URL}/checksums.json" -o checksums.json
# Verify cryptographic integrity
EXPECTED_SHA=$(grep -o "\"${SBOM}\"[[:space:]]*:[[:space:]]*\"[^\"]*" checksums.json | grep -o '[^"]*$')
ACTUAL_SHA=$(shasum -a 256 "${SBOM}" | awk '{print $1}')
if [ "$EXPECTED_SHA" = "$ACTUAL_SHA" ]; then
echo "✅ SBOM Integrity Verified: SHA-256 matches."
else
echo "❌ Integrity Mismatch!"
exit 1
fi
Automate continuous supply-chain monitoring by posting release SBOMs to your internal Dependency-Track server:
curl -X "POST" "https://dtrack.corp.example.com/api/v1/bom" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F "projectName=GoClaw" \
-F "projectVersion=${VERSION}" \
-F "autoCreate=true" \
-F "bom=@goclaw-sbom.cdx.json"
internal/sbom/sbom.go: Core collector, module dependency model, and validation of Go h1: module checksums.internal/sbom/cyclonedx.go: OWASP CycloneDX 1.5 JSON serializer.internal/sbom/spdx.go: Linux Foundation SPDX 2.3 JSON serializer.internal/sbom/summary.go: Component categorizer and human-readable terminal formatter.internal/cli/cmd_sbom.go: CLI command implementation for goclaw sbom.internal/gateway/handler_sbom.go: Authenticated API handler for /api/admin/sbom and /api/sbom.web/js/views/system.js & web/index.html: Admin Web UI card for viewing and downloading SBOMs..github/workflows/release.yml: Release CI/CD automation generating official CycloneDX and SPDX assets.