Announcement

👇Official Account👇

Welcome to join the group & private message

Article first/tail QR code

Skip to content

Go SBOM 实战:软件供应链安全从合规到落地

SBOM 为什么在 2026 年成为刚需

2026 年,软件供应链安全已从"最佳实践"升级为"法律要求":

  • 美国:EO 14028 行政令要求所有向联邦政府交付的软件必须附带 SBOM
  • 欧盟:CRA(Cyber Resilience Act)2026 年全面实施,要求产品全生命周期 SBOM 管理
  • 中国:等保 2.0 和关键信息基础设施安全保护条例中,软件成分透明化成为合规要求
  • 行业:金融、医疗、能源等关键行业已将 SBOM 列入供应商准入条件
┌──────────────────────────────────────────────────────────────────────┐
│              2026 SBOM 合规时间线                                     │
│                                                                      │
│  2024 ──── 2025 ──── 2026 ──── 2027 ──── 2028                       │
│    │         │         │         │         │                         │
│    ▼         ▼         ▼         ▼         ▼                         │
│  EO 14028  CRA 框架   CRA 全面   SBOM 2.0   全球供应链             │
│  发布       通过       实施      标准      安全协议                  │
│             SBOM 1.0   强制合规   推出      互联互通                 │
│             试点       xBOM 扩展                                       │
│                                                                      │
│  ← 建议期 ──────→ │ ← 过渡期 ──────→ │ ← 强制期 ──────→            │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

SBOM(Software Bill of Materials,软件物料清单) 的核心价值:

价值维度说明举例
透明性完整记录软件的组成成分知道你的 Go 二进制包含了哪些依赖
可追溯每个组件的来源、版本、许可证追溯 Log4j 类漏洞的影响范围
可审计支持自动化合规检查证明软件不包含已知高危漏洞
可响应漏洞披露后快速定位影响CVE 发布后 1 小时内确认是否受影响

SBOM 标准解读

三大主流标准对比

┌──────────────────────────────────────────────────────────────────────┐
│                    SBOM 标准对比                                      │
├────────────┬──────────────┬──────────────┬──────────────────────────┤
│            │ SPDX         │ CycloneDX    │ CSAF                     │
├────────────┼──────────────┼──────────────┼──────────────────────────┤
│ 发起方     │ Linux 基金会  │ OWASP       │ OASIS                    │
│ 最新版本   │ 3.0 (2026)   │ 1.6 (2025)  │ 2.2                     │
│ 格式       │ JSON/TagValue│ JSON/XML    │ JSON                     │
│ 专注点     │ 许可证合规    │ 安全漏洞    │ 安全公告                 │
│ Go 生态    │ 原生支持      │ Syft 原生   │ Grype 集成              │
│ 适用场景   │ 开源合规      │ 漏洞管理    │ 漏洞通报                │
│ 复杂度     │ 高           │ 中          │ 中                       │
│ 推荐度     │ ★★★☆        │ ★★★★★     │ ★★★☆                   │
└────────────┴──────────────┴──────────────┴──────────────────────────┘

CycloneDX 是 Go 项目首选 — 原因:

  1. Syft 原生输出 CycloneDX 格式
  2. Grype 直接消费 CycloneDX SBOM 进行漏洞扫描
  3. 结构精简,专注于安全用例
  4. 与 OCI 镜像签名(cosign)集成良好

SBOM 必需字段

json
{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "metadata": {
    "component": {
      "type": "application",
      "name": "my-go-service",
      "version": "1.2.3",
      "purl": "pkg:golang/github.com/example/my-go-service@1.2.3"
    },
    "timestamp": "2026-06-08T00:00:00Z",
    "tools": [
      {
        "name": "syft",
        "version": "1.20.0"
      }
    ]
  },
  "components": [
    {
      "type": "library",
      "name": "github.com/gin-gonic/gin",
      "version": "1.10.0",
      "purl": "pkg:golang/github.com/gin-gonic/gin@1.10.0",
      "licenses": [{"id": "MIT"}],
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "abc123..."
        }
      ]
    }
  ],
  "dependencies": [
    {
      "ref": "pkg:golang/github.com/example/my-go-service@1.2.3",
      "dependsOn": [
        "pkg:golang/github.com/gin-gonic/gin@1.10.0"
      ]
    }
  ]
}

