关于 implementing-supply-chain-security-with-in-toto
介绍如何使用 in-toto 验证软件供应链完整性的安全技能。它指导团队为构建步骤签署证明,并在部署前检查制品,也涵盖容器工作流。
主要功能
- 01定义供应链步骤和策略
- 02签署构建步骤证明
- 03记录制品输入与输出
- 04验证签名和制品哈希
- 05部署前检查来源证明
适用场景
- 01在 Kubernetes 部署前验证容器镜像
- 02记录带签名的 CI 构建步骤
- 03按供应链策略检查软件制品
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill implementing-supply-chain-security-with-in-toto安装后在 Claude Code 中输入/implementing-supply-chain-security-with-in-toto确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py详细介绍
使用 in-toto 实现供应链安全
概述
in-toto 是一个 CNCF 毕业项目,用于确保软件供应链从启动到最终用户安装全过程的完整性。它通过在每一步生成经过加密签名的证明(称为“链接元数据”),记录整个软件开发生命周期中发生的事件、执行者以及产生的工件,从而形成可验证记录。对于容器环境,in-toto 会验证部署到 Kubernetes 的镜像是否遵循了经过批准的构建流程,并且未被篡改。
何时使用
- 在环境中部署或配置使用 in toto 实现供应链安全能力时
- 在建立符合合规要求的安全控制措施时
- 在为该领域构建或改进安全架构时
- 在进行需要此实现的安全评估时
先决条件
- 用于 in-toto 客户端库的 Python 3.8+ 或 Go 运行时
- 用于签署证明的 GPG 或 Ed25519 密钥
- 容器构建流水线(Docker、Buildah 或 Kaniko)
- 容器镜像仓库(Docker Hub、ECR、GCR 或 Harbor)
- 用于部署验证的 Kubernetes 集群
核心概念
供应链布局
布局是核心策略文档,定义了:
- 步骤:供应链中的有序操作(clone、build、test、package、push)
- 执行方:执行每个步骤的授权实体(人员或 CI 系统)
- 检查:在验证时执行的客户端验证检查
- 预期工件:步骤之间的输入/输出关系
from in_toto.models.layout import Layout, Step, Inspection
from securesystemslib.interface import import_ed25519_privatekey_from_file
# Create the supply chain layout
layout = Layout()
layout.set_relative_expiration(months=3)
# Define the code clone step
step_clone = Step(name="clone")
step_clone.expected_materials = []
step_clone.expected_products = [["CREATE", "src/*"]]
step_clone.pubkeys = [clone_functionary_keyid]
step_clone.expected_command = ["git", "clone"]
step_clone.threshold = 1
# Define the build step
step_build = Step(name="build")
step_build.expected_materials = [["MATCH", "src/*", "WITH", "PRODUCTS", "FROM", "clone"]]
step_build.expected_products = [["CREATE", "image.tar"]]
step_build.pubkeys = [build_functionary_keyid]
step_build.expected_command = ["docker", "build"]
step_build.threshold = 1
# Define the scan step
step_scan = Step(name="scan")
step_scan.expected_materials = [["MATCH", "image.tar", "WITH", "PRODUCTS", "FROM", "build"]]
step_scan.expected_products = [["CREATE", "scan-report.json"]]
step_scan.pubkeys = [scan_functionary_keyid]
step_scan.threshold = 1
layout.steps = [step_clone, step_build, step_scan]
链接元数据
每次步骤执行都会生成一个链接文件,其中包含:
- 消耗的material(带哈希的输入工件)
- 产生的product(带哈希的输出工件)
- 执行的命令
- 执行方的加密签名
验证过程
在部署时,验证方会检查:
- 所有必需步骤均已执行
- 每个步骤均由授权执行方签名
- 工件哈希在步骤之间正确链接
- 步骤之间未发生未经授权的修改
实现
步骤 1:生成签名密钥
# Generate Ed25519 key pairs for each functionary
mkdir -p keys
# Project owner key (signs the layout)
in-toto-keygen --type ed25519 keys/owner
# CI builder key
in-toto-keygen --type ed25519 keys/builder
# Security scanner key
in-toto-keygen --type ed25519 keys/scanner
步骤 2:创建供应链布局
#!/usr/bin/env python3
"""Generate in-toto supply chain layout for container builds."""
from in_toto.models.layout import Layout, Step, Inspection
from in_toto.models.metadata import Envelope
from securesystemslib.signer import CryptoSigner
from securesystemslib.interface import import_ed25519_publickey_from_file
def create_container_build_layout():
layout = Layout()
layout.set_relative_expiration(months=6)
# Load functionary public keys
builder_key = import_ed25519_publickey_from_file("keys/builder.pub")
scanner_key = import_ed25519_publickey_from_file("keys/scanner.pub")
layout.keys = {
builder_key["keyid"]: builder_key,
scanner_key["keyid"]: scanner_key,
}
# Step 1: Source code checkout
checkout = Step(name="checkout")
checkout.expected_materials = []
checkout.expected_products = [
["CREATE", "Dockerfile"],
["CREATE", "src/*"],
["CREATE", "requirements.txt"],
]
checkout.pubkeys = [builder_key["keyid"]]
checkout.threshold = 1
# Step 2: Build container image
build = Step(name="build")
build.expected_materials = [
["MATCH", "Dockerfile", "WITH", "PRODUCTS", "FROM", "checkout"],
["MATCH", "src/*", "WITH", "PRODUCTS", "FROM", "checkout"],
]
build.expected_products = [["CREATE", "image-digest.txt"]]
build.pubkeys = [builder_key["keyid"]]
build.threshold = 1
# Step 3: Security scan
scan = Step(name="scan")
scan.expected_materials = [
["MATCH", "image-digest.txt", "WITH", "PRODUCTS", "FROM", "build"]
]
scan.expected_products = [
["CREATE", "vulnerability-report.json"],
["CREATE", "sbom.json"],
]
scan.pubkeys = [scanner_key["keyid"]]
scan.threshold = 1
# Inspection: Verify no critical vulnerabilities
inspect_vulns = Inspection(name="verify-no-critical-vulns")
inspect_vulns.expected_materials = [
["MATCH", "vulnerability-report.json", "WITH", "PRODUCTS", "FROM", "scan"]
]
inspect_vulns.run = [
"python", "-c",
"import json,sys; r=json.load(open('vulnerability-report.json')); "
"sys.exit(1) if any(v['severity']=='CRITICAL' for v in r.get('vulnerabilities',[])) else sys.exit(0)"
]
layout.steps = [checkout, build, scan]
layout.inspect = [inspect_vulns]
return layout
if __name__ == "__main__":
layout = create_container_build_layout()
# Sign with owner key and save
owner_signer = CryptoSigner.from_priv_key_uri("file:keys/owner")
envelope = Envelope.from_signable(layout)
envelope.create_signature(owner_signer)
envelope.dump("root.layout")
print("Layout created and signed: root.layout")
步骤 3:记录流水线步骤
# In CI/CD pipeline - record each step
# Step 1: Checkout
in-toto-run --step-name checkout \
--key keys/builder \
--products Dockerfile src/* requirements.txt \
-- git clone https://github.com/org/app.git .
# Step 2: Build
in-toto-run --step-name build \
--key keys/builder \
--materials Dockerfile src/* \
--products image-digest.txt \
-- bash -c "docker build -t app:latest . && docker inspect --format='{{.Id}}' app:latest > image-digest.txt"
# Step 3: Scan
in-toto-run --step-name scan \
--key keys/scanner \
--materials image-digest.txt \
--products vulnerability-report.json sbom.json \
-- bash -c "trivy image --format json app:latest > vulnerability-report.json && syft app:latest -o json > sbom.json"
步骤 4:部署前验证
# Verify the entire supply chain
in-toto-verify --layout root.layout \
--layout-key keys/owner.pub \
--link-dir ./link-metadata/
# If verification passes, proceed with deployment
if [ $? -eq 0 ]; then
kubectl apply -f deployment.yaml
echo "Supply chain verification passed - deploying"
else
echo "SUPPLY CHAIN VERIFICATION FAILED - blocking deployment"
exit 1
fi
步骤 5:Kubernetes 准入控制
与策略引擎集成,在准入时验证证明:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: in-toto-verifier
webhooks:
- name: verify.in-toto.io
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
operations: ["CREATE", "UPDATE"]
clientConfig:
service:
name: in-toto-webhook
namespace: security
path: /verify
failurePolicy: Fail
sideEffects: None
admissionReviewVersions: ["v1"]
SLSA 集成
in-toto 证明可直接映射到 SLSA(软件工件的供应链级别)要求:
| SLSA 级别 | in-toto 要求 |
|---|---|
| Level 1 | 构建流程已记录(布局存在) |
| Level 2 | 来自托管构建服务的已签名证明 |
| Level 3 | 加固的构建平台、不可伪造的来源 |
| Level 4 | 双方审查、封闭构建 |
参考资料
评论
支持 Markdown