SBOM管理Skill sbom-management

SBOM管理技能专注于软件物料清单(SBOM)的全生命周期管理,包括生成、格式转换(如CycloneDX和SPDX)、漏洞跟踪、VEX文档生成和供应链安全。适用于DevOps流程、CI/CD集成,并满足法规合规要求如美国行政命令14028和欧盟CRA。关键词:SBOM, 软件物料清单, 漏洞管理, 供应链安全, DevOps, 合规, CycloneDX, SPDX, 漏洞跟踪, 软件依赖。

DevOps 0 次安装 0 次浏览 更新于 3/11/2026

name: sbom-management description: 软件物料清单管理,包括生成、格式、漏洞跟踪和供应链安全 allowed-tools: Read, Glob, Grep, Write, Edit, Task

SBOM 管理

软件物料清单创建、维护和供应链安全的全面指南。

何时使用此技能

  • 为软件发布创建SBOM
  • 响应客户SBOM请求
  • 跟踪软件组件和依赖
  • 实施供应链安全
  • 满足法规要求(美国行政命令14028,欧盟CRA)

SBOM 基础

什么是SBOM?

软件物料清单是一个正式的、机器可读的软件组件和依赖、它们的关系以及相关元数据的清单。

您的应用程序
├── 依赖 A (v1.2.3) → 传递依赖 X
├── 依赖 B (v2.0.0) → 传递依赖 Y, Z
├── 依赖 C (v3.1.0)
└── 直接代码组件

NTIA 最低元素

根据NTIA SBOM指南的必需元素:

元素 描述 示例
供应商名称 创建/维护的实体 “Microsoft”
组件名称 组件的名称 “System.Text.Json”
版本 版本标识符 “8.0.0”
其他唯一标识符 额外ID PURL, CPE
依赖关系 上游/下游 “依赖”
SBOM数据作者 谁创建了SBOM “Contoso Inc”
时间戳 SBOM创建时间 “2025-01-15T10:30:00Z”

SBOM 格式

格式 优势 用例
CycloneDX 安全导向,支持VEX 漏洞管理
SPDX 许可证导向,ISO标准 许可证合规
SWID 软件标识 资产管理

CycloneDX(推荐)

基本结构

{
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "version": 1,
  "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
  "metadata": {
    "timestamp": "2025-01-15T10:30:00Z",
    "tools": [
      {
        "vendor": "CycloneDX",
        "name": "cyclonedx-dotnet",
        "version": "3.0.0"
      }
    ],
    "component": {
      "type": "application",
      "name": "MyApplication",
      "version": "1.0.0"
    }
  },
  "components": [
    {
      "type": "library",
      "bom-ref": "pkg:nuget/Newtonsoft.Json@13.0.3",
      "name": "Newtonsoft.Json",
      "version": "13.0.3",
      "purl": "pkg:nuget/Newtonsoft.Json@13.0.3",
      "licenses": [
        {
          "license": {
            "id": "MIT"
          }
        }
      ],
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "a5c9a4e..."
        }
      ]
    }
  ],
  "dependencies": [
    {
      "ref": "pkg:nuget/MyApplication@1.0.0",
      "dependsOn": [
        "pkg:nuget/Newtonsoft.Json@13.0.3"
      ]
    }
  ]
}

组件类型

应用程序    - 独立应用程序
框架      - 软件框架
库        - 软件库
容器      - 容器镜像
操作系统
设备         - 硬件设备
固件       - 设备固件
文件       - 任意文件
机器学习模型
数据       - 数据资产

.NET SBOM 生成

使用 CycloneDX 工具

# 安装工具
dotnet tool install --global CycloneDX

# 为解决方案生成SBOM
dotnet CycloneDX MyApp.sln -o sbom.json -j

# 包括开发依赖
dotnet CycloneDX MyApp.sln -o sbom.json -j --include-dev

# 递归为所有项目
dotnet CycloneDX . -o sbom.json -j -r

与构建集成

<!-- 添加到 Directory.Build.props -->
<PropertyGroup>
  <GenerateSBOM>true</GenerateSBOM>
  <SBOMFormat>CycloneDX</SBOMFormat>
</PropertyGroup>

<!-- MSBuild 目标 -->
<Target Name="GenerateSBOM" AfterTargets="Build" Condition="'$(GenerateSBOM)'=='true'">
  <Exec Command="dotnet CycloneDX $(MSBuildProjectFullPath) -o $(OutputPath)sbom.json -j" />
</Target>

程序化生成

using CycloneDX.Models;

public class SbomGenerator
{
    public Bom GenerateSbom(Project project, IEnumerable<PackageReference> packages)
    {
        var bom = new Bom
        {
            Version = 1,
            SerialNumber = $"urn:uuid:{Guid.NewGuid()}",
            Metadata = new Metadata
            {
                Timestamp = DateTime.UtcNow,
                Component = new Component
                {
                    Type = Component.Classification.Application,
                    Name = project.Name,
                    Version = project.Version
                }
            },
            Components = new List<Component>()
        };

        foreach (var pkg in packages)
        {
            bom.Components.Add(new Component
            {
                Type = Component.Classification.Library,
                BomRef = $"pkg:nuget/{pkg.Id}@{pkg.Version}",
                Name = pkg.Id,
                Version = pkg.Version,
                Purl = $"pkg:nuget/{pkg.Id}@{pkg.Version}",
                Licenses = pkg.Licenses?.Select(l => new LicenseChoice
                {
                    License = new License { Id = l }
                }).ToList()
            });
        }

        return bom;
    }
}

漏洞管理

VEX(漏洞可利用性交换)

VEX文档说明漏洞是否适用于您的产品:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "vulnerabilities": [
    {
      "id": "CVE-2023-12345",
      "source": {
        "name": "NVD",
        "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-12345"
      },
      "ratings": [
        {
          "severity": "high",
          "score": 7.5,
          "method": "CVSSv3"
        }
      ],
      "analysis": {
        "state": "not_affected",
        "justification": "code_not_reachable",
        "detail": "易受攻击的代码路径未在我们的实现中使用"
      },
      "affects": [
        {
          "ref": "pkg:nuget/SomePackage@1.0.0"
        }
      ]
    }
  ]
}

VEX 状态

状态 含义
exploitable 漏洞可利用
in_triage 正在调查
not_affected 不受影响
resolved 当前版本已修复

漏洞跟踪服务

public class VulnerabilityTracker
{
    private readonly IVulnerabilityDatabase _vulnDb;
    private readonly ISbomRepository _sbomRepo;

    public async Task<VulnerabilityReport> ScanSbom(
        string sbomPath,
        CancellationToken ct)
    {
        var sbom = await _sbomRepo.Load(sbomPath, ct);
        var report = new VulnerabilityReport
        {
            SbomSerialNumber = sbom.SerialNumber,
            ScanTimestamp = DateTimeOffset.UtcNow
        };

        foreach (var component in sbom.Components)
        {
            var vulns = await _vulnDb.GetVulnerabilities(
                component.Purl,
                ct);

            foreach (var vuln in vulns)
            {
                report.Vulnerabilities.Add(new VulnerabilityFinding
                {
                    ComponentRef = component.BomRef,
                    ComponentName = component.Name,
                    ComponentVersion = component.Version,
                    CveId = vuln.Id,
                    Severity = vuln.Severity,
                    CvssScore = vuln.CvssScore,
                    Description = vuln.Description,
                    FixedInVersion = vuln.FixedInVersion,
                    VexStatus = DetermineVexStatus(component, vuln)
                });
            }
        }

        return report;
    }

    private VexStatus DetermineVexStatus(Component component, Vulnerability vuln)
    {
        // 检查是否存在现有的VEX确定
        // 否则标记为 in_triage
        return VexStatus.InTriage;
    }
}

供应链安全

SLSA(软件工件供应链级别)

级别 要求
SLSA 1 构建过程文档化,生成来源证明
SLSA 2 版本控制,托管构建服务
SLSA 3 强化构建,验证来源证明
SLSA 4 双人审核,密封构建

包验证

public class PackageIntegrityVerifier
{
    public async Task<VerificationResult> VerifyPackage(
        PackageReference package,
        CancellationToken ct)
    {
        var result = new VerificationResult { Package = package };

        // 检查包签名
        var signature = await GetPackageSignature(package, ct);
        if (signature != null)
        {
            result.IsSigned = true;
            result.SignatureValid = await VerifySignature(signature, ct);
            result.SignerCertificate = signature.Certificate;
        }

        // 根据已知良好来源验证哈希
        var packageHash = await ComputePackageHash(package, ct);
        var expectedHash = await GetExpectedHash(package, ct);
        result.HashMatch = packageHash == expectedHash;

        // 检查已知漏洞
        result.Vulnerabilities = await ScanForVulnerabilities(package, ct);

        // 检查包年龄和维护状态
        result.LastUpdated = await GetLastUpdateDate(package, ct);
        result.IsDeprecated = await CheckDeprecationStatus(package, ct);

        return result;
    }
}

依赖锁定

<!-- 启用包锁文件以实现可重复构建 -->
<PropertyGroup>
  <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
  <RestoreLockedMode Condition="'$(CI)' == 'true'">true</RestoreLockedMode>
</PropertyGroup>

CI/CD 集成

GitHub Actions SBOM 生成

name: 生成 SBOM

on:
  release:
    types: [published]

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

      - name: 设置 .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '10.0.x'

      - name: 安装 CycloneDX
        run: dotnet tool install --global CycloneDX

      - name: 生成 SBOM
        run: |
          dotnet CycloneDX MySolution.sln \
            -o sbom.json \
            -j \
            --set-version ${{ github.event.release.tag_name }}

      - name: 签名 SBOM
        run: |
          # 使用 cosign 或类似工具签名
          cosign sign-blob --key ${{ secrets.SIGNING_KEY }} sbom.json

      - name: 上传 SBOM 到发布
        uses: actions/upload-release-asset@v1
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: ./sbom.json
          asset_name: sbom.json
          asset_content_type: application/json

      - name: 扫描漏洞
        run: |
          grype sbom:sbom.json --fail-on high

SBOM 证明

      - name: 生成 SBOM 证明
        uses: actions/attest-sbom@v1
        with:
          subject-path: './bin/MyApp.dll'
          sbom-path: './sbom.json'

SBOM 分发

发布位置

渠道 格式 受众
发布资产 JSON/XML 开发人员、安全团队
API 端点 JSON 自动化系统
文档 人类可读 审计员、客户
容器标签 参考 容器运行时

容器集成

# 在容器中包含 SBOM
LABEL org.opencontainers.image.sbom="sbom.json"
COPY sbom.json /app/sbom.json

# 或在构建时生成
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
RUN dotnet tool install --global CycloneDX
RUN dotnet CycloneDX /src/MyApp.csproj -o /app/sbom.json -j

法规要求

美国行政命令 14028

对美国政府销售的软件的要求:

  • 所有软件必须提供SBOM
  • 必须包括所有组件
  • 机器可读格式(SPDX、CycloneDX)
  • VEX 用于漏洞状态
  • 定期更新

欧盟网络弹性法案

即将实施的要求:

  • 所有包含数字元素的产品提供SBOM
  • 漏洞处理程序
  • 产品生命周期内的安全更新
  • 报告被积极利用的漏洞

SBOM 检查清单

生成

  • [ ] 包括所有直接依赖
  • [ ] 解析传递依赖
  • [ ] 准确记录版本
  • [ ] 识别许可证
  • [ ] 计算哈希
  • [ ] 生成PURL

质量

  • [ ] 存在NTIA最低元素
  • [ ] 机器可读格式
  • [ ] 符合架构
  • [ ] 准确的依赖图
  • [ ] 与实际部署的软件匹配

分发

  • [ ] 包含在发布资产中
  • [ ] 可通过API获取(如适用)
  • [ ] 签名/证明
  • [ ] VEX文档可用
  • [ ] 客户访问方法文档化

交叉引用

  • 许可证合规license-compliance 用于许可证义务
  • 安全security-frameworks 用于供应链安全
  • AI治理ai-governance 用于ML模型SBOM

资源