关键字段说明:

字段用途重要性
purl (Package URL)统一标识符,跨生态唯一★★★★★
hashes完整性校验,防篡改★★★★☆
licenses开源合规审计★★★★☆
dependencies依赖关系图,漏洞传播分析★★★★★

Go 项目 SBOM 实战

工具链全景

┌──────────────────────────────────────────────────────────────────────┐
│               Go 供应链安全工具链                                     │
│                                                                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────────┐    │
│  │  Syft    │  │  Grype   │  │  cosign  │  │  Go 工具链       │    │
│  │  SBOM生成│  │  漏洞扫描│  │  签名验证│  │  go.sum/vulncheck│    │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └───────┬──────────┘    │
│       │             │             │                │                │
│       ▼             ▼             ▼                ▼                │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │                    CI/CD 流水线                               │   │
│  │  Build → SBOM → Scan → Sign → Verify → Deploy              │   │
│  └──────────────────────────────────────────────────────────────┘   │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │                    存储层                                      │   │
│  │  OCI Registry(SBOM + 签名 作为 镜像附件)                   │   │
│  │  SBOM 管理平台(Dependency-Track / GUAC)                    │   │
│  └──────────────────────────────────────────────────────────────┘   │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

安装工具链

bash
# Syft — SBOM 生成
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

# Grype — 漏洞扫描
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin

# cosign — 容器签名
go install github.com/sigstore/cosign/v2/cmd/cosign@latest

# Go 内置漏洞检查
go install golang.org/x/vuln/cmd/govulncheck@latest

第一步:生成 SBOM

从 Go 源码生成

bash
# 从 Go 模块生成 SBOM(CycloneDX 格式)
syft dir:./my-go-service \
  --output cyclonedx-json \
  --file my-go-service.sbom.json

# 从 go.mod/go.sum 生成(更快,适合 CI)
syft dir:./my-go-service \
  --output cyclonedx-json \
  --file my-go-service.sbom.json \
  --select-catalogers "-golang-mod"

# 从 Go 二进制生成(适合已编译产物)
syft file:./my-go-service-binary \
  --output cyclonedx-json \
  --file my-go-service-binary.sbom.json

从 OCI 镜像生成

bash
# 从 Docker 镜像生成 SBOM
syft registry://ghcr.io/example/my-go-service:v1.2.3 \
  --output cyclonedx-json \
  --file my-go-service-image.sbom.json

# 多架构镜像
syft registry://ghcr.io/example/my-go-service:v1.2.3 \
  --platform linux/amd64 \
  --output cyclonedx-json \
  --file my-go-service-amd64.sbom.json

Go 内置方式:go.mod 深度分析

Go 1.26+ 提供了增强的模块图分析能力:

bash
# 查看完整依赖图
go mod graph

# 查看依赖为什么被引入
go mod why github.com/gin-gonic/gin

# Go 1.26+:查看依赖的工具链链
go version -m ./my-go-service-binary

输出示例:

my-go-service: go1.26.0
        dep     github.com/gin-gonic/gin       v1.10.0
        dep     github.com/go-playground/validator/v10  v10.22.0
        dep     golang.org/x/crypto    v0.24.0
        dep     golang.org/x/net       v0.26.0
        build   -buildmode=exe
        build   -compiler=gc
        build   CGO_ENABLED=0
        build   GOARCH=amd64
        build   GOOS=linux
        build   GOAMD64=v1
        build   vcs=git
        build   vcs.revision=abc123def456
        build   vcs.time=2026-06-07T12:00:00Z
        build   vcs.modified=false

第二步:漏洞扫描

Grype 扫描 SBOM

bash
# 扫描已生成的 SBOM
grype sbom:./my-go-service.sbom.json

# 直接扫描 Docker 镜像
grype registry://ghcr.io/example/my-go-service:v1.2.3

# 仅报告高危和严重漏洞
grype sbom:./my-go-service.sbom.json \
  --fail-on high \
  --output table

