
This lab builds, from scratch, a Python project whose workflows reach zero
findings on the four workflow scanners, actionlint, zizmor and poutine run
locally, plumber as a blocking gate in CI, publishes a signed image with
verifiable SLSA provenance and a verifiable SBOM, and honestly maximises OpenSSF
Scorecard. It is made of 5 guides to follow in order, backed by a
reproducible public repository. Application vulnerabilities are covered by
Trivy. It addresses an advanced reader who wants an executable reference, not
a magic recipe: every decision is explained, why this setting, which control it
satisfies, which trap it avoids.
What exactly does this lab build?
The lab produces a complete chain: five CI jobs, an attested build, a publication to GHCR and a double posture measurement. Four analyses run in parallel (lint, tests, SAST, audit) plus a build-check, that is the five CI jobs, then an attested build (SLSA provenance, SBOM, Cosign signature), a publication to GHCR, then a double measurement, the posture with OpenSSF Scorecard and the real exploitability with Plumber.
The running project is a deliberately minimal Python API (FastAPI). It is not the application that matters but the chain that builds, attests and publishes it. By the end of the lab, every published image carries:
- a signed SLSA provenance attestation (Sigstore keyless, Rekor log);
- an attested SBOM (CycloneDX) tied to the digest in the registry;
- a verifiable Cosign signature, plus a
provenance.intoto.jsonlattached to the release.
And the repository itself is governed: branch protection through a ruleset, a mandatory code-owner review, Dependabot with quarantine, and a posture measured by OpenSSF Scorecard.
Where is the reference repository?
The whole lab rests on the public repository
stephrobert/secure-python-pipeline, which you can browse, clone and fork to
reproduce every step identically. Nothing is hidden there: the published
workflows are the ones the guides comment on, line by line.
You will find it at github.com/stephrobert/secure-python-pipeline.
git clone https://github.com/stephrobert/secure-python-pipelineIt holds the seven workflows (CI, release, CodeQL, Scorecard, fuzzing,
plumber, SLSA verification), the hardened Dockerfile, the hash-locked
dependencies and the governance files (SECURITY.md, CODEOWNERS,
dependabot.yml). The guides that follow quote the code of that repository
as it stands: no excerpt is reconstructed from memory, every command was run
and validated before being documented.
Who is this lab for?
This lab is for people who already write GitHub Actions workflows and want to bring them up to the level of a security reference. If you have never written a workflow, start with the GitHub Actions foundations: the lab assumes the syntax, the jobs and the secrets are known.
Familiarity with supply chain concepts (SLSA, SBOM, Sigstore) helps, but every notion is recalled along the way.
What are the 5 guides, and in which order?
The lab is followed in order, from the bootstrap to the scoring: each guide
consumes what the previous one produced. Starting with the pipeline before
laying the base leads to the same place every time, a workflow failing on
unlocked dependencies and a Dockerfile running as root.
-
Secure bootstrap lays the base: the repository, the governance, the FastAPI application, hash-locked dependencies, a non-root
Dockerfile. Everything is validated locally before the first workflow. -
Hardened CI pipeline writes the integration workflow and takes it through the four workflow scanners,
actionlint,zizmor,poutineandplumber, with no tolerated exception. -
Verifiable build adds the native SLSA provenance, the attested SBOM and the keyless Cosign signature, all verifiable by a third party.
-
Protection and governance protects the branch with a ruleset, enforces code-owner review and equips the scanners with a GitHub App token.
-
Scoring and hardening honestly maximises OpenSSF Scorecard and aims for the OpenSSF Best Practices badge on
bestpractices.dev.
Next steps
- Lab 1: secure bootstrap: the repository, the governance files and the hardened image, all validated locally.
- Lab 2: hardened CI pipeline: the integration workflow that passes actionlint, zizmor, poutine and plumber with no tolerated exception.
- Lab 5: scoring and hardening: the OpenSSF Scorecard result earned honestly, with the Best Practices badge in sight.