← All articles
CI/CD Dependency Management and Security Scanning 2026-02-09 · 4 min read · dependencies · security · snyk

Dependency Management and Security Scanning

CI/CD 2026-02-09 · 4 min read dependencies security snyk trivy supply-chain

Dependency Management and Security Scanning

The average JavaScript project has 200+ transitive dependencies. The average Python project has 50+. Every one of them is attack surface. Supply chain attacks — compromising a widely-used package to inject malicious code — went from theoretical to routine. Dependency management is now a security concern, not just a convenience feature.

Lockfile Hygiene

Lockfiles pin your dependencies to exact versions. Without them, npm install on your machine and npm install in CI might install different versions.

What lockfiles do

# npm: package-lock.json
npm install              # Reads package-lock.json, installs exact versions
npm install --no-save    # Installs from lockfile without modifying it

# Bun: bun.lock
bun install              # Reads bun.lock

# pnpm: pnpm-lock.yaml
pnpm install --frozen-lockfile  # Fails if lockfile is out of date (use in CI)

# Python (pip): requirements.txt with hashes
pip install -r requirements.txt --require-hashes

# Go: go.sum
go mod verify            # Verifies checksums match go.sum

Rules:

  1. Always commit your lockfile
  2. In CI, use --frozen-lockfile (pnpm), npm ci (npm), or equivalent — fail the build if the lockfile is out of date
  3. Review lockfile changes in PRs — a lockfile diff that changes 500 packages when you added one dependency deserves scrutiny

Bun's lockfile

Bun uses a binary lockfile (bun.lock) which is faster to read/write but harder to review in diffs. For teams that need readable lockfile diffs:

# Generate human-readable text lockfile
bun install --save-text-lockfile

Vulnerability Scanning

npm audit / bun audit

Built-in vulnerability checking:

# Check for known vulnerabilities
npm audit

# Fix automatically where possible
npm audit fix

# Only show high/critical severity
npm audit --audit-level=high

npm audit checks the GitHub Advisory Database. It's a good starting point but has false positives and sometimes flags vulnerabilities in dev dependencies that aren't exploitable in production.

Trivy

Trivy is an open-source vulnerability scanner that handles dependencies, container images, IaC files, and more.

brew install trivy

# Scan a project directory (detects package.json, go.mod, requirements.txt, etc.)
trivy fs .

# Scan only for high/critical vulnerabilities
trivy fs --severity HIGH,CRITICAL .

# Scan a Docker image
trivy image my-app:latest

# Scan with SBOM output (Software Bill of Materials)
trivy fs --format spdx-json -o sbom.json .

# In CI: fail the build if critical vulnerabilities found
trivy fs --exit-code 1 --severity CRITICAL .

Trivy supports: npm, yarn, pnpm, pip, poetry, Go modules, Cargo (Rust), Maven, Gradle, NuGet, and more. It's the best free option for multi-language projects.

Snyk

Snyk is a commercial vulnerability scanning platform with a generous free tier.

npm install -g snyk

# Authenticate
snyk auth

# Test for vulnerabilities
snyk test

# Monitor continuously (reports new vulnerabilities as they're disclosed)
snyk monitor

# Fix vulnerabilities (opens PRs with updates)
snyk fix

Snyk's key advantage over npm audit is fix PRs: it can automatically open pull requests that update vulnerable dependencies to safe versions, including testing if the update breaks anything.

Pricing: Free for open source. 200 tests/month on private repos. Paid plans from $25/developer/month.

Socket

Socket takes a different approach: instead of checking a vulnerability database, it analyzes package behavior. It detects:

npm install -g socket
socket npm info lodash

Socket catches supply chain attacks that vulnerability databases miss because the attack is new (zero-day). It's complementary to Snyk/Trivy, not a replacement.

Automated Dependency Updates

Renovate

Renovate is an open-source tool that automatically opens PRs to update dependencies. It's more configurable than Dependabot.

// renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:recommended"
  ],
  "packageRules": [
    {
      "matchUpdateTypes": ["patch"],
      "automerge": true
    },
    {
      "matchUpdateTypes": ["major"],
      "labels": ["breaking-change"],
      "reviewers": ["team:platform"]
    },
    {
      "matchPackageNames": ["typescript", "eslint"],
      "groupName": "tooling"
    }
  ],
  "schedule": ["before 7am on Monday"]
}

Key features:

Dependabot

GitHub's built-in dependency updater. Simpler than Renovate but less configurable.

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10
    reviewers:
      - "your-team"

Renovate vs Dependabot: Renovate is more configurable (grouping, scheduling, auto-merge rules, monorepo support). Dependabot is simpler to set up and built into GitHub. For small projects, Dependabot is fine. For monorepos or teams with specific update policies, Renovate is worth the setup.

License Compliance

Some open-source licenses have requirements that affect commercial software. GPL requires derivative works to also be open-source. AGPL extends this to network use (SaaS). Most permissive licenses (MIT, Apache 2.0, BSD) have no such requirements.

license-checker

npx license-checker --summary
npx license-checker --failOn "GPL-2.0;GPL-3.0;AGPL-3.0"
npx license-checker --production  # Only check production dependencies

Trivy License Scanning

trivy fs --scanners license --severity HIGH .

Add license checks to CI if your company has compliance requirements. Most startups can skip this initially, but enterprise customers often require it.

CI Pipeline Example

A practical dependency security pipeline in GitHub Actions:

# .github/workflows/security.yml
name: Dependency Security
on:
  pull_request:
  schedule:
    - cron: '0 8 * * 1'  # Weekly Monday 8am

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Trivy vulnerability scan
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          severity: 'HIGH,CRITICAL'
          exit-code: '1'

      - name: License check
        run: npx license-checker --failOn "GPL-3.0;AGPL-3.0" --production

Recommendations

  1. Start with what's free: npm audit + Trivy covers most needs
  2. Automate updates: Renovate (or Dependabot) keeps dependencies from drifting months behind
  3. Scan in CI: Block merges when critical vulnerabilities are found
  4. Auto-merge patches: If CI passes and it's a patch update, merge it automatically
  5. Review major updates manually: Breaking changes need human review
  6. Don't ignore dev dependencies: A compromised build tool can inject code into your production bundle