# 输出 SARIF 格式(集成到 GitHub Code Scanning)
grype sbom:./my-go-service.sbom.json \
  --output sarif \
  --file grype-results.sarif

输出示例:

 ✔ Vulnerability DB        [updated]
 ✔ Loaded image            Parsed image
 ✔ Cataloged packages      [142 packages]

NAME                    INSTALLED   FIXED-IN    TYPE       VULNERABILITY   SEVERITY
golang.org/x/crypto     v0.24.0     v0.25.0     go-module  CVE-2026-XXXX   Critical
golang.org/x/net        v0.26.0     v0.27.0     go-module  CVE-2026-YYYY   High
github.com/gogo/protobuf v1.3.2    (no fix)    go-module  GHSA-rq3m-XXXX  Medium

Go 内置漏洞检查:govulncheck

bash
# 检查当前模块的已知漏洞
govulncheck ./...

# 检查特定包
govulncheck github.com/example/my-go-service/cmd/server

# 输出 JSON 格式
govulncheck -json ./...

# 仅显示实际调用的漏洞(而非仅依赖的)
govulncheck -mode module ./...

govulncheck 的优势在于调用图分析:只报告你的代码实际调用路径上的漏洞,而非所有依赖中的漏洞。这比 Grype 的"依赖存在即报告"更精准。

第三步:签名与验证

容器镜像 + SBOM 签名

bash
# 1. 构建并推送镜像
docker build -t ghcr.io/example/my-go-service:v1.2.3 .
docker push ghcr.io/example/my-go-service:v1.2.3

# 2. 将 SBOM 作为 OCI 镜像附件附加
syft registry://ghcr.io/example/my-go-service:v1.2.3 \
  --output cyclonedx-json \
  | cosign attach sbom --sbom - ghcr.io/example/my-go-service:v1.2.3

# 3. 签名镜像
cosign sign --yes ghcr.io/example/my-go-service:v1.2.3

# 4. 签名 SBOM
cosign sign --yes \
  --attachment sbom \
  ghcr.io/example/my-go-service:v1.2.3

# 5. 验证镜像签名
cosign verify ghcr.io/example/my-go-service:v1.2.3

# 6. 验证 SBOM 签名
cosign verify --attachment sbom ghcr.io/example/my-go-service:v1.2.3

第四步:SLSA 证明

SLSA(Supply-chain Levels for Software Artifacts)是供应链完整性的另一个关键标准:

┌──────────────────────────────────────────────────────────────────────┐
│                    SLSA Level 定义                                    │
├─────────┬────────────────────────────────────────────────────────────┤
│ Level 1 │ 构建过程有文档记录,有签名证明来源                          │
│ Level 2 │ 托管构建平台,签名构建产出                                 │
│ Level 3 │ 构建环境硬隔离,不可伪造的证明                              │
│ Level 4 │ 双人审核,可复现构建,全流程加密                            │
└─────────┴────────────────────────────────────────────────────────────┘

使用 GitHub Actions 生成 SLSA 证明:

yaml
# .github/workflows/build.yml
name: Build and Sign

on:
  push:
    tags: ['v*']

permissions:
  contents: read
  id-token: write
  packages: write

jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      digest: ${{ steps.build.outputs.digest }}

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: '1.26'

      - name: Build Go binary
        run: |
          CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" \
            -o my-go-service ./cmd/server

      - name: Build and push container
        id: build
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: ghcr.io/example/my-go-service:${{ github.ref_name }}
          provenance: true    # 自动生成 SLSA provenance
          sbom: true           # 自动生成 SBOM

      - name: Sign with cosign
        uses: sigstore/cosign-installer@v3
      - run: |
          cosign sign --yes \
            ghcr.io/example/my-go-service@${{ steps.build.outputs.digest }}

      - name: Scan with Grype
        uses: anchore/scan-action@v3
        with:
          image: ghcr.io/example/my-go-service@${{ steps.build.outputs.digest }}
          fail-build: true
          severity-cutoff: high
          output-format: sarif

      - name: Upload SARIF results
        uses: github/codeql-action/upload-sarif@v3
        if: always()

