[PR #15] [MERGED] feat: enterprise supply chain security — cosign keyless signing, SBOM attestation, SLSA provenance, Trivy scanning, Kyverno enforcement, ACT smoke validation #26

Closed
opened 2026-06-08 09:03:29 +00:00 by ryangr0 · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/webgrip/infrastructure/pull/15
Author: @Ryangr0
Created: 5/28/2026
Status: ✅ Merged
Merged: 5/29/2026
Merged by: @Ryangr0

Base: main ← Head: feat/supply-chain-security


📝 Commits (4)

  • 001fc74 feat: enterprise supply chain security — cosign, SBOM, SLSA, Trivy, Kyverno
  • b94c32d Add ACT dry-run smoke validation for supply chain workflow
  • 1293e3d Refine ACT dry-run mock artifacts for action smoke tests
  • 412662d Use realistic synthetic digest for ACT dry-run path

📊 Changes

15 files changed (+1469 additions, -1 deletions)

View changed files

➕ .actrc (+2 -0)
➕ .github/act/release-published.event.json (+10 -0)
➕ .github/actions/cosign-sign-attest/action.yml (+346 -0)
➕ .github/workflows/act_supply_chain_smoke.yml (+28 -0)
📝 .github/workflows/on_release_published.yml (+59 -0)
📝 README.md (+11 -1)
➕ docs/adrs/0002-supply-chain-security.md (+167 -0)
➕ docs/techdocs/docs/security/image-signing.md (+132 -0)
➕ docs/techdocs/docs/security/index.md (+53 -0)
➕ docs/techdocs/docs/security/kyverno-enforcement.md (+154 -0)
➕ docs/techdocs/docs/security/sbom-attestations.md (+154 -0)
➕ docs/techdocs/docs/security/supply-chain-security.md (+109 -0)
➕ docs/techdocs/docs/security/vulnerability-scanning.md (+105 -0)
📝 docs/techdocs/mkdocs.yml (+7 -0)
➕ ops/kyverno/cluster-policies/verify-webgrip-images.yaml (+132 -0)

📄 Description

Summary

This PR implements end-to-end software supply chain security for every container image published from this repository, targeting SLSA Build Level 2 and aligning with NIST SSDF (SP 800-218) and the CIS Software Supply Chain Security Guide.

No long-lived signing keys are required. Everything is driven by GitHub OIDC.

It also adds local ACT smoke-validation support so the supply-chain workflow shape can be validated before running in GitHub-hosted release jobs.


What this adds

🔐 Keyless image signing (cosign + GitHub OIDC)

Every released image is signed using cosign's keyless flow:

  1. GitHub issues an OIDC token for the workflow invocation
  2. cosign exchanges it with Sigstore's Fulcio CA for a short-lived X.509 certificate
  3. The cert's SAN encodes the exact workflow identity: https://github.com/webgrip/infrastructure/.github/workflows/on_release_published.yml@refs/tags/<tag>
  4. The signature + cert are stored in GHCR and recorded in the Rekor public transparency log

Forging this signature requires compromising GitHub's OIDC infrastructure, not just stealing a secret.

📦 SBOM generation + attestation (Syft + cosign)

Syft generates a full component inventory for every image in two formats:

  • CycloneDX JSON — primary format; cosign-attested in the OCI registry; ingestible by Dependency-Track and GUAC
  • SPDX JSON — ISO 5962:2021; NTIA minimum-element compliant; for license compliance tooling

Both SBOMs are also uploaded as 90-day workflow artifacts.

🏛️ SLSA Build Provenance (GitHub native attestations)

actions/attest-build-provenance records SLSA v1.0 Build Provenance in GitHub's attestation store and pushes it to the OCI registry. Verifiable with:

gh attestation verify oci://ghcr.io/webgrip/<image>@sha256:<digest> --owner webgrip

🛡️ Vulnerability scanning (Trivy)

Trivy scans every released image for OS and library CVEs:

  • SARIF results uploaded to GitHub Security tab (Code scanning)
  • Table summary printed in the build log
  • Non-blocking by default (exit-code: 0) — findings are tracked, not release-blocking

🔒 Kyverno cluster enforcement policy

ops/kyverno/cluster-policies/verify-webgrip-images.yaml provides a ClusterPolicy for the homelab cluster that:

  • Verifies the cosign signature at Pod admission time
  • Verifies the CycloneDX SBOM attestation is present
  • Mutates image tags to digest references (prevents tag-mutation attacks on running Pods)
  • Ships in Audit mode — switch to Enforce once all images are signed

🧪 ACT local smoke validation

Adds ACT-focused validation support for the signing pipeline:

  • Composite action now supports dry-run: 'true' to skip OIDC signing / registry mutation while still validating flow and outputs
  • New ACT smoke workflow executes the composite action in dry-run mode
  • Added ACT runner defaults and a sample release event payload for local simulation
  • README now includes local ACT commands for both smoke and release-event simulation

Changed files

File Change
.github/actions/cosign-sign-attest/action.yml New/Updated — composite action for signing pipeline, now with ACT dry-run mode
.github/workflows/on_release_published.yml Updated — release signing jobs
.github/workflows/act_supply_chain_smoke.yml New — ACT smoke workflow for local validation
.github/act/release-published.event.json New — sample release event payload for ACT
.actrc New — local ACT runner defaults
README.md Updated — ACT usage commands
ops/kyverno/cluster-policies/verify-webgrip-images.yaml New — ClusterPolicy for homelab-cluster enforcement
docs/adrs/0002-supply-chain-security.md New — ADR documenting the decision
docs/techdocs/docs/security/index.md New — security section overview
docs/techdocs/docs/security/supply-chain-security.md New — threat model, SLSA framework, NIST SSDF mapping
docs/techdocs/docs/security/image-signing.md New — cosign keyless flow, verification commands
docs/techdocs/docs/security/sbom-attestations.md New — SBOM formats, attestation inspection, GUAC/DT integration
docs/techdocs/docs/security/vulnerability-scanning.md New — Trivy usage, remediation workflow
docs/techdocs/docs/security/kyverno-enforcement.md New — cluster policy rollout strategy
docs/techdocs/mkdocs.yml Updated — Security section added to nav

Required job permissions

The new signing jobs require these permissions (scoped to the signing job only, not the build job):

permissions:
  contents: read
  packages: write       # push attestation OCI artifacts to GHCR
  id-token: write       # GitHub OIDC token for cosign keyless signing
  security-events: write # Trivy SARIF upload to Security tab
  attestations: write   # actions/attest-build-provenance

Verification after merge

Once a release is published after this PR merges:

# Verify cosign signature
cosign verify \
  --certificate-identity-regexp 'https://github.com/webgrip/infrastructure/.*on_release_published.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  ghcr.io/webgrip/<image>@sha256:<digest>

# Download and inspect the SBOM
cosign download attestation ghcr.io/webgrip/<image>@sha256:<digest> \
  | jq -r 'select(.payload) | .payload' | base64 -d | jq '.predicate.metadata'

# Verify SLSA provenance
gh attestation verify oci://ghcr.io/webgrip/<image>@sha256:<digest> --owner webgrip

Local ACT smoke checks:

# smoke-test composite action without registry/OIDC side effects
act workflow_dispatch -W .github/workflows/act_supply_chain_smoke.yml

# simulate release payload locally
act release -W .github/workflows/on_release_published.yml -e .github/act/release-published.event.json

Rollout plan for the cluster

  1. Merge this PR
  2. Publish a new release for each image (or retag existing ones)
  3. Apply ops/kyverno/cluster-policies/verify-webgrip-images.yaml to the homelab cluster in Audit mode
  4. Monitor kubectl get policyreport -A for violations
  5. Once all webgrip images show clean, switch policy to Enforce

Standards coverage

Standard Coverage
SLSA Build L2 ✅ Signed provenance, hosted build service
NIST SSDF DS.2.1 ✅ Sign release artifacts
NIST SSDF DS.6.1 ✅ SBOM for released software
NIST SSDF RV.1 ✅ Vulnerability identification via Trivy
NTIA Minimum SBOM Elements ✅ Via CycloneDX + SPDX
CIS SSC 2.3.1 ✅ All artifacts signed
CIS SSC 2.4.1 ✅ SBOMs generated per release

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/webgrip/infrastructure/pull/15 **Author:** [@Ryangr0](https://github.com/Ryangr0) **Created:** 5/28/2026 **Status:** ✅ Merged **Merged:** 5/29/2026 **Merged by:** [@Ryangr0](https://github.com/Ryangr0) **Base:** `main` ← **Head:** `feat/supply-chain-security` --- ### 📝 Commits (4) - [`001fc74`](https://github.com/webgrip/infrastructure/commit/001fc74efd32cd6d06abea764609d53ab3390544) feat: enterprise supply chain security — cosign, SBOM, SLSA, Trivy, Kyverno - [`b94c32d`](https://github.com/webgrip/infrastructure/commit/b94c32d6bb404cc7f217b4ef534c9f4e240269e8) Add ACT dry-run smoke validation for supply chain workflow - [`1293e3d`](https://github.com/webgrip/infrastructure/commit/1293e3d6b3bd57d0d8df39b5ee4c32dfad075c63) Refine ACT dry-run mock artifacts for action smoke tests - [`412662d`](https://github.com/webgrip/infrastructure/commit/412662dcd4dc5b15b4b35568f656ea0f4597200c) Use realistic synthetic digest for ACT dry-run path ### 📊 Changes **15 files changed** (+1469 additions, -1 deletions) <details> <summary>View changed files</summary> ➕ `.actrc` (+2 -0) ➕ `.github/act/release-published.event.json` (+10 -0) ➕ `.github/actions/cosign-sign-attest/action.yml` (+346 -0) ➕ `.github/workflows/act_supply_chain_smoke.yml` (+28 -0) 📝 `.github/workflows/on_release_published.yml` (+59 -0) 📝 `README.md` (+11 -1) ➕ `docs/adrs/0002-supply-chain-security.md` (+167 -0) ➕ `docs/techdocs/docs/security/image-signing.md` (+132 -0) ➕ `docs/techdocs/docs/security/index.md` (+53 -0) ➕ `docs/techdocs/docs/security/kyverno-enforcement.md` (+154 -0) ➕ `docs/techdocs/docs/security/sbom-attestations.md` (+154 -0) ➕ `docs/techdocs/docs/security/supply-chain-security.md` (+109 -0) ➕ `docs/techdocs/docs/security/vulnerability-scanning.md` (+105 -0) 📝 `docs/techdocs/mkdocs.yml` (+7 -0) ➕ `ops/kyverno/cluster-policies/verify-webgrip-images.yaml` (+132 -0) </details> ### 📄 Description ## Summary This PR implements end-to-end software supply chain security for every container image published from this repository, targeting **SLSA Build Level 2** and aligning with **NIST SSDF (SP 800-218)** and the **CIS Software Supply Chain Security Guide**. No long-lived signing keys are required. Everything is driven by GitHub OIDC. It also adds **local ACT smoke-validation support** so the supply-chain workflow shape can be validated before running in GitHub-hosted release jobs. --- ## What this adds ### 🔐 Keyless image signing (cosign + GitHub OIDC) Every released image is signed using cosign's keyless flow: 1. GitHub issues an OIDC token for the workflow invocation 2. cosign exchanges it with Sigstore's Fulcio CA for a short-lived X.509 certificate 3. The cert's SAN encodes the exact workflow identity: `https://github.com/webgrip/infrastructure/.github/workflows/on_release_published.yml@refs/tags/<tag>` 4. The signature + cert are stored in GHCR and recorded in the Rekor public transparency log Forging this signature requires compromising GitHub's OIDC infrastructure, not just stealing a secret. ### 📦 SBOM generation + attestation (Syft + cosign) Syft generates a full component inventory for every image in two formats: - **CycloneDX JSON** — primary format; cosign-attested in the OCI registry; ingestible by Dependency-Track and GUAC - **SPDX JSON** — ISO 5962:2021; NTIA minimum-element compliant; for license compliance tooling Both SBOMs are also uploaded as 90-day workflow artifacts. ### 🏛️ SLSA Build Provenance (GitHub native attestations) `actions/attest-build-provenance` records SLSA v1.0 Build Provenance in GitHub's attestation store and pushes it to the OCI registry. Verifiable with: ```bash gh attestation verify oci://ghcr.io/webgrip/<image>@sha256:<digest> --owner webgrip ``` ### 🛡️ Vulnerability scanning (Trivy) Trivy scans every released image for OS and library CVEs: - SARIF results uploaded to GitHub Security tab (Code scanning) - Table summary printed in the build log - Non-blocking by default (`exit-code: 0`) — findings are tracked, not release-blocking ### 🔒 Kyverno cluster enforcement policy `ops/kyverno/cluster-policies/verify-webgrip-images.yaml` provides a `ClusterPolicy` for the homelab cluster that: - Verifies the cosign signature at Pod admission time - Verifies the CycloneDX SBOM attestation is present - Mutates image tags to digest references (prevents tag-mutation attacks on running Pods) - Ships in `Audit` mode — switch to `Enforce` once all images are signed ### 🧪 ACT local smoke validation Adds ACT-focused validation support for the signing pipeline: - Composite action now supports `dry-run: 'true'` to skip OIDC signing / registry mutation while still validating flow and outputs - New ACT smoke workflow executes the composite action in dry-run mode - Added ACT runner defaults and a sample `release` event payload for local simulation - README now includes local ACT commands for both smoke and release-event simulation --- ## Changed files | File | Change | |------|--------| | `.github/actions/cosign-sign-attest/action.yml` | **New/Updated** — composite action for signing pipeline, now with ACT `dry-run` mode | | `.github/workflows/on_release_published.yml` | **Updated** — release signing jobs | | `.github/workflows/act_supply_chain_smoke.yml` | **New** — ACT smoke workflow for local validation | | `.github/act/release-published.event.json` | **New** — sample release event payload for ACT | | `.actrc` | **New** — local ACT runner defaults | | `README.md` | **Updated** — ACT usage commands | | `ops/kyverno/cluster-policies/verify-webgrip-images.yaml` | **New** — `ClusterPolicy` for homelab-cluster enforcement | | `docs/adrs/0002-supply-chain-security.md` | **New** — ADR documenting the decision | | `docs/techdocs/docs/security/index.md` | **New** — security section overview | | `docs/techdocs/docs/security/supply-chain-security.md` | **New** — threat model, SLSA framework, NIST SSDF mapping | | `docs/techdocs/docs/security/image-signing.md` | **New** — cosign keyless flow, verification commands | | `docs/techdocs/docs/security/sbom-attestations.md` | **New** — SBOM formats, attestation inspection, GUAC/DT integration | | `docs/techdocs/docs/security/vulnerability-scanning.md` | **New** — Trivy usage, remediation workflow | | `docs/techdocs/docs/security/kyverno-enforcement.md` | **New** — cluster policy rollout strategy | | `docs/techdocs/mkdocs.yml` | **Updated** — Security section added to nav | --- ## Required job permissions The new signing jobs require these permissions (scoped to the signing job only, not the build job): ```yaml permissions: contents: read packages: write # push attestation OCI artifacts to GHCR id-token: write # GitHub OIDC token for cosign keyless signing security-events: write # Trivy SARIF upload to Security tab attestations: write # actions/attest-build-provenance ``` --- ## Verification after merge Once a release is published after this PR merges: ```bash # Verify cosign signature cosign verify \ --certificate-identity-regexp 'https://github.com/webgrip/infrastructure/.*on_release_published.*' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ ghcr.io/webgrip/<image>@sha256:<digest> # Download and inspect the SBOM cosign download attestation ghcr.io/webgrip/<image>@sha256:<digest> \ | jq -r 'select(.payload) | .payload' | base64 -d | jq '.predicate.metadata' # Verify SLSA provenance gh attestation verify oci://ghcr.io/webgrip/<image>@sha256:<digest> --owner webgrip ``` Local ACT smoke checks: ```bash # smoke-test composite action without registry/OIDC side effects act workflow_dispatch -W .github/workflows/act_supply_chain_smoke.yml # simulate release payload locally act release -W .github/workflows/on_release_published.yml -e .github/act/release-published.event.json ``` --- ## Rollout plan for the cluster 1. Merge this PR 2. Publish a new release for each image (or retag existing ones) 3. Apply `ops/kyverno/cluster-policies/verify-webgrip-images.yaml` to the homelab cluster in `Audit` mode 4. Monitor `kubectl get policyreport -A` for violations 5. Once all webgrip images show clean, switch policy to `Enforce` --- ## Standards coverage | Standard | Coverage | |----------|----------| | SLSA Build L2 | ✅ Signed provenance, hosted build service | | NIST SSDF DS.2.1 | ✅ Sign release artifacts | | NIST SSDF DS.6.1 | ✅ SBOM for released software | | NIST SSDF RV.1 | ✅ Vulnerability identification via Trivy | | NTIA Minimum SBOM Elements | ✅ Via CycloneDX + SPDX | | CIS SSC 2.3.1 | ✅ All artifacts signed | | CIS SSC 2.4.1 | ✅ SBOMs generated per release | --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
ryangr0 2026-06-08 09:03:29 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
webgrip/infrastructure#26
No description provided.