Expert · DevSecOps · topic 48 of 53 · 35 min
Software supply chain security
Explanation
What is the software supply chain?
The software supply chain is everything that goes into what you ship: your own code, the open-source packages you install, the packages those packages install (transitive dependencies), the base image in your Dockerfile, the build tools, the CI runners and the reusable actions in your workflows. A small Node.js API with 20 direct dependencies often pulls in several hundred transitive ones. Any of them can carry a vulnerability (a weakness an attacker could use) or, rarely, malicious code.
Real incidents show why this matters. Log4Shell (December 2021) was a critical flaw in the Log4j logging library used inside thousands of Java products. In 2024 a backdoor was found in the xz compression tool before it reached most stable Linux releases. In March 2025 the tags of a popular GitHub Action, tj-actions/changed-files, were moved to a malicious commit that printed CI secrets into build logs.
SCA and lockfiles
SCA (software composition analysis) lists your dependencies and compares them with vulnerability databases, such as CVE records, the GitHub Advisory Database and OSV. A CVE (Common Vulnerabilities and Exposures) ID is a public name for one known vulnerability, like CVE-2021-44228 for Log4Shell. Tools include Dependabot, Snyk, OWASP Dependency-Check, Trivy, npm audit and pip-audit.
A lockfile (package-lock.json, poetry.lock, go.sum) records the exact version and a hash of every dependency, including transitive ones. Commit it, and install from it in CI (npm ci rather than npm install), so every build uses exactly the same, checked packages.
Typosquatting and dependency confusion: the defences
Typosquatting is publishing a harmful package with a name close to a popular one, hoping someone mistypes it. Dependency confusion happens when a company uses a private package name, and a public package with the same name and a higher version gets installed instead because the package manager checks the public registry too.
- Use scoped or namespaced packages for internal code (for example @acme/payments) and point that scope at your private registry.
- Use one internal registry proxy (such as Artifactory, Nexus, GitHub Packages or Azure Artifacts) as the only source for builds.
- Commit lockfiles with integrity hashes, and review every new dependency in the pull request: who maintains it, how popular it is, when it was last updated.
The scanning family
| Type | What it checks | When it runs | Examples |
|---|---|---|---|
| SAST (static analysis) | Your source code, without running it | Every pull request | Semgrep, SonarQube, CodeQL |
| SCA | Dependencies and their known vulnerabilities | Every pull request and daily | Dependabot, Snyk, OWASP Dependency-Check, Trivy |
| Secret scanning | Keys and tokens in code and history | Pre-commit and every push | gitleaks, GitHub secret scanning |
| Container image scanning | OS packages and libraries inside an image | After the image is built, and on a schedule | Trivy, Grype, Docker Scout |
| IaC scanning | Misconfiguration in Terraform, Kubernetes YAML, Dockerfiles | Every pull request | Checkov, Trivy (tfsec is now part of Trivy) |
| DAST (dynamic analysis) | A running app, tested from the outside | Against staging, before release | ZAP |
SBOMs: the ingredients list
An SBOM (software bill of materials) is a machine-readable list of every component and version inside your software, like the ingredients list on a food packet. The two main formats are SPDX (from the Linux Foundation, also an ISO standard) and CycloneDX (from OWASP). Governments and large customers increasingly ask for SBOMs: the US government pushed for them after a 2021 executive order, CERT-In published SBOM guidelines in India in 2024, and the EU Cyber Resilience Act requires them from product makers. The practical reason is simple: when the next Log4Shell is announced, an SBOM answers "are we affected?" in minutes instead of days.
syft ghcr.io/acme/canteen-api:3f9c2ab -o spdx-json > sbom.spdx.json # make an SPDX SBOM
trivy image --format cyclonedx --output sbom.cdx.json ghcr.io/acme/canteen-api:3f9c2ab
grype sbom:./sbom.spdx.json # scan the SBOM for known vulnerabilitiesSigning, provenance and SLSA
Signing proves an image came from you and was not changed. cosign, from the Sigstore project, signs container images and stores the signature next to the image in the registry. It also supports keyless signing, where the CI job's OIDC identity is used instead of a long-lived key and the signature is recorded in a public transparency log. Your cluster or deploy job then verifies the signature before running the image.
cosign sign --key cosign.key ghcr.io/acme/canteen-api@sha256:4a1f...e9
cosign verify --key cosign.pub ghcr.io/acme/canteen-api@sha256:4a1f...e9Provenance is a signed record of how an artefact was built: which source commit, which build system, which steps. SLSA (Supply-chain Levels for Software Artifacts, said "salsa") is a framework whose build levels describe how trustworthy that provenance is, from "provenance exists" up to "built on a hardened, isolated build platform".
Pin by digest, update with bots
A tag like node:22-slim or actions/checkout@v7 can be moved to point at different content. A digest (sha256:...) or a full commit SHA cannot. Pin base images by digest and third-party actions by full commit SHA, with the version in a comment. Then let Dependabot or Renovate open small pull requests to update the pins, so you stay pinned and current.
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Software supply chain security · 1/7
Your software is mostly other people's code: libraries, the libraries they use, base images, build tools and CI actions. That is your supply chain.
Prefer a video by a teacher? Find free videos on “software supply chain security sbom cosign slsa explained” on YouTube ↗
In real life: Log4Shell week at an Indian IT services company
When Log4Shell was announced in December 2021, a Chennai-based services company had to tell dozens of clients, including banks, whether they were affected. Teams with SBOMs and SCA dashboards searched for log4j-core and had a list of affected versions and projects within hours. Teams without them logged in to servers and searched JAR files by hand for days. Afterwards the company made an SBOM a required output of every build and stored it with each release.
Practice (0/3 done)
Which kind of tool finds a vulnerable version of a library listed in your package-lock.json?
Write affected(components, vulns). components is an SBOM-like list of {"name": ..., "version": "1.2.3"}. vulns is a list of {"id": ..., "package": ..., "range": ...} where range is one or more conditions joined by commas, like "<1.2.3" or ">=2.0.0,<2.4.1". Operators: <, <=, >, >=, ==. Return a sorted list of (name, version, vuln_id) for every component whose version matches ALL conditions of a vulnerability for the same package. Compare versions as numbers, not text: 2.10.0 is newer than 2.9.0. Also write parse_version(text) that returns a tuple of 3 ints, padding missing parts with 0 ("1.2" gives (1, 2, 0)).
Add supply chain checks to a GitHub Actions workflow for a Node.js API that builds a Docker image. Write the job steps (YAML or a clear list) and say which steps should FAIL the build and which should only report.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Kubernetes securityDevSecOps · same module
- DevSecOps: shifting security leftDevSecOps · same module
- Containers, images and registriesCloud Computing (AWS, Azure, Google Cloud) · Containers in the cloud
- Modules, environments and Terraform in CIInfrastructure as code with Terraform
- Testing, quality gates and artefactsCI/CD pipelines
- The OWASP Top 10: the most common web risksBackend Development · Backend security
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What is an SBOM?
Answer: A list of every component and version inside a piece of software
A software bill of materials is the ingredients list of your software, in formats like SPDX or CycloneDX.
Why pin a GitHub Action by full commit SHA instead of a tag like @v4?
Answer: A tag can be moved to different code; a commit SHA always means the same code
In the tj-actions incident, existing tags were moved to a malicious commit. A SHA cannot be moved.
Which tool is used to sign and verify container images?
Answer: cosign
cosign, from the Sigstore project, signs images and verifies signatures.
When is it acceptable to run a DAST scan such as ZAP against a website?
Answer: Only on your own application or with written permission from the owner
Testing other people's systems without permission is an offence, in India under the IT Act 2000 (sections 43 and 66).
Which scanner category finds a public S3 bucket defined in a Terraform file before it is created?
Answer: IaC scanning (for example Checkov or Trivy)
IaC scanners read Terraform and Kubernetes files and flag risky settings before anything is deployed.
What does pinning an image by digest (image@sha256:...) give you?Related
Answer: The exact same image content every time, because a digest cannot be moved like a tag
A digest is a content hash. Remember to update pins on a schedule so patches still arrive.
Why pin a third-party action to a full commit SHA instead of a tag like v2?Related
Answer: A tag can be moved to different code later; a commit SHA always means the same code
Pinning to a SHA protects you if the action's repository is compromised and a tag is moved.
From GitHub Actions
What is Google Cloud's current registry for container images?Related
Answer: Artifact Registry
Artifact Registry replaced Container Registry.
Why pin the version of a Registry module?Related
Answer: So an upstream update cannot change your infrastructure without review
Pinning means updates happen only when you change the version in a reviewed pull request.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “DevSecOps” before its exam: Kubernetes security.
- Module 11 exam: DevSecOps · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
- Then the next module, GitOps, platform engineering and DevOps careers. 53 topics left in the course before the final exam.