Supply Chain Security for CI/CD Pipelines: Dependencies, SBOMs, and Artifact Signing
The SolarWinds attack proved that compromising a single build pipeline can infiltrate thousands of organizations simultaneously. Supply chain security in CI/CD is no longer optional — it’s a board-level concern. In 2026, regulatory frameworks like the EU Cyber Resilience Act require software producers to maintain Software Bills of Materials. Therefore, this guide covers the practical tools and techniques to secure your build pipeline from source code to deployed artifact.
Dependency Scanning: Finding Vulnerabilities Before They Ship
Your application’s dependencies are its largest attack surface. A typical Node.js project pulls in 500-1500 transitive dependencies, and any one of them could contain a vulnerability or malicious code. Moreover, dependency confusion attacks — where an attacker publishes a package matching your internal package name on a public registry — have compromised major companies including Microsoft and Apple.
Integrate dependency scanning into every pull request, not just weekly audits. Tools like Snyk, Dependabot, and Trivy scan your lockfile against vulnerability databases and flag known CVEs with severity scores. Additionally, use lockfile pinning to prevent automatic dependency upgrades that could introduce compromised packages.
# GitHub Actions: dependency scanning on every PR
name: Security Scan
on: [pull_request]
jobs:
dependency-scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
- name: Fail on critical vulnerabilities
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL'
exit-code: '1'For private registries, configure scoped packages to prevent dependency confusion. Set your .npmrc to route @yourcompany/* packages to your private registry while everything else goes to the public npm registry. Consequently, an attacker cannot hijack your internal package names on the public registry.
Software Bill of Materials (SBOM): Know What You Ship
An SBOM is a complete inventory of every component in your software — libraries, frameworks, tools, and their versions. When a new vulnerability like Log4Shell drops, an SBOM lets you answer “are we affected?” in minutes instead of days. Furthermore, customers and regulators increasingly demand SBOMs as proof of supply chain diligence.
Generate SBOMs in standard formats (SPDX or CycloneDX) as part of your build pipeline. Attach them to your container images and release artifacts. For example, the CycloneDX tool generates SBOMs from lockfiles in seconds and outputs machine-readable JSON or XML.
# Generate SBOM from package lockfile
npx @cyclonedx/cyclonedx-npm --output-file sbom.json --output-format json
# Generate SBOM from container image
syft scan myapp:latest -o cyclonedx-json > container-sbom.json
# Verify SBOM against known vulnerabilities
grype sbom:./sbom.json --fail-on critical
# Attach SBOM to container image using cosign
cosign attach sbom --sbom sbom.json myregistry/myapp:v1.2.3Store SBOMs alongside your release artifacts in a versioned repository. When a new CVE is published, you can search all your SBOMs programmatically to identify every affected deployment. As a result, your incident response time drops from days to minutes.
Artifact Signing and Verification with Sigstore
Signing your build artifacts cryptographically proves they haven’t been tampered with between your CI pipeline and production. Sigstore’s cosign tool makes this practical by eliminating the key management burden — it uses keyless signing tied to your CI provider’s OIDC identity.
In a GitHub Actions workflow, cosign signs container images using the workflow’s OIDC token. Anyone can verify the signature and confirm the image was built by your specific repository and workflow. However, you must also verify signatures during deployment — signing without verification is like having a lock you never use.
# Sign and verify container images in CI
jobs:
build-and-sign:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for keyless signing
packages: write
steps:
- uses: sigstore/cosign-installer@v3
- name: Build and push image
run: |
docker build -t ghcr.io/myorg/myapp:$GITHUB_SHA .
docker push ghcr.io/myorg/myapp:$GITHUB_SHA
- name: Sign image (keyless)
run: cosign sign ghcr.io/myorg/myapp:$GITHUB_SHA
# In deployment pipeline: verify before deploying
- name: Verify signature
run: |
cosign verify ghcr.io/myorg/myapp:$GITHUB_SHA \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp 'github.com/myorg/myapp'Hardening GitHub Actions Workflows
GitHub Actions workflows are a prime target because they have access to secrets, deploy credentials, and the ability to publish packages. Pin all action versions to full commit SHAs — not tags, which can be moved. Specifically, replace uses: actions/checkout@v4 with uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11.
Limit permissions using the principle of least privilege. Set the workflow-level permissions to contents: read and only elevate specific job permissions when needed. Additionally, use environment protection rules to require manual approval for production deployments.
Provenance and SLSA Framework
SLSA (Supply-chain Levels for Software Artifacts) defines a maturity model for supply chain security. At SLSA Level 3, your build process is fully defined, auditable, and resistant to tampering. GitHub now generates SLSA provenance attestations automatically for Actions workflows, proving exactly how an artifact was built.
Enable provenance generation in your workflow and verify it during deployment. This creates an auditable chain from source commit to deployed artifact. For example, Kubernetes admission controllers can reject any image without valid provenance, preventing unauthorized deployments.
Related Reading:
- Container Security: Hardening Docker Images
- API Security with OAuth and Zero Trust
- Docker Compose to Kubernetes Migration
Resources:
In conclusion, supply chain security requires defense in depth — scanning dependencies, generating SBOMs, signing artifacts, and hardening your CI/CD environment. No single tool solves the problem. Start with dependency scanning and lockfile pinning, add SBOM generation and artifact signing, then work toward SLSA Level 3 provenance. The investment pays off when the next Log4Shell hits and you can answer “are we affected?” in five minutes.