7 Proven Steps: SLSA 1.1 Implementation in CI/CD

TL;DR (for dev & engineering leaders)

SLSA 1.1 raises the bar on build integrity and provenance. This guide gives you drop-in CI steps to: 1) generate provenance for every build, 2) sign artifacts & SBOMs, 3) verify at deploy, 4) block unsigned or policy-violating releases, 5) run OpenSSF Scorecard + policy-as-code checks, and 6) publish auditable evidence that helps you pass reviews and map to NIST CSF 2.0 / 800-171—without slowing delivery.

7 Proven Steps: SLSA 1.1 Implementation in CI/CD

Update: We’ve published a complete SSDF 1.1 CI/CD attestation walkthrough—SBOM, signing, provenance, and verification at deploy.
https://www.cybersrely.com/ssdf-1-1-ci-cd-attestation/


What you’ll build

  • A CI pipeline that emits a SLSA 1.1 provenance file for every build and signs images, tars, zips, SBOMs.
  • A CD gate that verifies signatures/provenance before rollout.
  • Policy-as-code to fail risky builds automatically.
  • An evidence store (digest-addressed) with artifacts auditors can reuse.

Step 1 — Generate SLSA provenance for every build

GitHub Actions (container image example):

name: build-and-provenance
on: [push]
jobs:
  build:
    permissions:
      id-token: write        # keyless signing
      contents: read
      packages: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build image
        run: |
          IMAGE=ghcr.io/${{ github.repository }}:${{ github.sha }}
          echo "IMAGE=$IMAGE" >> $GITHUB_ENV
          docker build -t $IMAGE .

      - name: Login to GHCR
        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin

      - name: Push image
        run: docker push $IMAGE

      # --- SLSA provenance (in-toto Statement, predicate v1) ---
      - name: Create build provenance
        run: |
          cat > provenance.json <<'JSON'
          {
            "_type": "https://in-toto.io/Statement/v1",
            "subject": [{"name": "${{ env.IMAGE }}", "digest": {"sha256": "$(docker inspect $IMAGE --format='{{.Id}}' | cut -d: -f2)"}}],
            "predicateType": "https://slsa.dev/provenance/v1",
            "predicate": {
              "buildType": "https://slsa.dev/container/build",
              "builder": {"id": "github-actions"},
              "buildConfig": {"workflow": "${{ github.workflow }}", "ref": "${{ github.ref }}"},
              "metadata": {"buildInvocationID": "${{ github.run_id }}"}
            }
          }
          JSON
          mkdir -p out && mv provenance.json out/provenance-${{ github.sha }}.json

Tip: For multi-artifact repos, emit one provenance per artifact (image, binary, zip) so you can verify each by digest later.


Step 2 — Sign artifacts, SBOMs, and provenance (keyless)

# Build SBOM (example with Syft CLI)
syft packages dir:. -o cyclonedx-json > out/sbom-${GITHUB_SHA}.json

# Cosign keyless sign: image + SBOM + provenance (OIDC via CI)
cosign sign ${IMAGE}
cosign attest --predicate out/sbom-${GITHUB_SHA}.json \
  --type cyclonedx ${IMAGE}
cosign attest --predicate out/provenance-${GITHUB_SHA}.json \
  --type slsaprovenance ${IMAGE}

GitHub Actions step (OIDC already enabled above):

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

- name: Sign & attest
  run: |
    cosign sign $IMAGE
    cosign attest --predicate out/sbom-${{ github.sha }}.json --type cyclonedx $IMAGE
    cosign attest --predicate out/provenance-${{ github.sha }}.json --type slsaprovenance $IMAGE

Step 3 — Verify at deploy (fail closed by default)

CD verification gate (Kubernetes example):

- name: Verify image & attestations
  run: |
    set -euo pipefail
    cosign verify $IMAGE
    cosign verify-attestation --type slsaprovenance $IMAGE | jq .
    cosign verify-attestation --type cyclonedx $IMAGE | jq .

Only roll out if verification passes:

- name: Deploy (only if verified)
  if: success()
  run: |
    kubectl set image deploy/app app=$IMAGE

Step 4 — Block unsigned or non-compliant releases (policy gates)

Conftest/OPA Rego policy to require SLSA provenance + Scorecard min score:

package cicd

default allow = false

# Inputs: verification JSON + scorecard JSON fed via CI steps
provenance_ok {
  input.attestations[_].type == "slsaprovenance"
  input.attestations[_].verified == true
}

scorecard_ok {
  sc := input.scorecard
  sc.score >= 7        # set your bar: 0..10
  not sc.checks[_].name == "Binary-Artifacts" with sc.checks[_].pass == false
}

allow { provenance_ok; scorecard_ok }

CI step to enforce the policy:

- name: Run policy checks
  run: |
    cosign verify-attestation --type slsaprovenance $IMAGE > out/verify.json
    scorecard --repo="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" --format=json > out/scorecard.json
    conftest test --input json --policy policy/ out/verify.json out/scorecard.json

Step 5 — Add OpenSSF Scorecard + “policy-as-code” in CI

Scorecard GitHub Action (fail under threshold & publish evidence):

- name: OpenSSF Scorecard
  uses: ossf/scorecard-action@v2
  with:
    results_file: out/scorecard.json
    results_format: json
