第一章:从PGP到Sigstore——软件供应链安全的演进
随着开源软件生态的迅猛发展,代码来源的真实性与完整性成为关键挑战。早期的解决方案依赖于 PGP(Pretty Good Privacy)签名机制,开发者通过私钥对提交内容签名,用户则使用公钥验证。尽管 PGP 提供了加密保障,但其密钥管理复杂、缺乏自动化验证流程,并且难以集成到现代 CI/CD 流水线中。
PGP 的局限性
- 密钥分发困难,容易遭遇中间人攻击
- 无集中化信任体系,依赖“信任网”模型
- 难以与容器镜像、二进制文件等现代制品集成
为应对这些挑战,Sigstore 应运而生。它由 Linux 基金会主导,旨在为软件供应链提供透明、自动化和可验证的签名与验证机制。Sigstore 使用基于证书的短期密钥、可信时间戳服务(TSA),以及公开可审计的日志系统(如 Rekor),实现端到端的可追溯性。
Sigstore 核心组件
| 组件 | 功能说明 |
|---|
| cosign | 用于容器镜像和文件的签名与验证工具 |
| fulcio | 颁发基于 OIDC 身份的代码签名证书 |
| rekor | 不可篡改的透明日志,记录所有签名事件 |
例如,使用 cosign 对容器镜像签名的操作如下:
# 登录到容器注册中心 docker login # 使用 cosign 签名镜像 cosign sign --oidc-issuer=https://oauth2.example.com \ registry.example.com/myapp:v1.2.3 # 系统将自动获取短期证书并完成签名
graph TD A[开发者提交代码] --> B{CI/CD 触发构建} B --> C[cosign 请求 Fulcio 颁发证书] C --> D[对镜像进行签名] D --> E[将签名记录写入 Rekor 日志] E --> F[发布至镜像仓库] F --> G[用户拉取并验证签名]
第二章:Sigstore核心组件与工作原理
2.1 理解Sigstore的三大支柱:cosign、fulcio、rekor
Sigstore 通过三个核心组件构建软件供应链的安全信任体系:cosign、fulcio 和 rekor,各自承担关键角色。
cosign:签名与验证的基石
cosign 提供容器镜像和文件的签名与验证功能,支持无密钥签名。开发者可使用以下命令完成镜像签名:
cosign sign --key cosign.key gcr.io/example/image:tag
该命令使用本地私钥对指定镜像签名,公钥用于后续验证,确保来源可信。
fulcio:基于身份的证书颁发
fulcio 依据开发者身份(如GitHub账户)签发短期X.509证书,实现零信任下的身份绑定,避免长期密钥管理风险。
rekor:透明化存储签名记录
所有签名记录被写入 rekor 的不可变日志树中,形成全局可验证的审计轨迹。查询签名记录可通过:
cosign verify --rekor-url https://rekor.sigstore.dev gcr.io/example/image:tag
此命令从 rekor 获取签名条目,并结合 fulcio 证书链完成端到端验证。
2.2 基于OIDC的身份认证机制与无密钥签名实践
OIDC认证流程概述
OpenID Connect(OIDC)在OAuth 2.0基础上构建,提供身份层认证。用户通过授权服务器获取ID Token,该JWT格式令牌包含用户身份声明,由Issuer签名确保完整性。
无密钥签名的实现方式
采用基于公钥基础设施的验证机制,服务端无需存储私钥。依赖JWKS(JSON Web Key Set)端点动态获取公钥:
// Go中使用oidc库验证ID Token verifier := provider.Verifier(&oidc.Config{ClientID: "your-client-id"}) idToken, err := verifier.Verify(ctx, rawIDToken) if err != nil { // 验证失败:签名无效或声明不匹配 } claims := make(map[string]interface{}) idToken.Claims(&claims) // 解析用户声明
上述代码通过预注册Client ID校验令牌合法性,并解析标准声明如
sub、
email。JWKS自动轮询机制保障公钥更新透明化,提升系统安全性与可维护性。
2.3 Spire与透明日志(Transparency Log)在验证中的作用
身份验证与证书分发机制
Spire 是一个零信任架构下的身份认证系统,通过工作负载 API 分发音量凭证。每个节点在加入集群时由 Spire Server 颁发短期 SVID(SPIFFE Verifiable Identity Document),确保最小权限原则。
// 示例:通过 SPIRE Agent 获取 SVID resp, err := client.FetchX509SVID() if err != nil { log.Fatal(err) } for _, svid := range resp.Svids { fmt.Printf("Workload ID: %s\n", svid.SpiffeId) fmt.Printf("Cert: %s\n", svid.X509Svid) }
上述代码展示了客户端从 SPIRE Agent 获取 X.509-SVID 的过程。SpiffeId 标识唯一工作负载身份,用于后续访问控制。
透明日志的审计能力
透明日志(Transparency Log)记录所有证书签发行为,提供可验证、不可篡改的日志流。其结构通常采用默克尔树(Merkle Tree),支持高效一致性校验。
| 字段 | 说明 |
|---|
| Log Root | 周期性生成的哈希根,代表当前日志状态 |
| Inclusion Proof | 证明某条目已写入日志的密码学证据 |
结合 Spire 与透明日志,可实现“谁在何时获取了何种身份”的全程可追溯,大幅提升系统安全性与合规性。
2.4 签名与验证流程详解:从镜像到制品
在现代软件供应链中,制品的完整性与来源可信性至关重要。签名与验证机制贯穿于从容器镜像到最终部署制品的全生命周期。
签名流程核心步骤
- 开发者使用私钥对制品摘要进行数字签名
- 签名信息与制品元数据一同上传至镜像仓库
- CI/CD 系统自动附加策略标签,标记信任级别
验证阶段执行逻辑
// VerifyImageSignature 验证镜像签名合法性 func VerifyImageSignature(imageDigest, signature []byte, publicKey *rsa.PublicKey) bool { h := sha256.Sum256(imageDigest) err := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, h[:], signature) return err == nil }
该函数通过 RSA 公钥验证制品摘要签名,确保内容未被篡改。参数
imageDigest为镜像哈希值,
signature是原始签名,
publicKey来自可信证书链。
典型验证流程状态表
| 阶段 | 操作 | 输出 |
|---|
| 拉取制品 | 获取镜像与签名清单 | blob 数据 |
| 解析签名 | 提取公钥与签名体 | 加密对象 |
| 执行验证 | 比对摘要与签名 | 信任/拒绝 |
2.5 实战:使用cosign对容器镜像进行签名与验证
在CI/CD流程中保障容器镜像的完整性至关重要。Cosign作为Sigstore项目的一部分,提供了简单高效的签名与验证机制。
安装与配置
通过以下命令安装cosign:
wget https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -O /usr/local/bin/cosign chmod +x /usr/local/bin/cosign
该命令下载amd64架构的二进制文件并赋予可执行权限,确保后续命令可用。
镜像签名流程
生成密钥对并签名镜像:
cosign generate-key-pair cosign sign --key cosign.key your-registry/image:tag
generate-key-pair创建私钥
cosign.key和公钥
cosign.pub;
sign命令使用私钥对指定镜像生成签名并上传至远程仓库。
验证机制
部署时验证镜像完整性:
cosign verify --key cosign.pub your-registry/image:tag
此命令拉取镜像签名信息,并使用公钥验证来源可信性,防止篡改镜像运行。
第三章:Sigstore在DevSecOps中的集成路径
3.1 在CI流水线中嵌入Sigstore自动签名
在现代持续集成(CI)流程中,确保软件供应链安全至关重要。将 Sigstore 集成到 CI 流水线中,可实现对构建产物的自动化加密签名与验证。
集成方式概述
通过在 CI 脚本中调用
cosign工具,可在镜像构建后自动完成签名。例如,在 GitHub Actions 中:
- name: Sign image with Cosign run: | cosign sign --key ${{ secrets.SIGNING_KEY }} $IMAGE_DIGEST
该步骤使用预配置的私钥对容器镜像摘要进行签名,签名信息存储于 OCI 仓库中,与镜像绑定。
关键优势
- 零信任环境下的完整性保障
- 与现有 CI/CD 平台无缝集成
- 支持基于 OIDC 的身份认证,无需长期密钥管理
通过此机制,所有由流水线生成的构件均可被追溯和验证,显著提升发布安全性。
3.2 与GitHub Actions深度集成实现端到端信任
在现代CI/CD流程中,确保代码从提交到部署的每一步都具备可验证的信任机制至关重要。通过将Sigstore与GitHub Actions深度集成,开发者可在流水线中自动完成代码签名与验证。
自动化签名工作流
利用GitHub Actions触发构建时,可通过
sigstore/sign-action对产出物进行签名:
- name: Sign artifact uses: sigstore/sign-action@v2 with: artifacts: "dist/*.tar.gz" signature: "dist/artifact.sig" certificate: "dist/artifact.crt"
该步骤生成的签名、证书由Sigstore透明日志记录,确保不可篡改。参数
artifacts指定待签名文件,
signature和
certificate定义输出路径。
信任链验证机制
下游系统可通过公开的透明日志校验签名来源,结合SLSA安全等级提升软件供应链整体可信度。整个过程无需管理私钥,极大降低泄露风险。
3.3 验证策略在Kubernetes部署前的强制执行
在Kubernetes部署流程中,验证策略的前置执行是保障集群安全与稳定的核心环节。通过引入准入控制器(Admission Controller),可在对象持久化前拦截创建请求,实施策略校验。
使用ValidatingAdmissionPolicy进行声明式验证
Kubernetes 1.26+ 引入的 `ValidatingAdmissionPolicy` 支持基于CRD的声明式规则定义,无需编写复杂Webhook服务。
apiVersion: admissionregistration.k8s.io/v1alpha1 kind: ValidatingAdmissionPolicy metadata: name: "require-label-policy" spec: matchConstraints: resourceRules: - apiGroups: [""] resources: ["pods"] operations: ["CREATE"] validations: - expression: "object.metadata.labels['env'] in ['prod', 'staging']" message: "env 标签必须为 prod 或 staging"
上述策略强制所有新建Pod必须包含合法的 `env` 标签。表达式使用Common Expression Language (CEL),轻量高效且无副作用。该机制将策略逻辑下沉至API Server层,实现统一、可审计的资源准入控制。
第四章:企业级应用与安全治理
4.1 建立组织级证书颁发与身份映射策略
在大型组织中,统一的证书颁发机制是零信任安全架构的核心。通过部署私有CA(证书颁发机构),可实现对设备、服务和用户的身份可信签发。
基于角色的身份映射策略
身份证书应与组织内的角色权限绑定,确保最小权限原则。例如,在Kubernetes环境中,客户端证书中的OU字段可映射至RBAC角色:
Subject: O=developers, OU=backend, CN=alice@company.com
上述证书可映射为集群中的“backend-developer”角色,自动授予相应命名空间的读写权限。
证书生命周期管理流程
- 申请:通过自动化API提交CSR(证书签名请求)
- 审批:基于策略的自动或人工审批流程
- 签发:CA签署并返回证书
- 轮换:定期自动更新证书,避免长期有效凭证风险
该流程确保所有实体身份持续可信,降低凭证泄露带来的安全风险。
4.2 利用Rekor公开日志实现审计与合规追溯
Rekor 是 Sigstore 项目中的透明日志组件,用于记录和验证软件供应链中各类签名事件。通过将数字工件(如容器镜像、二进制文件)的哈希值写入不可篡改的公开日志,Rekor 提供了可验证的时间戳和存在性证明。
查询日志条目
可通过 Rekor CLI 查询特定哈希是否已录入日志:
rekor-cli search --sha 8b3bfe7a9...
该命令返回包含 UUID 和时间戳的条目信息,用于后续审计追踪。
验证完整性与时间顺序
每个日志条目均包含 Merkel 树签名,确保数据一致性。组织可定期轮询 Rekor 服务器,比对本地记录与公开日志差异,及时发现篡改或遗漏。
| 字段 | 用途 |
|---|
| UUID | 唯一标识日志条目 |
| IntegratedTime | 记录写入时间,用于合规时序验证 |
4.3 多租户环境下的策略管理与policy-controller配置
在多租户Kubernetes集群中,策略管理是保障租户隔离与安全的核心环节。通过`policy-controller`可实现对Pod、命名空间等资源的细粒度访问控制。
策略控制器的核心功能
监听自定义策略资源(CRD),动态生成NetworkPolicy和PodSecurityPolicy。其工作流程如下:
用户提交策略 → API Server → policy-controller监听变更 → 校验并转换 → 下发至对应命名空间
配置示例与说明
apiVersion: policy.example.com/v1 kind: TenantPolicy metadata: name: tenant-a-policy spec: namespaceSelector: matchLabels: tenant: a network: egress: - to: - ipBlock: cidr: 10.96.0.0/12
上述配置限制租户A的命名空间仅能访问集群内部服务网段,防止外部数据泄露。其中
namespaceSelector用于匹配目标租户命名空间,
egress定义出口流量规则,确保网络层面租户隔离。
4.4 迁移挑战与从PGP到Sigstore的平滑过渡方案
向Sigstore迁移的核心难点在于开发者习惯、密钥管理机制和现有签名生态的兼容性。PGP依赖长期存在的私钥对和Web of Trust模型,而Sigstore采用基于短时效证书和透明日志(如Rekor)的自动化签名体系。
关键挑战对比
- PGP私钥需长期保管,存在泄露风险
- Sigstore依赖OIDC身份认证,需集成现有IAM系统
- 历史PGP签名无法直接在Sigstore验证
平滑过渡策略
可采用双签模式,在CI流程中同时生成PGP和Sigstore签名:
# 双重签名示例:GPG + Cosign gpg --sign --armor --output release.tar.gz.asc release.tar.gz cosign sign --oidc-issuer=https://accounts.google.com --fulcio-issuer=https://fulcio.sigstore.dev bundle.img
该脚本先使用本地GPG密钥签名,再通过OAuth2流程获取短期证书完成Sigstore签名。逐步将关键项目迁移并验证后,最终停用PGP路径,实现安全与兼容的平衡。
第五章:未来已来——构建零信任的软件交付链
从构建到部署的全程验证
现代软件交付不再依赖网络边界防护,而是将信任嵌入每个环节。零信任模型要求对代码来源、构建环境、依赖项和部署目标进行持续验证。例如,使用 Sigstore 对 CI/CD 中的构件进行签名与验证,确保只有经过认证的提交才能进入生产环境。
自动化策略执行
在 Kubernetes 环境中,借助 Open Policy Agent(OPA)实现策略即代码。以下是一个用于阻止未签名镜像运行的 Rego 策略片段:
package kubernetes.admission deny[msg] { input.request.kind.kind == "Pod" container := input.request.object.spec.containers[_] not startswith(container.image, "registry.internal/") not is_signed(container.image) msg := sprintf("Unsigned image not allowed: %v", [container.image]) } is_signed(image) { # 查询镜像签名数据库或调用 cosign verify result := http.send({"method": "GET", "url": concat("", ["https://sigdb.example.com/", image, "/signature"])}) result.status == 200 }
关键组件清单
- 代码签名工具(如 Cosign、Sigstore)
- 不可变制品仓库(如 Harbor 配置只读镜像)
- SBOM(软件物料清单)生成与审计(Syft + Grype)
- CI/CD 流水线中的自动策略拦截(GitHub Actions + OPA)
实战案例:金融企业交付链改造
某银行将原有 Jenkins 构建系统升级为 GitOps 模式,结合 Argo CD 与 Tekton 实现构建溯源。所有镜像必须附带 SBOM 并通过漏洞扫描,且由双人使用硬件密钥完成签名后方可部署。该机制在一次供应链攻击中成功阻断了植入恶意依赖的构件发布。
| 阶段 | 验证动作 | 工具链 |
|---|
| 代码提交 | 开发者身份 SSO 认证 | GitHub + OIDC |
| 构建 | 环境隔离 + 构建可重现性校验 | BuildKit + Attestation |
| 部署 | 策略引擎校验签名与合规性 | OPA + Kyverno |