Supply Chain Security

Verifying the authenticity and integrity of Sentinel releases before deploying to production.

Overview

Sentinel sits at the edge of your network and handles all inbound traffic. Verifying that the binary or container image you deploy is the exact artifact built by the Sentinel CI pipeline is a critical operational practice.

Examples on this page use CalVer release versions (e.g., 26.01_0). Replace with your target version. See Versioning for the full versioning scheme and LTS windows.

Every release includes:

  • SHA-256 checksums for integrity verification
  • Sigstore cosign signatures (keyless, tied to GitHub Actions OIDC)
  • SLSA v1.0 provenance attestations (Build Level 3)
  • Software Bill of Materials in CycloneDX and SPDX formats

Verifying Binary Releases

SHA-256 Checksums

Every release archive has a corresponding .sha256 file. This is the simplest verification step.

# Download binary and checksum
VERSION="26.01_0"
curl -LO "https://github.com/raskell-io/sentinel/releases/download/${VERSION}/sentinel-${VERSION}-linux-amd64.tar.gz"
curl -LO "https://github.com/raskell-io/sentinel/releases/download/${VERSION}/sentinel-${VERSION}-linux-amd64.tar.gz.sha256"

# Verify checksum
sha256sum -c "sentinel-${VERSION}-linux-amd64.tar.gz.sha256"

Expected output:

sentinel-26.01_0-linux-amd64.tar.gz: OK

Cosign Signature Verification

Cosign keyless signatures prove the binary was built by the Sentinel GitHub Actions pipeline, not by a third party.

Install cosign

# Linux
curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign

# macOS
brew install cosign

Verify a binary

VERSION="26.01_0"

cosign verify-blob \
  --bundle "sentinel-${VERSION}-linux-amd64.tar.gz.bundle" \
  --certificate-identity-regexp "github.com/raskell-io/sentinel" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  "sentinel-${VERSION}-linux-amd64.tar.gz"

Expected output:

Verified OK

What this proves:

  • The binary was built by a GitHub Actions workflow in the raskell-io/sentinel repository
  • The signature is recorded in the Sigstore transparency log (Rekor) and is publicly auditable
  • No private keys are involved — the signing identity is the GitHub Actions OIDC token

Verifying Container Images

Cosign Image Verification

cosign verify \
  ghcr.io/raskell-io/sentinel:26.01_0 \
  --certificate-identity-regexp "github.com/raskell-io/sentinel" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"

Inspecting Container SBOM

The container SBOM is attached as a cosign attestation:

cosign verify-attestation \
  --type cyclonedx \
  --certificate-identity-regexp "github.com/raskell-io/sentinel" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/raskell-io/sentinel:26.01_0 | jq -r '.payload' | base64 -d | jq .

SLSA Provenance Verification

SLSA provenance proves the build was performed on GitHub-hosted runners from a specific source commit.

Install slsa-verifier

# Linux
curl -LO https://github.com/slsa-framework/slsa-verifier/releases/latest/download/slsa-verifier-linux-amd64
chmod +x slsa-verifier-linux-amd64
sudo mv slsa-verifier-linux-amd64 /usr/local/bin/slsa-verifier

# macOS
brew install slsa-verifier

Verify provenance

VERSION="26.01_0"

slsa-verifier verify-artifact \
  "sentinel-${VERSION}-linux-amd64.tar.gz" \
  --provenance-path "sentinel-${VERSION}-linux-amd64.tar.gz.intoto.jsonl" \
  --source-uri github.com/raskell-io/sentinel

What SLSA Level 3 guarantees:

  • Build ran on GitHub-hosted infrastructure (not a developer laptop)
  • Build script is defined in the repository (not injected)
  • Provenance is non-forgeable (generated by the SLSA GitHub Generator, not the build itself)

Software Bill of Materials

Available Formats

Each release includes two SBOM formats:

FormatFileUse Case
CycloneDX 1.5sentinel-VERSION-sbom.cdx.jsonPreferred for vulnerability scanning
SPDX 2.3sentinel-VERSION-sbom.spdx.jsonPreferred for license compliance

Where to Find SBOMs

  • Binary releases: Attached as GitHub release assets
  • Container images: Attached as cosign attestations (see above)

Analyzing Dependencies

Scan SBOMs for known vulnerabilities using standard tools:

# Using grype (Anchore)
grype sbom:sentinel-26.01_0-sbom.cdx.json

# Using trivy (Aqua Security)
trivy sbom sentinel-26.01_0-sbom.cdx.json

# Using osv-scanner (Google)
osv-scanner --sbom sentinel-26.01_0-sbom.cdx.json

License Analysis

# List all dependency licenses
cat sentinel-26.01_0-sbom.cdx.json | jq '[.components[].licenses[]?.license.id] | group_by(.) | map({license: .[0], count: length}) | sort_by(-.count)'

Building from Source

You can independently verify that a release binary matches a build from source:

# Clone at the release tag
VERSION="26.01_0"
git clone --depth 1 --branch "$VERSION" https://github.com/raskell-io/sentinel.git
cd sentinel

# Build
cargo build --release

# Compare checksum
sha256sum target/release/sentinel

Note: Exact byte-for-byte reproducibility depends on the Rust compiler version, target triple, and build environment matching the CI pipeline. The release notes include the Rust version used.

CI/CD Integration

GitHub Actions

Verify the Sentinel container image before deploying:

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

- name: Verify Sentinel image
  run: |
    cosign verify \
      ghcr.io/raskell-io/sentinel:26.01_0 \
      --certificate-identity-regexp "github.com/raskell-io/sentinel" \
      --certificate-oidc-issuer "https://token.actions.githubusercontent.com"

Kubernetes Admission Control (Kyverno)

Enforce cosign verification on Sentinel images in your cluster:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-sentinel-images
spec:
  validationFailureAction: Enforce
  rules:
    - name: verify-cosign-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "ghcr.io/raskell-io/sentinel*"
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/raskell-io/sentinel/*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: "https://rekor.sigstore.dev"

Kubernetes Admission Control (OPA/Gatekeeper)

apiVersion: externaldata.gatekeeper.sh/v1beta1
kind: Provider
metadata:
  name: cosign-verifier
spec:
  url: https://cosign-gatekeeper-provider.cosign-system:8443/validate
  timeout: 5
---
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: cosignverification
spec:
  crd:
    spec:
      names:
        kind: CosignVerification
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package cosignverification
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          startswith(container.image, "ghcr.io/raskell-io/sentinel")
          not external_data({"provider": "cosign-verifier", "keys": [container.image]})
          msg := sprintf("Image %v failed cosign verification", [container.image])
        }

Compliance Notes

Sentinel’s supply chain security practices align with the following standards and frameworks:

StandardCoverage
SLSA Level 3Build provenance, non-forgeable attestations
EO 14028 (US)SBOM generation, software supply chain security
SSDF (NIST SP 800-218)Secure software development practices
CIS Software Supply ChainSigned artifacts, dependency management

For organizations requiring specific compliance documentation, see the Enterprise Builds offering which includes CalVer-based LTS releases, early security advisories, and configuration stability guarantees.

See Also