implementing-supply-chain-security-with-in-toto について
in-toto を使ってソフトウェアサプライチェーンの完全性を検証するセキュリティスキルです。ビルド工程の証明への署名と、デプロイ前の成果物検査を案内し、コンテナのワークフローも扱います。
主な機能
- 01サプライチェーン工程とポリシーの定義
- 02ビルド工程の証明への署名
- 03成果物の入出力の記録
- 04署名と成果物ハッシュの検証
- 05デプロイ前の来歴確認
活用シーン
- 01Kubernetes デプロイ前のコンテナイメージ検証
- 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 クラスター
主な概念
サプライチェーンのレイアウト
レイアウトは、次の内容を定義する中心的なポリシードキュメントです。
- ステップ:サプライチェーンにおける順序付けられた操作(クローン、ビルド、テスト、パッケージ化、プッシュ)
- 実行者:各ステップを実行する、認可されたエンティティ(人または 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]
リンクメタデータ
各ステップの実行時に、次の内容を含むリンクファイルが生成されます。
- 使用したマテリアル(ハッシュ付きの入力成果物)
- 生成したプロダクト(ハッシュ付きの出力成果物)
- 実行したコマンド
- 実行者の暗号署名
検証プロセス
デプロイ時に、検証者は次の項目を確認します。
- 必要なすべてのステップが実行されたこと
- 各ステップが認可された実行者によって署名されていること
- ステップ間で成果物のハッシュが正しく連鎖していること
- ステップ間で認可されていない変更が行われていないこと
実装
ステップ 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 の要件 |
|---|---|
| レベル 1 | ビルドプロセスが文書化されている(レイアウトが存在する) |
| レベル 2 | ホスト型ビルドサービスによる署名付き証明 |
| レベル 3 | 強化されたビルドプラットフォーム、偽造不可能な来歴 |
| レベル 4 | 2者によるレビュー、ハーメチックビルド |
参考資料
コメント
Markdown 対応