Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français
  • 10 min

By updated

Improve this page

GitHub logo

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.

Secure pipeline: four parallel CI analyses (lint with ruff, tests with pytest, SAST with bandit, audit with pip-audit and Trivy), then an attested build (SLSA provenance, Syft SBOM, Cosign signature), a GHCR publication by digest with attestations and signature, and finally posture measured by OpenSSF Scorecard and real exploitability by Plumber.CI: parallel analysesBuild + AttestDocker, SLSA provenance, SBOM (Syft), Cosign signatureGHCRimage @sha256 + attestations + signatureOpenSSF Scorecardposture (18 checks)Plumberreal exploitabilityLint(ruff)Test(pytest)SAST(bandit)Audit(pip-audit + Trivy)
Source · SVG
Esc to close, + and − to zoom, scroll to move around. 100 %

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.jsonl attached 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.

Terminal window
git clone https://github.com/stephrobert/secure-python-pipeline

It 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.

  1. 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.

  2. Hardened CI pipeline writes the integration workflow and runs it through the four workflow scanners, actionlint, zizmor, poutine and plumber, with no tolerated exception.

  3. Verifiable build adds the native SLSA provenance, the attested SBOM and the keyless Cosign signature, all verifiable by a third party.

  4. Protection and governance protects the branch with a ruleset, enforces code-owner review and equips the scanners with a GitHub App token.

  5. Scoring and hardening honestly maximises OpenSSF Scorecard and aims for the OpenSSF Best Practices badge on bestpractices.dev.

Key points

  • The lab is not about its FastAPI application, but about the chain that builds, attests and publishes it.
  • The five guides are followed in order: each one consumes what the previous one produced.
  • The workflows pass the four scanners, actionlint, zizmor, poutine and plumber, with no tolerated exception.
  • Every published image carries SLSA provenance, an attested SBOM and a Cosign signature a third party can verify.
  • The reference repository is public: every quoted excerpt can be compared with the code that actually ran.

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn