出海企业软件供应链安全实战:容器镜像签名 + SBOM + SLSA 防护指南(2026版)
Meta Description: 出海企业软件供应链安全完整落地指南:cosign 给镜像签名、syft 生成 SBOM、Trivy 漏洞门禁、Kyverno 准入校验,一套命令把阿里云 ACR 与 AWS ECR 的供应链防线建起来。
- 前言
- 软件供应链攻击为什么防不住
- 供应链安全全景架构
- 核心工具链与方案对比
- 第一步:容器镜像签名(cosign 实战)
- 第二步:SBOM 生成与制品溯源
- 第三步:把安全门禁装进 CI/CD 流水线
- 多云镜像仓库安全能力对比(阿里云 ACR / AWS ECR / 腾讯云 TCR)
Meta Description: 出海企业软件供应链安全完整落地指南:cosign 给镜像签名、syft 生成 SBOM、Trivy 漏洞门禁、Kyverno 准入校验,一套命令把阿里云 ACR 与 AWS ECR 的供应链防线建起来。附工具对比表、价格表与 FAQ。
关键词: 软件供应链安全、容器镜像签名、cosign、SBOM、SLSA、Trivy、Kyverno、多云安全
前言
软件供应链安全的落地答案是:把"可信"变成每一环可验证的工程动作——用 cosign 给每个镜像签名、用 syft 为每个镜像生成 SBOM、在 CI 里用 Trivy 卡住高危漏洞、再用 Kyverno 在集群准入时强制校验签名——让"从代码提交到生产运行"的每一跳都有可审计的证据。 本文是《出海企业 CI/CD 流水线搭建实战》的安全续篇:上一篇文章我们搭好了 GitHub Actions + 容器化 + 双推 ACR/ECR 的发布管道,但流水线只解决"能不能发布",不解决"发布的东西可不可信"。2026 年出海企业面对的已经不是"要不要做供应链安全",而是"攻击者已经用自动化手段投毒,你的仓库和集群凭什么挡得住"。
为什么单独用一整篇讲供应链安全?因为 2021 年的 Log4j、2024 年的 xz-utils 后门、2025 年以来 PyPI/npm 生态的高频投毒,本质是同一类问题:企业消费了大量开源组件与第三方镜像,却没有任何机制验证"我拿到的这一份"就是"作者发布的那一份"。镜像一旦被替换成恶意版本,你的 ACK/EKS 集群、生产数据库、客户数据全部暴露。本文按"威胁 → 架构 → 工具对比 → 签名实战 → SBOM 实战 → 流水线门禁 → 多云仓库对比 → 价格 → SLSA 等级"的顺序展开,命令全部可直接复制。
一、软件供应链攻击为什么防不住
先看攻击链条。一个容器镜像从作者到你的生产集群,中间隔着代码仓库、构建机、镜像仓库、拉取节点四个环节,任何一环被劫持都是灾难:
graph TD
A[上游依赖: npm/PyPI/Maven/GitHub] --> B[构建机/CI 流水线]
C[源码仓库被入侵] --> B
B --> D[镜像仓库 ACR/ECR]
E[仓库凭据泄露/仓库投毒] --> D
D --> F[K8s 集群 ACK/EKS]
F --> G[生产业务与数据]
H[开发者本机被入侵] --> C
攻击者常用的五条路径:
- 依赖投毒:往开源生态上传名字相似的恶意包,等待开发者拼错自动拉取(typosquatting);或先"养号"发布几个正常版本积累信任,再在某次更新里注入后门。
- 构建劫持:CI 流水线引用了被攻破的第三方 Action 或构建镜像,恶意代码在构建阶段被打进产物。
- 仓库投毒/替换:拿到镜像仓库凭据后,把正常 tag 覆盖成恶意镜像;或企业内网 DNS 被劫持,拉取请求被导向伪造的仓库地址。
- 运行期绕过:集群拉取的镜像没有签名校验,攻击者只要能在任意一环替换镜像,K8s 就会"照单全收"。
- 供应链下游蔓延:你发布的镜像又成为别人的上游——镜像被污染后,受害范围按依赖树指数扩散。
传统安全方案(防火墙、WAF、EDR)全都防不住这类攻击,原因在于它们只保护"边界"而不验证"内容":防火墙不知道镜像里的可执行文件是谁写的,WAF 不检查部署清单里的镜像 tag 是否被篡改。唯一有效的思路是内容验证(Content Trust):给镜像签名 + 生成 SBOM + 准入强制校验。
二、供应链安全全景架构
目标架构分四层:构建层(签名 + SBOM 生产)、仓库层(不可变 tag + artifact 存储)、准入层(集群校验签名与漏洞)、审计层(签名日志 + SBOM 归档)。下面用两张图说明。
graph TD
A[GitHub Actions 流水线] --> B[构建镜像]
B --> C[Trivy 漏洞扫描 - 高危即失败]
B --> D[syft 生成 SBOM]
B --> E[cosign 签名 keyless]
D --> F[SBOM 上传仓库 OCI artifact]
E --> F
F --> G[ACR / ECR 不可变 tag]
G --> H[Kubernetes 准入控制 Kyverno]
H -->|签名+漏洞双重校验| I[Pod 调度到节点]
F --> J[审计归档与合规报表]
ASCII 图展示"谁持有什么证据",方便贴进架构评审文档:
┌──────────────────────────────────────────────────────────────┐
│ CI 流水线 (GitHub Actions) │
│ 源码 ──► 构建镜像 ──► Trivy 扫描(高危拒绝) │
│ │ │ │
│ ▼ ▼ │
│ cosign 签名 syft 生成 SBOM ──► cosign attach │
│ │ │ │
└──────────────┼────────────────────────────┼───────────────────┘
▼ ▼
┌──────────────────────────────────────────────────────────────┐
│ 镜像仓库 (阿里云 ACR / AWS ECR) │
│ 不可变 tag + 签名 OCI artifact + SBOM artifact │
└──────────────────────────┬───────────────────────────────────┘
▼ 拉取
┌──────────────────────────────────────────────────────────────┐
│ K8s 集群准入 (Kyverno / OPA Gatekeeper) │
│ 1. 校验 cosign 签名有效 2. 校验漏洞低于阈值 │
│ 不满足 = 拒绝调度 │
└──────────────────────────────────────────────────────────────┘
设计要点:签名和 SBOM 与镜像一起存放在同一个仓库(作为 OCI artifact),这样"镜像 + 证据"永远不分离;校验发生在两个时点——CI 发布时自检一次,集群准入时再强制一次。后者的存在意味着:即使有人绕过 CI 直接往仓库塞镜像,集群也不会执行。
三、核心工具链与方案对比
生态里的工具已经成熟,选型表如下(全部开源、2026 年仍在活跃维护):
| 环节 | 工具 | 作用 | 替代方案 |
|---|---|---|---|
| 镜像签名 | cosign | 给镜像签名/验签,支持 keyless | Notation(微软主导)、Docker Content Trust |
| SBOM 生成 | syft(Anchore) | 从镜像生成 SPDX/CycloneDX 清单 | Trivy 内置 SBOM、SBOM-TOOL(微软) |
| 漏洞扫描 | Trivy(Aqua) | 镜像/依赖漏洞扫描,输出门禁 | Grype、Clair、ACR/ECR 内置扫描 |
| 签名背书验证 | slsa-verifier | 验证 SLSA 来源与构建方 | in-toto 框架 |
| 准入控制 | Kyverno | 集群侧强制签名+漏洞策略 | OPA Gatekeeper、ACR 交付链、EKS Image Policy |
选型建议:签名用 cosign(keyless 模式)+ 扫描用 Trivy + SBOM 用 syft + 准入用 Kyverno,这是目前社区事实标准,四个工具全部免费,且与阿里云 ACR、AWS ECR、腾讯云 TCR 都能配合。Notation 在微软生态与 AKS 集成度更高,但跨云通用性和社区资料不如 cosign。
四、第一步:容器镜像签名(cosign 实战)
签名解决"这个镜像到底是不是我们构建的"。cosign 有两种模式:
模式一:本地密钥对(适合小团队、私有场景)
// 生成密钥对(cosign.key 私钥 / cosign.pub 公钥)
cosign generate-key-pair
// 签名并推送(签名作为 OCI artifact 存入仓库)
cosign sign --key cosign.key registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:20260811-001
// 任何一方用公钥验签
cosign verify --key cosign.pub registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:20260811-001
注意:私钥要放进云厂商的密钥管理服务(阿里云 KMS / AWS KMS),不要出现在构建机上。
模式二:keyless(无密钥,推荐)——利用 GitHub Actions 的 OIDC 身份直接向 sigstore 免费公证服务签名,不需要管理任何私钥,签名里自动携带"是谁在哪个流水线构建的"信息:
// 在 CI 里(GitHub Actions 环境自动注入 OIDC token)
cosign sign --yes registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:$GITHUB_SHA
// 验签:校验签名主体必须是你们组织的发布工作流
cosign verify \
--certificate-identity "https://github.com/your-org/webapp/.github/workflows/sign.yml@refs/tags/*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:$GITHUB_SHA
keyless 的信任模型更优:没有私钥可泄露,签名证据(透明日志)公开可查,任何审计都能复现"这个镜像确实出自你们流水线"。它和《多云统一身份认证》一文讲的 OIDC 联邦是同一套机制——流水线不再持有长期密钥,身份即凭证。
仓库侧配合:
- 阿里云 ACR:镜像仓库开启"不可变 tag",防止 tag 被覆盖;ACR 企业版支持配置 cosign 公钥并启用"仅允许已签名镜像拉取"的仓库策略。
- AWS ECR:创建仓库时指定不可变 tag(
imageTagMutability: IMMUTABLE),并在仓库策略中收紧推拉权限,只允许 CI 角色写入。
五、第二步:SBOM 生成与制品溯源
SBOM(软件物料清单)回答"这个镜像里到底有什么"。它列出一个镜像内所有组件、版本、许可证与依赖关系,是漏洞响应的前提——Log4j 事件里,没有 SBOM 的企业要花数周排查哪些镜像受影响,有 SBOM 的企业几分钟定位。
// 从镜像生成 SPDX 格式 SBOM
syft registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:20260811-001 -o spdx-json=webapp.spdx.json
// 或直接生成 CycloneDX 格式
syft registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:20260811-001 -o cyclonedx-json=webapp.cdx.json
// 把 SBOM 作为 OCI artifact 附到镜像上,与镜像共存
cosign attach sbom --sbom webapp.spdx.json --type spdx registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:20260811-001
// 事后随时取出 SBOM 核对
cosign download sbom registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:20260811-001
SBOM 的三个使用场景:漏洞应急(新漏洞公布后按组件名批量检索受影响镜像);许可合规(检查 GPL/AGPL 组件是否混入商业闭源产品);客户审计(出海客户、海外合作方普遍要求提供依赖清单,ISO 27001 / SOC 2 审计直接采信 SBOM 归档)。
六、第三步:把安全门禁装进 CI/CD 流水线
把签名、SBOM、扫描串进《CI/CD 流水线搭建》一文的工作流。完整 workflow 如下(沿用上一篇文章的 OIDC 免密钥与双推结构,新增三道安全关卡):
name: build-sign-publish
on:
push:
tags: ['v*']
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-southeast-1
role-to-assume: arn:aws:iam::123456789012:role/gha-ecr-push
- uses: docker/login-action@v3
with:
registry: registry-intl.ap-southeast-1.aliyuncs.com
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
- uses: docker/login-action@v3
with:
registry: 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com
- uses: sigstore/cosign-installer@v3
- run: docker build -t webapp:${{ github.sha }} .
- run: docker push registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:${{ github.sha }}
- run: docker push 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team/webapp:${{ github.sha }}
- run: trivy image --severity HIGH,CRITICAL --exit-code 1 --ignore-unfixed webapp:${{ github.sha }}
- run: syft webapp:${{ github.sha }} -o spdx-json=webapp.spdx.json
- run: cosign attach sbom --sbom webapp.spdx.json --type spdx registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:${{ github.sha }}
- run: cosign sign --yes registry-intl.ap-southeast-1.aliyuncs.com/team/webapp:${{ github.sha }}
- run: cosign sign --yes 123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team/webapp:${{ github.sha }}
三道门禁:Trivy 扫描(存在 HIGH/CRITICAL 漏洞直接非零退出,阻断发布);SBOM 生成并附着(证据入库);cosign keyless 签名(双云仓库各自签名,因为签名与仓库一一绑定)。注意 --ignore-unfixed:只拦截"已有修复版本"的高危漏洞,避免因为上游还没发补丁而永久卡死发布。
集群侧准入校验用 Kyverno,策略如下(不满足签名或漏洞要求的 Pod 直接拒绝调度):
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-cosign-signature
spec:
validationFailureAction: Enforce
webhookTimeoutSeconds: 30
rules:
- name: check-cosign
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry-intl.ap-southeast-1.aliyuncs.com/team/*"
- "123456789012.dkr.ecr.ap-southeast-1.amazonaws.com/team/*"
attestors:
- count: 1
entries:
- keyless:
subject: "https://github.com/your-org/webapp/.github/workflows/build-sign-publish.yml@refs/tags/*"
issuer: "https://token.actions.githubusercontent.com"
落地顺序建议:先在审计模式(validationFailureAction: Audit)观察一周,确认没有误伤,再切到 Enforce 强制模式。
七、多云镜像仓库安全能力对比(阿里云 ACR / AWS ECR / 腾讯云 TCR)
| 能力 | 阿里云 ACR(国际版) | AWS ECR | 腾讯云 TCR(国际版) |
|---|---|---|---|
| 免费层 | 个人版免费 | 无实例费,按存储+流量计费 | 个人版免费 |
| 不可变 tag | 支持 | 支持(创建时指定) | 支持 |
| 内置漏洞扫描 | 支持(企业版) | 支持(增强扫描) | 支持(企业版) |
| cosign 签名支持 | 支持(企业版交付链) | 支持(配合 Kyverno/OPA) | 支持(配合集群准入) |
| OCI artifact(SBOM 存储) | 支持 | 支持 | 支持 |
| 仓库访问策略 | RAM 授权 + 仓库策略 | IAM 资源策略 | CAM 授权 |
| 私有网络访问 | VPC 内网 + PrivateLink | VPC Endpoint | VPC 内网 |
| 跨区域同步 | 支持(同账号/跨账号) | 支持(跨区域复制) | 支持 |
| 与集群集成 | ACK 原生集成 | EKS 原生集成 | TKE 原生集成 |
结论:三家的"仓库本体"能力基本对齐,差异主要在配套生态——如果你已经在用 ACK 就选 ACR,用 EKS 就选 ECR,双云就两个都推(这正是上一篇文章的架构)。供应链安全的胜负手不在仓库而在流水线和准入层,那两层的工具(cosign/syft/Trivy/Kyverno)与云厂商无关、完全通用。
八、参考价格(新加坡区域)
| 项目 | 阿里云 ACR | AWS ECR | 腾讯云 TCR |
|---|---|---|---|
| 免费额度 | 个人版免费 | 存储 $0.10/GB/月,出流量 100GB/月免费 | 个人版免费 |
| 企业版起步价 | 基础版约 ¥200/月(约 $28) | 无实例费用 | 基础版约 ¥300/月(约 $42) |
| 超出流量 | 按区域流量计费 | $0.09/GB | 按区域流量计费 |
| 漏洞扫描 | 企业版内置 | 增强扫描按扫描次数计费 | 企业版内置 |
价格仅为参考,实际以官网实时报价为准。对多数出海团队,最优解是 ACR 个人版 + ECR 按量付费的组合——签名、SBOM、Trivy、Kyverno 这些核心安全能力全部免费开源,仓库本身的费用通常不到整体云账单的 1%。
九、从 L1 到 L4:SLSA 等级落地路径
SLSA(软件供应链等级)是衡量供应链安全成熟度的行业标准,共 L1-L4 四级。对出海企业,达到 L3 是接海外订单的加分项,达到 L4 是金融/政务客户的准入门槛。
| 等级 | 要求 | 落地动作 | 难度 |
|---|---|---|---|
| L1 | 构建过程可追溯 | 版本控制 + CI 记录构建来源 | 低 |
| L2 | 构建托管 + 签名 | 用托管 CI(GitHub Actions)+ cosign 签名 | 低 |
| L3 | 构建隔离 + 可验证来源 | 独立构建环境 + keyless 签名 + 防篡改产物 | 中 |
| L4 | 全链路可审计 | 双人评审 + 密闭构建 + 透明日志全记录 | 高 |
本文的落地组合(keyless 签名 + 构建机托管 + SBOM 归档)实际上已经把团队带到 L3:构建在 GitHub 托管环境完成、签名携带可验证来源、透明日志公开可审计。L4 需要密闭构建(Hermetic Build)与更严格的评审流程,属增量优化,不必一步到位。
十、常见问题 FAQ
Q1: cosign 和 Notation 到底选哪个?
选 cosign。理由:跨云通用性最好(ACR/ECR/TCR 与自建 Harbor 都支持)、keyless 模式免密钥管理、社区资料与工具链最全。Notation 在纯微软生态(Azure + AKS + ACR)里体验更顺滑,但一旦涉及多云或自建仓库,生态配套明显薄弱。
Q2: keyless 模式没有私钥,安全性会不会更差?
不会,反而更好。keyless 把"信任"从"你保管私钥"转移为"你的 CI 身份(OIDC)由可信身份提供商认证",签名证据写入 sigstore 透明日志,任何篡改都会被公开记录。私钥模式最大的风险恰恰是私钥泄露后无人知晓——keyless 模式从机制上消灭了这个风险。
Q3: SBOM 每次构建都要生成吗?成本高不高?
要,而且必须和每次构建绑定。syft 生成一份 SBOM 只需几秒,在 CI 里成本可忽略。SBOM 的价值在于"镜像和它的依赖清单永远一一对应",如果只在发版时补一份,应急时根本无法定位到具体镜像。建议同时把 SBOM 归档到对象存储(OSS/S3)做长期留存。
Q4: 存量老镜像没有签名,怎么处理?
分三步:第一步,准入策略先跑 Audit 模式摸清存量;第二步,对仍然在用的镜像统一补签一次(用当前流水线重新构建发布,或对未变更镜像补签);第三步,设一个 30-60 天的过渡期,之后切 Enforce 强制模式。已经停用超过 90 天的镜像直接清理,不要为僵尸镜像付出合规成本。
Q5: Trivy 扫描告警太多,怎么设阈值才合理?
原则:只对"有修复版本"的 HIGH/CRITICAL 设硬门禁,即 --exit-code 1 --ignore-unfixed;LOW/MEDIUM 记录到工单系统按周处理。完全不设阈值等于把发布卡死,阈值太松等于没有门禁——"高危且可修复"是唯一合理的硬性拦截线。
Q6: 镜像签名之后还能被篡改吗?
篡改会造成"签名失效"而非"篡改成功"。攻击者改了镜像内容,签名校验必然失败,Kyverno 会在准入时拒绝调度。唯一需要警惕的是"合法构建的恶意镜像"(比如 CI 被入侵后构建了后门版本)——这正是 SBOM + 双人评审 + 审计日志存在的原因:让异常构建在流程中暴露,而不是等运行时才发现。
Q7: 国内团队访问 sigstore 服务慢,keyless 签名还能用吗?
能用。keyless 只需要构建机访问 sigstore(GitHub Actions 的海外 runner 访问无压力);国内自建 runner 的团队,可以在 CI 里配置自建 Rekor/Fulcio 服务,或退回私钥模式用 KMS 托管。签名验证动作(cosign verify / Kyverno)在集群侧执行,不依赖 sigstore 在线服务——证书链验证是离线的。
Q8: 供应链安全对出海合规(GDPR/ISO 27001/SOC 2)有什么实际价值?
直接价值有两个:一是审计证据——签名日志、SBOM 归档、准入策略本身就是 ISO 27001 与 SOC 2 的采信材料,能显著缩短外部审计周期;二是响应能力——GDPR 要求数据泄露后及时通报,有 SBOM 的企业能把"排查受影响系统"从数周压缩到数小时。合规不是买来的证书,是能拿出手的工程证据。
总结
供应链安全不复杂,但必须工程化:cosign 签名解决"谁构建的",syft/SBOM 解决"里面有什么",Trivy 解决"有没有已知漏洞",Kyverno 解决"集群只执行可信镜像"。四件套全部开源免费,和阿里云 ACR、AWS ECR、腾讯云 TCR 都能无缝配合。给团队的落地路径就三步:本周把 Trivy 门禁加进流水线;两周内接上 cosign keyless 签名;一个月内让 Kyverno 从 Audit 切到 Enforce。至此,你上一篇文章搭好的 CI/CD 管道才真正配得上"生产级"三个字。
🚀 企业出海需要云架构咨询?通过 7.chengzicloud.cloud 联系我们,获取专属方案。从 CI/CD 流水线、供应链安全、双活架构到 FinOps 成本治理,我们提供一站式企业级云服务。
相关阅读
- 出海企业CI/CD流水线搭建实战:GitHub Actions + 容器化部署 — 本文的母篇,先搭好发布管道再接安全门禁
- 海外服务器安全加固清单:24项安全检查与配置实战 — 供应链安全之外的主机侧纵深防御
- OpenTofu 与 Terraform 多云基础设施实战:一套代码管理阿里云+AWS — 把仓库、签名公钥与准入策略全部代码化
- 多云统一身份认证实战:阿里云RAM SSO + AWS IAM Identity Center — keyless 签名背后的 OIDC 身份联邦机制详解
本文由 7.chengzicloud.cloud 提供,点击访问首页了解更多