CI/CD 完整流水线

将 SBOM 生成、漏洞扫描、签名验证整合为完整流水线:

yaml
# .github/workflows/supply-chain-security.yml
name: Supply Chain Security

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  sbom-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: '1.26'

      # ──── 1. Go 内置漏洞检查 ────
      - name: Run govulncheck
        run: |
          go install golang.org/x/vuln/cmd/govulncheck@latest
          govulncheck -json ./... > govulncheck-results.json

      # ──── 2. 生成 SBOM ────
      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ghcr.io/example/my-go-service:latest
          format: cyclonedx-json
          output-file: sbom.json

      # ──── 3. 漏洞扫描 ────
      - name: Scan SBOM for vulnerabilities
        uses: anchore/scan-action@v3
        with:
          sbom: sbom.json
          fail-build: true
          severity-cutoff: high

      # ──── 4. 许可证合规检查 ────
      - name: Check licenses
        run: |
          # 拒绝 GPL 等传染性许可证
          syft dir:./ -o json | \
            jq -r '.artifacts[] | select(.licenses[]?.value | test("GPL|AGPL")) | .name + " " + .licenses[0].value' > license-violations.txt
          if [ -s license-violations.txt ]; then
            echo "❌ 发现不合规许可证:"
            cat license-violations.txt
            exit 1
          fi
          echo "✅ 许可证合规检查通过"

      # ──── 5. 上传 SBOM 到管理平台 ────
      - name: Upload SBOM to Dependency-Track
        if: github.ref == 'refs/heads/main'
        run: |
          curl -X POST "https://dtrack.example.com/api/v1/bom" \
            -H "X-API-Key: ${{ secrets.DTRACK_API_KEY }}" \
            -H "Content-Type: multipart/form-data" \
            -F "project=${{ secrets.DTRACK_PROJECT_ID }}" \
            -F "bom=@sbom.json"

SBOM 管理平台

生成 SBOM 只是第一步,持续管理才是核心:

┌──────────────────────────────────────────────────────────────────────┐
│                    SBOM 管理平台对比                                  │
├─────────────┬────────────────────────────────────────────────────────┤
│             │                                                        │
│ Dependency  │  OWASP 开源,功能最全面的 SBOM 管理平台                │
│ -Track      │  - 漏洞扫描 + 许可证合规 + 策略管理                    │
│             │  - 支持 CycloneDX / SPDX                                │
│             │  - 适合中大型企业                                       │
│             │                                                        │
│ GUAC        │  Google 开源的供应链聚合平台                            │
│ (Graph for  │  - 将 SBOM 数据聚合为知识图谱                          │
│  Understand │  - 支持依赖传播分析                                    │
│  Artifact   │  - 适合复杂供应链场景                                   │
│  Composition)│                                                        │
│             │                                                        │
│ Sigstore    │  签名与验证基础设施                                     │
│ Rekor       │  - 不可篡改的签名透明日志                              │
│             │  - 支持密钥轮换和时间点验证                             │
│             │  - 适合需要审计追踪的场景                               │
│             │                                                        │
└─────────────┴────────────────────────────────────────────────────────┘

Go 供应链安全最佳实践

1. go.mod 卫生管理

bash
# 定期清理未使用的依赖
go mod tidy

# 验证依赖完整性(确保 go.sum 与上游一致)
go mod verify

# 检查直接依赖是否有更新
go list -u -m -json all | \
  jq -r 'select(.Update != null) | "\(.Path) \(.Version) → \(.Update.Version)"'

# 替换有漏洞的依赖
go get golang.org/x/crypto@latest
go mod tidy

2. GOPROXY 安全配置

bash
# 设置私有 Go 代理(避免直连 GitHub,防止中间人攻击)
go env -w GOPROXY=https://goproxy.cn,direct

