supply-chain · git:20261017.0361a9b · 2026-10-17 · sha256 c49bb140c0e1977e

supply-chain git:20261017.0361a9bA

Immutable. This exact content never changes and is served at /api/v1/blob/c49bb140c0e1977e.

---
name: supply-chain
description: Secure the software supply chain from source to running container. Covers Cosign keyless image signing (Sigstore/Rekor), SBOM generation and attestation (Syft), vulnerability scanning with severity gates (Trivy/Grype), SLSA Level 2 provenance, and Kyverno/OPA admission enforcement. All open-source, no license cost. Use when asked to "sign my image", "generate an SBOM", "scan for CVEs", "attest build provenance", "enforce image signatures in Kubernetes", or "implement SLSA".
argument-hint: "[audit|sign|sbom|scan|enforce|slsa] [description or file path]"
title: "Supply Chain Command"
sidebar_label: "supply-chain"
custom_edit_url: null
---

Secure the software supply chain — from the build pipeline to running containers.

---

## Interactive Wizard (fires when no arguments are provided)

When invoked with no arguments, ask before proceeding:

**Q1 — Mode?**
```
What do you need?
  1. audit    — review an existing CI/CD pipeline for supply chain security gaps
  2. sign     — set up keyless image signing with Cosign (Sigstore/Rekor, no key management)
  3. sbom     — generate and attest an SBOM with Syft
  4. scan     — add a CVE vulnerability gate with Trivy or Grype
  5. enforce  — write a Kyverno policy to block unsigned images at admission
  6. slsa     — generate a SLSA Level 2 provenance workflow

Enter 1–6 or mode name:
```

**Q2 — Context** (after mode selected, one at a time):
- **audit**: `Paste your GitHub Actions workflow file(s) or describe your current CI/CD pipeline:`
- **sign**: `Which container registry? (ECR / GHCR / Docker Hub / other):`
- **sbom**: `Which image and registry? (e.g. ghcr.io/org/image):`
- **scan**: `Which scanner preference? Trivy (recommended) or Grype — or no preference:`
- **enforce**: `Which registry or image prefix should the policy cover? (e.g. ghcr.io/myorg/*):`
- **slsa**: `Which registry and repo? (e.g. ghcr.io/org/image from github.com/org/repo):`

Then proceed into the relevant mode below.

---

## Mode: audit

Review an existing CI/CD pipeline and cluster admission configuration for supply chain security gaps.

Steps:
1. Ask for or read: the GitHub Actions workflow file(s), any existing image scanning steps, and any Kyverno/OPA admission policies
2. Classify gaps by severity:
   - **Critical**: images pushed without signing, no CVE gate, unsigned images admitted to cluster
   - **High**: SBOM not generated or not attested, severity gate only on CRITICAL (misses HIGH)
   - **Medium**: action versions pinned to tag not SHA, no SLSA provenance
3. Output a prioritised gap list:
   ```
   [CRITICAL] No image signing — any image can be admitted to the cluster
   [CRITICAL] No CVE severity gate — vulnerable images pass CI
   [HIGH]     No SBOM attestation — cannot audit what is running
   [MEDIUM]   Action versions pinned to tag, not SHA
   ```
4. Recommend the fix order: sign → scan-gate → SBOM → enforce → SLSA

Reference: `references/supply-chain.md` → Gap classification, Fix order

## Mode: sign

Set up keyless image signing with Cosign using Sigstore/Rekor (no key management required).

Steps:
1. Confirm the image registry (ECR, GHCR, Docker Hub) and CI platform (GitHub Actions assumed)
2. Generate the signing workflow step:
   ```yaml
   - name: Install Cosign
     uses: sigstore/cosign-installer@11086d9f32b178aa24e93c2b86eba3ef4b16b68a  # v3.8.1

   - name: Sign image
     run: |
       cosign sign --yes \
         ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
   ```
3. Explain the keyless flow: GitHub Actions OIDC token → Fulcio CA → Rekor transparency log
4. Show verification command:
   ```bash
   cosign verify \
     --certificate-identity-regexp="https://github.com/<org>/<repo>/.github/workflows/.*" \
     --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
     ghcr.io/<org>/<image>@<digest>
   ```
5. Flag: always sign the digest (`@sha256:…`), never the tag — tags are mutable

Key rules:
- Never store signing keys in CI secrets — use keyless only
- Always sign the digest, not the tag
- Pin `cosign-installer` to a full SHA, e.g.: `sigstore/cosign-installer@11086d9f32b178aa24e93c2b86eba3ef4b16b68a`

Reference: `references/supply-chain.md` → Keyless signing, Rekor transparency log

## Mode: sbom

Generate a Software Bill of Materials with Syft and attest it as an OCI artifact alongside the image.

Steps:
1. Add the SBOM generation step after build and push (digest is only available after registry push):
   ```yaml
   - name: Generate SBOM
     uses: anchore/sbom-action@61119d458adab75f756bc0b9e4bde25725f86a7a  # v0.20.0
     with:
       image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
       format: spdx-json
       output-file: sbom.spdx.json

   - name: Attest SBOM
     run: |
       cosign attest --yes \
         --predicate sbom.spdx.json \
         --type spdxjson \
         ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
   ```
