Lock down the supply chain and enforce policy at admission
Continues from the last build: The Storefront now autoscales on real traffic, but nothing stops an unsigned, unscanned, or policy-violating image from reaching the cluster, and there is no admission guardrail to reject one.
Your pipeline ships fast and the platform scales itself, which is exactly when the next class of incident shows up: not a crash, but a compromised or careless artifact reaching prod.
What you'll build
A Storefront pipeline that scans every image with Trivy and fails on critical or high vulnerabilities, attaches an SBOM, and signs the image and its provenance with cosign keyless OIDC, paired with a Kyverno admission layer on the cluster that verifies the cosign signature against your workflow identity and rejects any Pod that is unsigned, from an untrusted registry, running as root, or missing required resource limits and labels, all proven by one deploy that Kyverno blocks and one that it admits.
See how we teach, before you sign up
You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:
permissions:
contents: read
packages: write
id-token: write # cosign keyless signing needs this
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ...build + push the image tagged by github.sha (earlier rung)...
- name: Scan image with Trivy
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: ghcr.io/${{ github.repository_owner }}/storefront:${{ github.sha }}
severity: 'CRITICAL,HIGH'
exit-code: '1' # fail the build on a match
# SBOM + cosign sign steps are added in the milestonesReading this file
aquasecurity/trivy-actionRuns the Trivy scanner against the freshly built image inside the workflow so vulnerabilities are caught before the image is signed or shipped.exit-code: '1'Makes Trivy return a non-zero exit code when it finds a matching vulnerability, which fails the job instead of merely printing a report.id-token: writeGrants the workflow the OIDC token cosign needs for keyless signing, so the signature is bound to this workflow identity with no stored key.
The scan + sign additions folded into the existing build job. Start with the scan in report mode, then set exit-code so criticals fail the build.
That's 1 of 9 explained code blocks in this single project.
The build, milestone by milestone
- 1
Scan the image in CI and fail the build on critical CVEs
5 guided stepsAn unscanned image is a known-unknown shipped to prod: the base layer alone can carry dozens of CVEs you never chose to run. Failing the build on criticals turns "we hope it is clean" into a gate that proves it before the image is ever signed or admitted.
- 2
Generate an SBOM so you know what is inside
5 guided stepsWhen the next Log4Shell drops, the only fast answer to "are we affected?" is a queryable list of every component in every image. An SBOM turns a frantic all-hands grep into a one-line lookup, and it is the input that later lets cosign attach a verifiable attestation about what you shipped.
- 3
Sign the image and its provenance with cosign keyless OIDC
5 guided stepsA SHA tag proves which bits you have, not who built them. Keyless cosign binds a signature to your workflow identity via OIDC and logs it in a transparency log, so the cluster can later prove an image was built by your pipeline and not pushed by a leaked registry token. No key to store means no key to leak.
- 4
Install Kyverno and verify signatures at admission
5 guided stepsCI signing is only half the loop: it proves what you built, but nothing stops a different, unsigned image from being applied straight to the cluster. An admission policy that verifies the cosign signature against your identity makes the cluster refuse anything your pipeline did not sign, closing the gap between "we sign" and "only signed runs".
- 5
Enforce registry, non-root, limits, and required labels
5 guided stepsSignature verification proves who built an image, not how it runs. A signed image can still come from a typo'd registry, run as root, hog a node with no limits, or be unowned with no labels. These validation rules make the cluster refuse the careless-config class of risk, not just the malicious-image one.
- 6
Prove it: one blocked deploy, one admitted deploy
5 guided stepsA guard you have not watched reject something is a guard you only believe in. Capturing one clear block and one clean admit turns the whole rung into demonstrable evidence: the cluster refuses the bad artifact and runs the good one, which is exactly the story you tell in a review or interview.
What's inside when you start
You'll walk away with
This is portfolio-grade. Build it free.
Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.
Start building