sbom-supply-chain

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SBOM & Supply Chain Security

SBOM与供应链安全

Improve release trust with reproducible metadata and verification gates.
通过可复现的元数据和验证关卡提升发布版本的可信度。

When to Use This Skill

何时使用该技能

Use this skill when:
  • Producing SBOMs for container images or application builds
  • Verifying dependencies before deploy
  • Enforcing signed artifact and provenance policies
  • Preparing for SOC2, ISO 27001, or customer security reviews
  • Implementing SLSA framework requirements
  • Responding to supply chain vulnerabilities (e.g., Log4Shell-style events)
在以下场景使用本技能:
  • 为容器镜像或应用构建生成SBOM
  • 部署前验证依赖项
  • 强制执行签名工件和来源策略
  • 为SOC2、ISO 27001或客户安全审查做准备
  • 实施SLSA框架要求
  • 响应供应链漏洞(如Log4Shell类事件)

Prerequisites

前置条件

  • syft
    installed for SBOM generation
  • cdxgen
    installed for CycloneDX SBOM generation
  • grype
    for vulnerability matching against SBOMs
  • cosign
    v2+ for signing and attestation
  • Container registry with OCI artifact support
  • CI/CD pipeline with OIDC identity for keyless signing
  • 已安装
    syft
    用于SBOM生成
  • 已安装
    cdxgen
    用于生成CycloneDX格式SBOM
  • 已安装
    grype
    用于匹配SBOM中的漏洞
  • 已安装v2+版本的
    cosign
    用于签名和证明
  • 支持OCI工件的容器注册表
  • 具备OIDC身份用于无密钥签名的CI/CD流水线

SBOM Formats

SBOM格式

CycloneDX vs SPDX Comparison

CycloneDX与SPDX对比

yaml
comparison:
  cyclonedx:
    standard: "OWASP CycloneDX"
    focus: "Application security, vulnerability tracking"
    formats: ["JSON", "XML", "Protocol Buffers"]
    strengths:
      - Vulnerability references (VEX support)
      - Service and API dependency tracking
      - Hardware BOM support
    best_for: "Security-focused SBOM, vulnerability management"

  spdx:
    standard: "Linux Foundation SPDX (ISO/IEC 5962:2021)"
    focus: "License compliance, legal review"
    formats: ["JSON", "RDF/XML", "Tag-Value", "YAML"]
    strengths:
      - ISO standard
      - License expression language
      - Relationship modeling
    best_for: "License compliance, regulatory requirements"
yaml
comparison:
  cyclonedx:
    standard: "OWASP CycloneDX"
    focus: "Application security, vulnerability tracking"
    formats: ["JSON", "XML", "Protocol Buffers"]
    strengths:
      - Vulnerability references (VEX support)
      - Service and API dependency tracking
      - Hardware BOM support
    best_for: "Security-focused SBOM, vulnerability management"

  spdx:
    standard: "Linux Foundation SPDX (ISO/IEC 5962:2021)"
    focus: "License compliance, legal review"
    formats: ["JSON", "RDF/XML", "Tag-Value", "YAML"]
    strengths:
      - ISO standard
      - License expression language
      - Relationship modeling
    best_for: "License compliance, regulatory requirements"

Syft SBOM Generation

Syft SBOM生成

bash
undefined
bash
undefined

Generate SBOM for a container image (CycloneDX JSON)

为容器镜像生成SBOM(CycloneDX JSON格式)

syft ghcr.io/acme/api:v1.2.3 -o cyclonedx-json > sbom-cyclonedx.json
syft ghcr.io/acme/api:v1.2.3 -o cyclonedx-json > sbom-cyclonedx.json

Generate SBOM in SPDX format

生成SPDX格式的SBOM

syft ghcr.io/acme/api:v1.2.3 -o spdx-json > sbom-spdx.json
syft ghcr.io/acme/api:v1.2.3 -o spdx-json > sbom-spdx.json

Generate SBOM from a local directory (source code)

从本地目录(源代码)生成SBOM

syft dir:. -o cyclonedx-json > sbom-source.json
syft dir:. -o cyclonedx-json > sbom-source.json

Generate SBOM from a Dockerfile/built image

从Dockerfile/构建好的镜像生成SBOM

syft docker:my-local-image:latest -o cyclonedx-json > sbom-local.json
syft docker:my-local-image:latest -o cyclonedx-json > sbom-local.json