- name: Enforce minimum Scorecard score
  run: |
    SCORE=$(jq '.score' out/scorecard.json)
    [ "${SCORE%.*}" -ge 7 ] || { echo "Scorecard < 7"; exit 1; }

Step 6 — Publish auditable artifacts to an evidence store

Digest-addressed layout:

evidence/
  images/
    sha256/<digest>/
      image.txt                 # reference (registry, tag)
      cosign-bundle.json        # signature bundle
      provenance.json           # SLSA v1.1 predicate
      sbom.cdx.json             # CycloneDX SBOM
      scorecard.json
      policy-result.json
      metadata.json             # build/run ids, reviewers, ticket links

Why it helps audits: reviewers can re-verify signatures by digest, trace build → source, and match SBOM to shipped artifact. This supports NIST CSF 2.0 (governance & protection themes) and NIST SP 800-171 families (e.g., configuration management, audit & accountability, system integrity) with concrete evidence, not just policy text.


Step 7 — Map dev controls to compliance (what auditors actually use)

Dev control (you ship)Evidence (you store)Helps with…*
Signed builds (keyless)cosign bundle + verify logsIntegrity & release control (CSF Protect; 800-171 CM/AU/SI)
SLSA provenance v1.1in-toto statement (predicate)Build traceability (CSF Govern/Protect; 800-171 CM)
SBOM (CycloneDX)sbom.cdx.json per digestComponent visibility (CSF Identify/Protect; 800-171 CM/RA)
Policy gates (OPA/Conftest)policy code + CI status + logsPreventative control (CSF Protect; 800-171 SI)
OpenSSF Scorecard ≥ thresholdscorecard.json + trendSecure-by-default practices (CSF Govern/Protect)

*High-level alignment for audit narratives; use your specific program’s mappings during formal assessments.


Real-time recipes (copy/paste)

GitLab CI variant:

build:
  image: gcr.io/kaniko-project/executor:latest
  script:
    - export IMAGE=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - /kaniko/executor --destination $IMAGE
    - cosign sign $IMAGE
    - syft packages dir:. -o cyclonedx-json > sbom.json
    - cosign attest --predicate sbom.json --type cyclonedx $IMAGE
    - ./scripts/gen-provenance.sh > provenance.json
    - cosign attest --predicate provenance.json --type slsaprovenance $IMAGE
  artifacts:
    paths: [sbom.json, provenance.json]
    when: always

deploy:
  stage: deploy
  script:
    - cosign verify $IMAGE
    - cosign verify-attestation --type slsaprovenance $IMAGE
    - cosign verify-attestation --type cyclonedx $IMAGE
    - kubectl set image deploy/app app=$IMAGE

Minimal gen-provenance.sh:

#!/usr/bin/env bash
set -euo pipefail
cat << JSON
{
  "_type":"https://in-toto.io/Statement/v1",
  "subject":[{"name":"$IMAGE","digest":{"sha256":"$(crane digest $IMAGE | cut -d: -f2)"}}],
  "predicateType":"https://slsa.dev/provenance/v1",
  "predicate":{
    "buildType":"https://slsa.dev/container/build",
    "builder":{"id":"gitlab-ci"},
    "buildConfig":{"pipeline":"$CI_PIPELINE_ID","project":"$CI_PROJECT_PATH"},
    "metadata":{"buildInvocationID":"$CI_JOB_ID"}
  }
}
JSON

Kubernetes admission (block unsigned by default) — example with Kyverno:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-signed-images
spec:
  validationFailureAction: Enforce
  rules:
  - name: verify-signature
    match:
      resources:
        kinds: ["Pod"]
    verifyImages:
    - imageReferences: ["ghcr.io/yourorg/*"]
      attestations:
      - type: "https://slsa.dev/provenance/v1"
      # Optionally require Scorecard passthrough via custom attestation

Evidence your execs (and auditors) will love

  • One build → one digest → one folder (everything resolvable by SHA-256).
  • Deterministic: anyone can re-verify with the same commands.
  • Narrative ready: link tickets/owners/PRs in metadata.json.
  • Quarterly reviews: export Scorecard trends and signature coverage.

Where to go next (related reads on Cyber Rely)


Try our free scanner (great for quick external checks)

Use our Free Website Vulnerability Scanner to spot common issues before release and attach a report PDF to your evidence bundle.

The homepage of our free tool displays the URL input field and the “Scan” action.

Screenshot of the free tools webpage where you can access security assessment tools for different vulnerability detection.
Screenshot of the free tools webpage where you can access security assessment tools for different vulnerability detection.

Sample report summary to check Website Vulnerability (issues found & severities).

An example of a vulnerability assessment report generated using our free tool provides valuable insights into potential vulnerabilities.
An example of a vulnerability assessment report generated using our free tool provides valuable insights into potential vulnerabilities.

👉 Run a scan: https://free.pentesttesting.com/


Need help implementing this?

If you want a sprint-friendly rollout with artifact mapping to NIST CSF 2.0 / 800-171 and ready-to-verify evidence, our teams can help:


Free Consultation

If you have any questions or need expert assistance, feel free to schedule a Free consultation with one of our security engineers>>

🔐 Frequently Asked Questions (FAQs)

Find answers to commonly asked questions about SLSA 1.1 Implementation in CI/CD.

Get a Quote

Leave a Comment

Your email address will not be published. Required fields are marked *

Cyber Rely Logo cyber security
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.