Your application is a chain of dependencies, build tools, and third-party services. Any link can be compromised. Here's how to protect yours.
Modern software supply chains are attack surfaces:
Your Code
+ npm/pip/cargo packages (1000s of them)
+ Build tools (webpack, babel, etc.)
+ CI/CD systems (GitHub Actions, etc.)
+ Container base images
+ Cloud services
+ Third-party APIs
= A chain as secure as its weakest link
# Commit package-lock.json / yarn.lock / Cargo.lock
# Always use exact install in CI
npm ci # Uses lockfile exactly
pip install -r requirements.txt # Pin all versions
# Never:
npm install # Can pull newer version than expected
pip install requests # No version pin# Verify npm package integrity
npm audit
# For critical packages, verify signatures
npm view react dist-tags// Instead of:
"express": "^4.18.0" // Allows auto-minor/patch updates
// Use:
"express": "4.18.2" // Exact version — you control updatesGenerate a manifest of every component in your software:
# Generate SBOM
npx @cyclonedx/cyclonedx-npm --output-format json --output-file sbom.json
# Submit to dependency track for continuous monitoringThis lets you instantly identify affected software when a new CVE is published.
# GitHub Actions security hardening
on: push
permissions:
contents: read # Minimum permissions needed
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false # Don't expose git credentials
# Pin action versions by SHA (not tags — tags can move!)
- uses: actions/setup-node@11f8f9e8dcc4b56cd8b819930068e13b5ada12ab
with:
node-version: '20'
- run: npm ci
- run: npm audit --audit-level=critical# Pin base image digest (not just tag)
FROM node:20.11.0-alpine@sha256:abc123... # SHA doesn't change
# Run as non-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Scan before deploying
# trivy image myapp:latestnpm ci in CInpm audit failing on criticalThis takes half a day to implement. Do it.