Generate SBOM for a specific package ecosystem

为特定包生态系统生成SBOM

syft dir:. --catalogers python -o cyclonedx-json > sbom-python.json
syft dir:. --catalogers python -o cyclonedx-json > sbom-python.json

Include file hashes for deeper analysis

包含文件哈希以进行深度分析

syft ghcr.io/acme/api:v1.2.3 -o cyclonedx-json --file-metadata > sbom-with-hashes.json
syft ghcr.io/acme/api:v1.2.3 -o cyclonedx-json --file-metadata > sbom-with-hashes.json

Multiple output formats simultaneously

同时生成多种输出格式

syft ghcr.io/acme/api:v1.2.3
-o cyclonedx-json=sbom-cdx.json
-o spdx-json=sbom-spdx.json
-o table=sbom-summary.txt
undefined
syft ghcr.io/acme/api:v1.2.3
-o cyclonedx-json=sbom-cdx.json
-o spdx-json=sbom-spdx.json
-o table=sbom-summary.txt
undefined

cdxgen SBOM Generation

cdxgen SBOM生成

bash
undefined
bash
undefined

Install cdxgen

安装cdxgen

npm install -g @cyclonedx/cdxgen
npm install -g @cyclonedx/cdxgen

Generate CycloneDX SBOM for a project directory

为项目目录生成CycloneDX格式SBOM

cdxgen -o sbom.json .
cdxgen -o sbom.json .

Specify project type

指定项目类型

cdxgen -t python -o sbom-python.json . cdxgen -t java -o sbom-java.json . cdxgen -t node -o sbom-node.json . cdxgen -t go -o sbom-go.json .
cdxgen -t python -o sbom-python.json . cdxgen -t java -o sbom-java.json . cdxgen -t node -o sbom-node.json . cdxgen -t go -o sbom-go.json .

Generate SBOM with evidence (call stacks, file occurrences)

生成包含证据(调用栈、文件出现位置)的SBOM

cdxgen --evidence -o sbom-with-evidence.json .
cdxgen --evidence -o sbom-with-evidence.json .

Generate for a container image

为容器镜像生成SBOM

cdxgen -t docker -o sbom-container.json ghcr.io/acme/api:v1.2.3
cdxgen -t docker -o sbom-container.json ghcr.io/acme/api:v1.2.3

Generate with deep analysis (slower but more accurate)

生成深度分析的SBOM(速度较慢但更准确)

cdxgen --deep -o sbom-deep.json .
cdxgen --deep -o sbom-deep.json .

Output in different formats

输出为不同格式

cdxgen -o sbom.xml --format xml .
undefined
cdxgen -o sbom.xml --format xml .
undefined

Vulnerability Matching

漏洞匹配

bash
undefined
bash
undefined

Scan SBOM for vulnerabilities with Grype

使用Grype扫描SBOM中的漏洞

grype sbom:sbom-cyclonedx.json
grype sbom:sbom-cyclonedx.json

Fail on critical/high vulnerabilities

遇到严重/高危漏洞时终止

grype sbom:sbom-cyclonedx.json --fail-on high
grype sbom:sbom-cyclonedx.json --fail-on high

Output as JSON for CI processing

以JSON格式输出供CI处理

grype sbom:sbom-cyclonedx.json -o json > vulnerability-report.json
grype sbom:sbom-cyclonedx.json -o json > vulnerability-report.json

Scan container image directly

直接扫描容器镜像

grype ghcr.io/acme/api:v1.2.3
grype ghcr.io/acme/api:v1.2.3

Use Trivy with SBOM input

将SBOM作为输入使用Trivy扫描

trivy sbom sbom-cyclonedx.json
trivy sbom sbom-cyclonedx.json

Trivy scan with severity filter

使用Trivy扫描并按严重性过滤

trivy sbom sbom-cyclonedx.json --severity CRITICAL,HIGH --exit-code 1
undefined
trivy sbom sbom-cyclonedx.json --severity CRITICAL,HIGH --exit-code 1
undefined

Cosign Signing and Attestation

Cosign签名与证明

Image Signing

镜像签名

bash
undefined
bash
undefined

Keyless signing (recommended - uses OIDC identity from CI)

无密钥签名(推荐 - 使用CI中的OIDC身份)