# 设置 GONOSUMCHECK 和 GONOSUMDB(内部模块不校验公共校验和数据库)
go env -w GONOSUMCHECK=gitlab.internal.com/*
go env -w GONOSUMDB=gitlab.internal.com/*

# 设置 GOFLAGS 确保使用校验和数据库
go env -w GONOSUMCHECK=""
go env -w GOSUM=on

3. 构建可复现性

Go 1.26+ 增强了构建可复现性支持:

dockerfile
# Dockerfile — 可复现构建
FROM golang:1.26-alpine AS builder

# 固定版本号,避免浮动标签
ARG GO_VERSION=1.26.0
ARG ALPINE_VERSION=3.20

# 使用 -trimpath 移除构建路径信息
# 使用 -ldflags="-s -w" 移除调试信息
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
    -trimpath \
    -ldflags="-s -w -X main.version=v1.2.3 -X main.commit=$(git rev-parse HEAD)" \
    -o /app/server ./cmd/server

FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]

验证可复现性:

bash
# 构建两次,比较哈希
docker build -t test:v1 .
HASH1=$(docker inspect --format='{{index .RepoDigests 0}}' test:v1)

docker build --no-cache -t test:v2 .
HASH2=$(docker inspect --format='{{index .RepoDigests 0}}' test:v2)

if [ "$HASH1" = "$HASH2" ]; then
  echo "✅ 构建可复现"
else
  echo "❌ 构建不可复现,需要检查"
fi

4. 依赖锁定与审计

bash
# 生成依赖审计报告
go mod graph | \
  awk '{print $1}' | \
  sort -u | \
  while read dep; do
    # 检查每个依赖是否有已知漏洞
    govulncheck "$dep" 2>/dev/null && echo "✅ $dep" || echo "❌ $dep"
  done

5. 自动化 PR 依赖更新

使用 Dependabot 或 Renovate 自动创建依赖更新 PR:

yaml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
      - "security"
    reviewers:
      - "security-team"
    # 只自动合并补丁版本更新
    allow:
      - dependency-type: "patch"

从合规到安全文化

SBOM 不是目的,而是建立软件供应链安全文化的起点:

┌──────────────────────────────────────────────────────────────────────┐
│                 SBOM 成熟度模型                                       │
│                                                                      │
│  Level 1: 基础合规                                                  │
│  ├─ 生成 SBOM(CycloneDX/SPDX)                                     │
│  ├─ SBOM 随软件交付                                                 │
│  └─ 手动漏洞扫描                                                    │
│                                                                      │
│  Level 2: 自动化集成                                                │
│  ├─ CI/CD 自动生成 SBOM                                             │
│  ├─ 自动化漏洞扫描(Grype/govulncheck)                              │
│  ├─ 镜像签名(cosign)                                              │
│  └─ SARIF 集成到 Code Scanning                                     │
│                                                                      │
│  Level 3: 持续管理                                                  │
│  ├─ SBOM 管理平台(Dependency-Track)                               │
│  ├─ 漏洞 SLA(Critical 24h / High 7d / Medium 30d)                 │
│  ├─ 许可证策略自动执行                                              │
│  └─ SLSA Level 3 证明                                               │
│                                                                      │
│  Level 4: 供应链完整性                                              │
│  ├─ 可复现构建验证                                                  │
│  ├─ 依赖传播图分析(GUAC)                                          │
│  ├─ 实时漏洞影响评估                                                │
│  └─ SLSA Level 4 + 全流程加密                                      │
│                                                                      │
│  ← 你在这里?────→ 目标:至少 Level 2                               │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

总结

Go 项目的软件供应链安全在 2026 年已经形成了成熟的工具链和方法论:

  1. Syft 生成 SBOM + Grype 扫描漏洞 — 5 分钟即可集成到 CI
  2. govulncheck 精准定位 — 基于调用图的漏洞分析比依赖扫描更精准
  3. cosign 签名验证 — 确保镜像和 SBOM 在交付链中不被篡改
  4. SLSA 证明 — 从构建到部署的全链路可追溯
  5. Dependency-Track 持续管理 — SBOM 不是一次性产物,需要持续更新和监控

一句话总结:SBOM 是软件供应链安全的基础设施——没有它,你甚至不知道自己有什么;有了它,才能知道该修什么。从 Syft + Grype + cosign 三件套开始,10 分钟就能让 Go 项目达到供应链安全 Level 2。

参考资料

上次更新于: