mcpField
S
sbom-supply-chain

sbom-supply-chain

github.com/bagelholeセキュリティ1.2k328 回インストール23 週間前に更新
リポジトリ

sbom-supply-chain について

sbom-supply-chain は、ソフトウェアのビルドとリリースに携わるチーム向けのスキルです。SBOM の生成、脆弱性チェック、成果物の検証に加え、署名や証明、サプライチェーンポリシーの適用を扱います。

主な機能

  1. 01CycloneDX と SPDX の SBOM 生成
  2. 02SBOM に基づく脆弱性照合
  3. 03cosign による成果物の署名
  4. 04SBOM と来歴証明の添付
  5. 05検証ポリシーの適用

活用シーン

  1. 01イメージやアプリケーションビルドの SBOM 作成
  2. 02デプロイ前の依存関係チェック
  3. 03成果物の署名と来歴証明の必須化
  4. 04セキュリティレビューや SLSA 要件への準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill sbom-supply-chain

インストール後、Claude Code で/sbom-supply-chainを入力して読み込まれたか確認します。

詳細

SBOM とサプライチェーンセキュリティ

再現可能なメタデータと検証ゲートにより、リリースへの信頼性を高めます。

このスキルを使う場面

次のような場合にこのスキルを使います。

  • コンテナイメージやアプリケーションのビルド向けに SBOM を生成する
  • デプロイ前に依存関係を検証する
  • 署名済みアーティファクトと来歴のポリシーを適用する
  • SOC2、ISO 27001、または顧客のセキュリティレビューに備える
  • SLSA フレームワークの要件を実装する
  • サプライチェーンの脆弱性(Log4Shell のようなインシデントなど)に対応する

前提条件

  • SBOM 生成用の syft がインストールされていること
  • CycloneDX SBOM 生成用の cdxgen がインストールされていること
  • SBOM に対する脆弱性マッチング用の grype
  • 署名とアテステーション用の cosign v2+
  • OCI アーティファクトに対応したコンテナレジストリ
  • キーレス署名用の OIDC ID を備えた CI/CD パイプライン

SBOM 形式

CycloneDX と SPDX の比較
comparison:
  cyclonedx:
    standard: "OWASP CycloneDX"
    focus: "Application security, vulnerability tracking"
    formats: ["JSON", "XML", "Protocol Buffers"]
    strengths:
      - Vulnerability references (VEX support)
      - Service and API dependency tracking
      - Hardware BOM support
    best_for: "Security-focused SBOM, vulnerability management"

  spdx:
    standard: "Linux Foundation SPDX (ISO/IEC 5962:2021)"
    focus: "License compliance, legal review"
    formats: ["JSON", "RDF/XML", "Tag-Value", "YAML"]
    strengths:
      - ISO standard
      - License expression language
      - Relationship modeling
    best_for: "License compliance, regulatory requirements"

Syft による SBOM 生成

# Generate SBOM for a container image (CycloneDX JSON)
syft ghcr.io/acme/api:v1.2.3 -o cyclonedx-json > sbom-cyclonedx.json

# Generate SBOM in SPDX format
syft ghcr.io/acme/api:v1.2.3 -o spdx-json > sbom-spdx.json

# Generate SBOM from a local directory (source code)
syft dir:. -o cyclonedx-json > sbom-source.json

# Generate SBOM from a Dockerfile/built image
syft docker:my-local-image:latest -o cyclonedx-json > sbom-local.json

# Generate SBOM for a specific package ecosystem
syft dir:. --catalogers python -o cyclonedx-json > sbom-python.json

# Include file hashes for deeper analysis
syft ghcr.io/acme/api:v1.2.3 -o cyclonedx-json --file-metadata > sbom-with-hashes.json

# Multiple output formats simultaneously
syft ghcr.io/acme/api:v1.2.3 \
  -o cyclonedx-json=sbom-cdx.json \
  -o spdx-json=sbom-spdx.json \
  -o table=sbom-summary.txt

cdxgen による SBOM 生成

# Install cdxgen
npm install -g @cyclonedx/cdxgen

# Generate CycloneDX SBOM for a project directory
cdxgen -o sbom.json .