cosign sign ghcr.io/acme/api@sha256:abc123...
cosign sign ghcr.io/acme/api@sha256:abc123...

Sign with a key pair

使用密钥对签名

cosign generate-key-pair cosign sign --key cosign.key ghcr.io/acme/api@sha256:abc123...
cosign generate-key-pair cosign sign --key cosign.key ghcr.io/acme/api@sha256:abc123...

Verify keyless signature

验证无密钥签名

cosign verify
--certificate-identity=https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
ghcr.io/acme/api@sha256:abc123...
cosign verify
--certificate-identity=https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
ghcr.io/acme/api@sha256:abc123...

Verify with key

使用密钥验证

cosign verify --key cosign.pub ghcr.io/acme/api@sha256:abc123...
undefined
cosign verify --key cosign.pub ghcr.io/acme/api@sha256:abc123...
undefined

SBOM Attestation

SBOM证明

bash
undefined
bash
undefined

Attach SBOM as an in-toto attestation to a container image

将SBOM作为in-toto证明附加到容器镜像

cosign attest --predicate sbom-cyclonedx.json
--type cyclonedx
ghcr.io/acme/api@sha256:abc123...
cosign attest --predicate sbom-cyclonedx.json
--type cyclonedx
ghcr.io/acme/api@sha256:abc123...

Attach SPDX SBOM

附加SPDX格式SBOM

cosign attest --predicate sbom-spdx.json
--type spdx
ghcr.io/acme/api@sha256:abc123...
cosign attest --predicate sbom-spdx.json
--type spdx
ghcr.io/acme/api@sha256:abc123...

Verify SBOM attestation

验证SBOM证明

cosign verify-attestation
--type cyclonedx
--certificate-identity=https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
ghcr.io/acme/api@sha256:abc123...
cosign verify-attestation
--type cyclonedx
--certificate-identity=https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
ghcr.io/acme/api@sha256:abc123...

Extract the SBOM from attestation

从证明中提取SBOM

cosign verify-attestation --type cyclonedx
--certificate-identity=... --certificate-oidc-issuer=...
ghcr.io/acme/api@sha256:abc123... | jq -r '.payload' | base64 -d | jq '.predicate'
undefined
cosign verify-attestation --type cyclonedx
--certificate-identity=... --certificate-oidc-issuer=...
ghcr.io/acme/api@sha256:abc123... | jq -r '.payload' | base64 -d | jq '.predicate'
undefined

In-toto Provenance Attestation

In-toto来源证明

bash
undefined
bash
undefined

Create a custom provenance attestation

创建自定义来源证明

cat > provenance.json << 'EOF' { "buildType": "https://github.com/acme/build-system@v1", "builder": { "id": "https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main" }, "invocation": { "configSource": { "uri": "git+https://github.com/acme/api@refs/heads/main", "digest": { "sha1": "abc123def456" }, "entryPoint": ".github/workflows/build.yml" } }, "metadata": { "buildStartedOn": "2025-01-15T10:00:00Z", "buildFinishedOn": "2025-01-15T10:05:00Z", "completeness": { "parameters": true, "environment": true, "materials": true } }, "materials": [ { "uri": "git+https://github.com/acme/api@refs/heads/main", "digest": { "sha1": "abc123def456" } }, { "uri": "pkg:docker/python@3.11-slim", "digest": { "sha256": "def456..." } } ] } EOF
cat > provenance.json << 'EOF' { "buildType": "https://github.com/acme/build-system@v1", "builder": { "id": "https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main" }, "invocation": { "configSource": { "uri": "git+https://github.com/acme/api@refs/heads/main", "digest": { "sha1": "abc123def456" }, "entryPoint": ".github/workflows/build.yml" } }, "metadata": { "buildStartedOn": "2025-01-15T10:00:00Z", "buildFinishedOn": "2025-01-15T10:05:00Z", "completeness": { "parameters": true, "environment": true, "materials": true } }, "materials": [ { "uri": "git+https://github.com/acme/api@refs/heads/main", "digest": { "sha1": "abc123def456" } }, { "uri": "pkg:docker/python@3.11-slim", "digest": { "sha256": "def456..." } } ] } EOF

Attach provenance attestation

附加来源证明

cosign attest --predicate provenance.json
--type slsaprovenance
ghcr.io/acme/api@sha256:abc123...
undefined
cosign attest --predicate provenance.json
--type slsaprovenance
ghcr.io/acme/api@sha256:abc123...
undefined