2. Show how to retrieve the SBOM attestation:
   ```bash
   cosign download attestation \
     --predicate-type https://spdx.dev/Document \
     ghcr.io/<org>/<image>@<digest> | jq '.payload | @base64d | fromjson'
   ```
3. Note: use `spdx-json` format for broadest tooling compatibility; `cyclonedx-json` is an alternative

Reference: `references/supply-chain.md` → SBOM formats, Syft, Attestation

## Mode: scan

Add a CVE vulnerability scan with a configurable severity gate that fails the build.

Steps:
1. Add Trivy scan step:
   ```yaml
   - name: Scan image for vulnerabilities
     uses: aquasecurity/trivy-action@18f2135c0b15d26b3a4c2efded75e06b6f0e4884  # v0.30.0
     with:
       image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
       format: table
       exit-code: '1'
       ignore-unfixed: true
       vuln-type: os,library
       severity: CRITICAL,HIGH
   ```
2. Explain `ignore-unfixed: true` — skip CVEs with no fix available (reduces noise without reducing security)
3. For Grype (alternative), show:
   ```yaml
   - name: Scan with Grype
     uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2  # v7.4.0
     with:
       image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
       fail-build: true
       severity-cutoff: high
   ```
4. Recommend Trivy for new setups (CNCF, single binary, SBOM support); Grype for teams already using Syft

Reference: `references/supply-chain.md` → Trivy vs Grype, Severity gates

## Mode: enforce

Generate a Kyverno `ImageValidatingPolicy` that blocks unsigned or unverified images at admission time.

Finding where unsigned images already run: Kubescape reports them as control C-0237 "Check if signature exists" (`/platform-skills:kubescape-operator`, or `kubescape scan control C-0237` on a cluster). Use that list to size the rollout before switching the policy to `Deny`.

Steps:
1. Ask: keyless (Sigstore) or key-based signing?
2. For keyless, generate:
   ```yaml
   apiVersion: policies.kyverno.io/v1
   kind: ImageValidatingPolicy
   metadata:
     name: require-signed-images
   spec:
     validationActions: [Audit]   # switch to [Deny] after all images are signing
     matchConstraints:
       resourceRules:
       - apiGroups: [""]
         apiVersions: ["v1"]
         operations: ["CREATE", "UPDATE"]
         resources: ["pods"]
     matchImageReferences:
     - glob: "ghcr.io/<org>/*"
     validations:
     - expression: >
         images.containers.map(image, verifyImageSignatures(image, [{"keyless": {
           "url": "https://fulcio.sigstore.dev",
           "rekor": {"url": "https://rekor.sigstore.dev"},
           "identities": [{"issuer": "https://token.actions.githubusercontent.com",
             "subjectRegExp": "https://github.com/<org>/.*"}]
         }}])).all(e, e > 0)
       message: "Image must be signed via Sigstore keyless signing from GitHub Actions"
   ```
3. Show audit-first deployment:
   ```yaml
   spec:
     validationActions: [Audit]   # start here, switch to [Deny] after validation
   ```
4. Cross-reference: `/platform-skills:kyverno` for full ImageValidatingPolicy guidance

Reference: `references/supply-chain.md` → Kyverno enforcement, `references/kyverno.md` → ImageValidatingPolicy

## Mode: slsa

Generate a GitHub Actions workflow for SLSA Level 2 provenance using `slsa-github-generator`.

Steps:
1. Explain what SLSA L2 gives: signed provenance linking the artifact to the specific build inputs (source commit, workflow, runner)
2. Generate the workflow using the official reusable workflow:
   ```yaml
   jobs:
     build:
       runs-on: ubuntu-latest
       outputs:
         digest: ${{ steps.build.outputs.digest }}
       permissions:
         contents: read
         packages: write
       steps:
         - name: Build and push image
           id: build
           uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355  # v6.10.0
           with:
             push: true
             tags: ghcr.io/<org>/<image>:${{ github.sha }}

     provenance:
       needs: build
       permissions:
         actions: read
         id-token: write
         packages: write
       uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@5a775b367a56d5bd118a224a811bba288150a563  # v2.0.0
       with:
         image: ghcr.io/<org>/<image>
         digest: ${{ needs.build.outputs.digest }}
         registry-username: ${{ github.actor }}
       secrets:
         registry-password: ${{ secrets.GITHUB_TOKEN }}
   ```
3. Show provenance verification:
   ```bash
   slsa-verifier verify-image \
     ghcr.io/<org>/<image>@<digest> \
     --source-uri github.com/<org>/<repo> \
     --source-branch main
   ```
4. Note: `generator_container_slsa3.yml` produces L2 provenance by default; L3 requires hermetic builds not available on standard GitHub-hosted runners

Reference: `references/supply-chain.md` → SLSA levels, slsa-github-generator

---

Signing and SBOMs cover what the pipeline *produces*. They say nothing about the pipeline itself — an unpinned `uses:` or a `pull_request_target` checkout of untrusted code compromises the build before any artifact exists. To audit the workflows that run this supply chain, including `unpinned-uses` hash-pin policy enforcement, use `/platform-skills:zizmor`. They also say nothing about whether a credential leaked into the repo that produces this artifact in the first place — for that, live-validate and revoke with `/platform-skills:kingfisher`.

---

After completing this task, log errors and learnings via `/platform-skills:self-improve log`.