# Specify project type
cdxgen -t python -o sbom-python.json .
cdxgen -t java -o sbom-java.json .
cdxgen -t node -o sbom-node.json .
cdxgen -t go -o sbom-go.json .

# Generate SBOM with evidence (call stacks, file occurrences)
cdxgen --evidence -o sbom-with-evidence.json .

# Generate for a container image
cdxgen -t docker -o sbom-container.json ghcr.io/acme/api:v1.2.3

# Generate with deep analysis (slower but more accurate)
cdxgen --deep -o sbom-deep.json .

# Output in different formats
cdxgen -o sbom.xml --format xml .

脆弱性マッチング

# Scan SBOM for vulnerabilities with Grype
grype sbom:sbom-cyclonedx.json

# Fail on critical/high vulnerabilities
grype sbom:sbom-cyclonedx.json --fail-on high

# Output as JSON for CI processing
grype sbom:sbom-cyclonedx.json -o json > vulnerability-report.json

# Scan container image directly
grype ghcr.io/acme/api:v1.2.3

# Use Trivy with SBOM input
trivy sbom sbom-cyclonedx.json

# Trivy scan with severity filter
trivy sbom sbom-cyclonedx.json --severity CRITICAL,HIGH --exit-code 1

Cosign による署名とアテステーション

イメージの署名
# Keyless signing (recommended - uses OIDC identity from CI)
cosign sign ghcr.io/acme/api@sha256:abc123...

# Sign with a key pair
cosign generate-key-pair
cosign sign --key cosign.key ghcr.io/acme/api@sha256:abc123...

# Verify keyless signature
cosign verify \
  --certificate-identity=https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  ghcr.io/acme/api@sha256:abc123...

# Verify with key
cosign verify --key cosign.pub ghcr.io/acme/api@sha256:abc123...
SBOM アテステーション
# Attach SBOM as an in-toto attestation to a container image
cosign attest --predicate sbom-cyclonedx.json \
  --type cyclonedx \
  ghcr.io/acme/api@sha256:abc123...

# Attach SPDX SBOM
cosign attest --predicate sbom-spdx.json \
  --type spdx \
  ghcr.io/acme/api@sha256:abc123...

# Verify SBOM attestation
cosign verify-attestation \
  --type cyclonedx \
  --certificate-identity=https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  ghcr.io/acme/api@sha256:abc123...

# Extract the SBOM from attestation
cosign verify-attestation --type cyclonedx \
  --certificate-identity=... --certificate-oidc-issuer=... \
  ghcr.io/acme/api@sha256:abc123... | jq -r '.payload' | base64 -d | jq '.predicate'
In-toto 来歴アテステーション
# Create a custom provenance attestation
cat > provenance.json << 'EOF'
{
  "buildType": "https://github.com/acme/build-system@v1",
  "builder": {
    "id": "https://github.com/acme/api/.github/workflows/build.yml@refs/heads/main"
  },
  "invocation": {
    "configSource": {
      "uri": "git+https://github.com/acme/api@refs/heads/main",
      "digest": { "sha1": "abc123def456" },
      "entryPoint": ".github/workflows/build.yml"
    }
  },
  "metadata": {
    "buildStartedOn": "2025-01-15T10:00:00Z",
    "buildFinishedOn": "2025-01-15T10:05:00Z",
    "completeness": {
      "parameters": true,
      "environment": true,
      "materials": true
    }
  },
  "materials": [
    {
      "uri": "git+https://github.com/acme/api@refs/heads/main",
      "digest": { "sha1": "abc123def456" }
    },
    {
      "uri": "pkg:docker/[email protected]",
      "digest": { "sha256": "def456..." }
    }
  ]
}
EOF

# Attach provenance attestation
cosign attest --predicate provenance.json \
  --type slsaprovenance \
  ghcr.io/acme/api@sha256:abc123...

CI/CD パイプラインへの統合

# .github/workflows/sbom-supply-chain.yml
name: Build with SBOM and Signing
on:
  push:
    tags: ['v*']

permissions:
  contents: read
  packages: write
  id-token: write  # Required for keyless signing