CI/CD Pipeline Integration

CI/CD流水线集成

yaml
undefined
yaml
undefined

.github/workflows/sbom-supply-chain.yml

.github/workflows/sbom-supply-chain.yml

name: Build with SBOM and Signing on: push: tags: ['v*']
permissions: contents: read packages: write id-token: write # Required for keyless signing
jobs: build-sign-attest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v3

  - name: Login to GHCR
    uses: docker/login-action@v3
    with:
      registry: ghcr.io
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}

  - name: Build and push image
    id: build
    uses: docker/build-push-action@v5
    with:
      push: true
      tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}

  - name: Install tools
    run: |
      curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
      curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin

  - name: Generate SBOM
    run: |
      syft ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }} \
        -o cyclonedx-json=sbom-cdx.json \
        -o spdx-json=sbom-spdx.json

  - name: Scan SBOM for vulnerabilities
    run: |
      grype sbom:sbom-cdx.json --fail-on critical -o json > vuln-report.json

  - name: Install cosign
    uses: sigstore/cosign-installer@v3

  - name: Sign image (keyless)
    run: |
      cosign sign ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

  - name: Attach SBOM attestation
    run: |
      cosign attest --predicate sbom-cdx.json \
        --type cyclonedx \
        ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

  - name: Upload artifacts
    uses: actions/upload-artifact@v4
    with:
      name: sbom-and-reports
      path: |
        sbom-cdx.json
        sbom-spdx.json
        vuln-report.json
undefined
name: Build with SBOM and Signing on: push: tags: ['v*']
permissions: contents: read packages: write id-token: write # 无密钥签名所需权限
jobs: build-sign-attest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v3

  - name: Login to GHCR
    uses: docker/login-action@v3
    with:
      registry: ghcr.io
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}

  - name: Build and push image
    id: build
    uses: docker/build-push-action@v5
    with:
      push: true
      tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}

  - name: Install tools
    run: |
      curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
      curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin

  - name: Generate SBOM
    run: |
      syft ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }} \
        -o cyclonedx-json=sbom-cdx.json \
        -o spdx-json=sbom-spdx.json

  - name: Scan SBOM for vulnerabilities
    run: |
      grype sbom:sbom-cdx.json --fail-on critical -o json > vuln-report.json

  - name: Install cosign
    uses: sigstore/cosign-installer@v3

  - name: Sign image (keyless)
    run: |
      cosign sign ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

  - name: Attach SBOM attestation
    run: |
      cosign attest --predicate sbom-cdx.json \
        --type cyclonedx \
        ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

  - name: Upload artifacts
    uses: actions/upload-artifact@v4
    with:
      name: sbom-and-reports
      path: |
        sbom-cdx.json
        sbom-spdx.json
        vuln-report.json
undefined

Policy Enforcement

策略强制执行

Kyverno Policy: Require Signed Images with SBOM

Kyverno策略:要求带SBOM的签名镜像

yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-signed-images-with-sbom
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds: ["Pod"]
      verifyImages:
        - imageReferences: ["ghcr.io/acme/*"]
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/acme/*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: "https://rekor.sigstore.dev"
          attestations:
            - type: cyclonedx
              conditions:
                - all:
                    - key: "{{ components[].name }}"
                      operator: AllNotIn
                      value: ["log4j-core"]
yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-signed-images-with-sbom
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds: ["Pod"]
      verifyImages:
        - imageReferences: ["ghcr.io/acme/*"]
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/acme/*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: "https://rekor.sigstore.dev"
          attestations:
            - type: cyclonedx
              conditions:
                - all:
                    - key: "{{ components[].name }}"
                      operator: AllNotIn
                      value: ["log4j-core"]

OPA Policy: Verify SBOM Before Deploy

OPA策略:部署前验证SBOM

rego
package sbom.verify

import rego.v1

default allow := false

allow if {
    sbom_present
    no_critical_vulns
    signed_by_ci
}

sbom_present if {
    input.attestations.cyclonedx != null
    count(input.attestations.cyclonedx.components) > 0
}

no_critical_vulns if {
    not any_critical
}

any_critical if {
    some vuln in input.vulnerability_report.matches
    vuln.vulnerability.severity == "Critical"
    vuln.vulnerability.fix.state == "fixed"
}

signed_by_ci if {
    input.signature.issuer == "https://token.actions.githubusercontent.com"
    startswith(input.signature.subject, "https://github.com/acme/")
}
rego
package sbom.verify

import rego.v1

default allow := false

allow if {
    sbom_present
    no_critical_vulns
    signed_by_ci
}

sbom_present if {
    input.attestations.cyclonedx != null
    count(input.attestations.cyclonedx.components) > 0
}

no_critical_vulns if {
    not any_critical
}

any_critical if {
    some vuln in input.vulnerability_report.matches
    vuln.vulnerability.severity == "Critical"
    vuln.vulnerability.fix.state == "fixed"
}

signed_by_ci if {
    input.signature.issuer == "https://token.actions.githubusercontent.com"
    startswith(input.signature.subject, "https://github.com/acme/")
}

Troubleshooting

故障排查

ProblemCauseSolution
Syft misses dependenciesUnsupported package manager or formatCheck syft catalogers list; use
cdxgen
for deeper analysis; contribute upstream
Cosign sign fails with "no identity token"Missing OIDC provider in CIEnsure
id-token: write
permission in GitHub Actions; check OIDC provider config
Grype reports false positivesPackage version detection incorrectVerify SBOM accuracy; report to grype GitHub; add ignore rules for confirmed FPs
SBOM attestation too largeLarge image with many dependenciesCompress SBOM; use SPDX compact format; consider splitting per layer
Verification fails in admission controllerWrong identity or issuer URLCheck exact
--certificate-identity
and
--certificate-oidc-issuer
values
cdxgen produces empty SBOMProject type not detectedSpecify type explicitly with
-t
; ensure manifest files (package.json, etc.) exist
问题原因解决方案
Syft遗漏依赖项不支持的包管理器或格式查看syft目录器列表;使用
cdxgen
进行深度分析;向上游贡献支持
Cosign签名失败并提示“no identity token”CI中缺少OIDC提供者在GitHub Actions中确保
id-token: write
权限;检查OIDC提供者配置
Grype报告误报包版本检测错误验证SBOM准确性;向Grype的GitHub仓库提交报告;为已确认的误报添加忽略规则
SBOM证明过大镜像包含大量依赖项压缩SBOM;使用SPDX紧凑格式;考虑按层拆分
准入控制器中验证失败身份或发行者URL错误检查
--certificate-identity
--certificate-oidc-issuer
的准确值
cdxgen生成空SBOM未检测到项目类型使用
-t
显式指定类型;确保存在清单文件(如package.json等)

Best Practices

最佳实践

  • Generate SBOMs in both CycloneDX and SPDX for maximum compatibility
  • Sign all release artifacts with keyless signing (Sigstore/Fulcio)
  • Attach SBOMs as in-toto attestations to container images
  • Scan SBOMs for vulnerabilities in CI and block on critical findings
  • Archive SBOMs for every release for audit and incident response
  • Enforce signature verification in admission controllers (Kyverno, OPA)
  • Monitor for new CVEs against stored SBOMs continuously
  • Include SBOM generation in every build pipeline, not just releases
  • Track SBOM completeness metrics (percentage of deps captured)
  • Establish a VEX (Vulnerability Exploitability eXchange) process for false positives
  • 同时生成CycloneDX和SPDX格式的SBOM以获得最大兼容性
  • 使用无密钥签名(Sigstore/Fulcio)对所有发布工件进行签名
  • 将SBOM作为in-toto证明附加到容器镜像
  • 在CI中扫描SBOM漏洞,并在发现严重问题时阻止发布
  • 为每个发布版本存档SBOM,用于审计和事件响应
  • 在准入控制器(Kyverno、OPA)中强制执行签名验证
  • 持续监控已存储SBOM的新CVE
  • 在每个构建流水线中都包含SBOM生成,而不仅仅是发布版本
  • 跟踪SBOM完整性指标(捕获的依赖项百分比)
  • 建立VEX(漏洞可利用性交换)流程处理误报

Related Skills

相关技能

  • dependency-scanning - Library vulnerability triage
  • container-scanning - Container CVE scanning
  • policy-as-code - Policy enforcement
  • model-supply-chain-security - ML artifact trust
  • dependency-scanning - 库漏洞分类
  • container-scanning - 容器CVE扫描
  • policy-as-code - 策略强制执行
  • model-supply-chain-security - ML工件信任