jobs:
  build-sign-attest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push image
        id: build
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}

      - name: Install tools
        run: |
          curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
          curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin

      - name: Generate SBOM
        run: |
          syft ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }} \
            -o cyclonedx-json=sbom-cdx.json \
            -o spdx-json=sbom-spdx.json

      - name: Scan SBOM for vulnerabilities
        run: |
          grype sbom:sbom-cdx.json --fail-on critical -o json > vuln-report.json

      - name: Install cosign
        uses: sigstore/cosign-installer@v3

      - name: Sign image (keyless)
        run: |
          cosign sign ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

      - name: Attach SBOM attestation
        run: |
          cosign attest --predicate sbom-cdx.json \
            --type cyclonedx \
            ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: sbom-and-reports
          path: |
            sbom-cdx.json
            sbom-spdx.json
            vuln-report.json

ポリシーの適用

Kyverno ポリシー:SBOM を含む署名済みイメージを必須にする
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-signed-images-with-sbom
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds: ["Pod"]
      verifyImages:
        - imageReferences: ["ghcr.io/acme/*"]
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/acme/*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: "https://rekor.sigstore.dev"
          attestations:
            - type: cyclonedx
              conditions:
                - all:
                    - key: "{{ components[].name }}"
                      operator: AllNotIn
                      value: ["log4j-core"]
OPA ポリシー:デプロイ前に SBOM を検証する
package sbom.verify

import rego.v1

default allow := false

allow if {
    sbom_present
    no_critical_vulns
    signed_by_ci
}

sbom_present if {
    input.attestations.cyclonedx != null
    count(input.attestations.cyclonedx.components) > 0
}

no_critical_vulns if {
    not any_critical
}

any_critical if {
    some vuln in input.vulnerability_report.matches
    vuln.vulnerability.severity == "Critical"
    vuln.vulnerability.fix.state == "fixed"
}

signed_by_ci if {
    input.signature.issuer == "https://token.actions.githubusercontent.com"
    startswith(input.signature.subject, "https://github.com/acme/")
}

トラブルシューティング

問題原因解決策
Syft が依存関係を検出できないパッケージマネージャーまたは形式がサポートされていないsyft のカタログ化ツール一覧を確認します。より詳細な分析には cdxgen を使います。上流にコントリビュートします
Cosign の署名が「no identity token」で失敗するCI に OIDC プロバイダーがないGitHub Actions で id-token: write 権限が設定されていることを確認します。OIDC プロバイダーの設定を確認します
Grype が誤検出を報告するパッケージのバージョン検出が不正確SBOM の正確性を確認します。grype の GitHub に報告します。確認済みの誤検出には無視ルールを追加します
SBOM アテステーションが大きすぎる依存関係が多い大きなイメージSBOM を圧縮します。SPDX のコンパクト形式を使います。レイヤーごとに分割することを検討します
アドミッションコントローラーで検証に失敗するID または発行者 URL が誤っている--certificate-identity と --certificate-oidc-issuer の値が正確であることを確認します
cdxgen が空の SBOM を生成するプロジェクトの種類が検出されていない-t で種類を明示します。マニフェストファイル(package.json など)が存在することを確認します

ベストプラクティス

  • 互換性を最大限に高めるため、CycloneDX と SPDX の両方で SBOM を生成します
  • キーレス署名(Sigstore/Fulcio)ですべてのリリースアーティファクトに署名します
  • in-toto アテステーションとして SBOM をコンテナイメージに添付します
  • CI で SBOM の脆弱性をスキャンし、重大な検出結果があれば処理をブロックします
  • 監査とインシデント対応に備え、すべてのリリースの SBOM を保管します
  • アドミッションコントローラー(Kyverno、OPA)で署名検証を適用します
  • 保管済みの SBOM に対する新たな CVE を継続的に監視します
  • リリース時だけでなく、すべてのビルドパイプラインに SBOM 生成を含めます
  • SBOM の完全性指標(記録された依存関係の割合)を追跡します
  • 誤検出に対応するため、VEX(Vulnerability Exploitability eXchange)プロセスを確立します

関連スキル

コメント