Claude Code for Supply Chain Security: SBOM, Sigstore, and Dependency Hardening — Claude Skills 360 Blog
Blog / Security / Claude Code for Supply Chain Security: SBOM, Sigstore, and Dependency Hardening
Security

Claude Code for Supply Chain Security: SBOM, Sigstore, and Dependency Hardening

Published: September 23, 2026
Read time: 8 min read
By: Claude Skills 360

Software supply chain attacks — compromised npm packages, tampered Docker images, malicious dependencies — have become a primary attack vector. The SolarWinds and XZ Utils incidents demonstrated that production software with no obvious code bugs can still deliver attacker code through the supply chain. Claude Code implements the technical controls that make your build pipeline trustworthy: Software Bill of Materials (SBOM), artifact signing, dependency pinning, and automated update workflows.

Software Bill of Materials (SBOM)

Generate an SBOM for our project and add it to every release.
We need visibility into our full dependency tree including transitive deps.
# .github/workflows/release.yml — SBOM generation in CI

- name: Generate SBOM (Node.js)
  uses: anchore/sbom-action@v0
  with:
    format: spdx-json    # SPDX 2.3 — industry standard
    output-file: sbom.spdx.json
    # Include dev dependencies? No for production builds
    config: ./.sbom-config.yaml

# .sbom-config.yaml
catalogers:
  - node-modules-cataloger     # Reads node_modules
  - npm-cataloger               # Reads package-lock.json
exclude:
  - '**/node_modules/**'        # Already covered by node-modules-cataloger
  - '**/*.test.ts'              # Exclude test files

For Docker images (full dependency tree):

# Generate SBOM from Docker image — scans OS packages + language packages
syft ubuntu-22.04 -o spdx-json > ubuntu-sbom.json

# More useful: scan your production image
syft myapp:latest -o spdx-json > myapp-sbom.spdx.json

# Scan for known vulnerabilities in the SBOM
grype sbom:myapp-sbom.spdx.json --fail-on high

Attach SBOM to releases:

- name: Attach SBOM to GitHub release
  uses: softprops/action-gh-release@v2
  with:
    files: |
      sbom.spdx.json
      dist/app.tar.gz

Signing Artifacts with Sigstore/cosign

After generating the SBOM and build artifacts,
sign them so users can verify they came from our CI pipeline.
# .github/workflows/release.yml — keyless signing with Sigstore

- name: Install cosign
  uses: sigstore/cosign-installer@v3

- name: Sign container image (keyless — uses OIDC identity)
  run: |
    cosign sign --yes \
      --rekor-url=https://rekor.sigstore.dev \
      ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}
  env:
    COSIGN_EXPERIMENTAL: 1  # Keyless mode — no private key management

- name: Sign SBOM and attach to image
  run: |
    cosign attest --yes \
      --type spdxjson \
      --predicate sbom.spdx.json \
      ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}

- name: Sign release binary
  run: |
    cosign sign-blob --yes \
      --output-signature dist/app.tar.gz.sig \
      --output-certificate dist/app.tar.gz.cert \
      dist/app.tar.gz

Verify in your deployment pipeline:

# Verify the image was signed by our CI pipeline (checks OIDC identity)
cosign verify \
  --certificate-identity-regexp="https://github.com/mycompany/myapp/.github/workflows/release.yml@refs/heads/main" \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  myregistry.io/myapp:1.2.3

# Verify and extract the SBOM
cosign verify-attestation \
  --type spdxjson \
  --certificate-identity-regexp="https://github.com/mycompany/myapp/.github/workflows/release.yml" \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  myregistry.io/myapp:1.2.3 | jq .payload | base64 -d | jq .predicate

Dependency Pinning and Automated Updates

Our package.json uses ^ ranges — a compromised patch release could get in.
Pin everything but automate updates so we don't fall behind.

Generate pinned lockfile and enforce it in CI:

# Pin exact versions in package.json
npm shrinkwrap  # Creates npm-shrinkwrap.json — exact versions

# Or use --exact flag when adding packages
npm install --save-exact express  # "express": "4.18.2" not "^4.18.2"

Enforce no lockfile drift in CI:

# .github/workflows/ci.yml
- name: Verify lockfile is current
  run: |
    npm ci  # Fails if package-lock.json doesn't match package.json
    # npm ci is more deterministic than npm install — always use in CI

Renovate for automated dependency updates:

// renovate.json — automated, security-gated updates
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  
  // Auto-merge patch updates that pass CI (low risk)
  "packageRules": [
    {
      "matchUpdateTypes": ["patch"],
      "matchCurrentVersion": "!/^0/",  // Exclude pre-1.0 (unstable)
      "automerge": true,
      "automergeType": "pr"
    },
    {
      // Security updates: merge immediately
      "matchCategories": ["security"],
      "automerge": true,
      "schedule": ["at any time"]
    },
    {
      // Major updates: group together, require human review
      "matchUpdateTypes": ["major"],
      "groupName": "major dependencies",
      "schedule": ["on the first day of the month"]
    }
  ],
  
  // Vulnerability alerts: always create PRs regardless of schedule
  "vulnerabilityAlerts": {
    "enabled": true,
    "schedule": ["at any time"]
  },
  
  "lockFileMaintenance": {
    "enabled": true,
    "schedule": ["on Sunday"]
  }
}

Container Image Hardening

Our Docker images run as root and include many tools attackers could use.
Harden them.
# Multi-stage: builder has full toolchain, runtime has nothing extra
FROM node:20-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev  # Only production deps in final image

COPY src/ ./src/
COPY tsconfig.json ./
RUN npm run build

# Final image: distroless — no shell, no package manager, no attack surface
FROM gcr.io/distroless/nodejs20-debian12 AS runtime

# Security: run as non-root
USER nonroot:nonroot

WORKDIR /app

COPY --from=builder --chown=nonroot:nonroot /app/node_modules ./node_modules
COPY --from=builder --chown=nonroot:nonroot /app/dist ./dist

# Read-only filesystem — attacker can't modify files
VOLUME ["/tmp"]  # Allow writes only to /tmp

EXPOSE 3000

CMD ["/app/dist/server.js"]

Scan image in CI before pushing:

- name: Build image
  run: docker build -t myapp:${{ github.sha }} .

- name: Scan for vulnerabilities
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: myapp:${{ github.sha }}
    format: sarif
    output: trivy-results.sarif
    # Fail on high/critical
    exit-code: '1'
    severity: 'HIGH,CRITICAL'
    ignore-unfixed: true  # Only flag if a fix is available

- name: Upload Trivy results to GitHub Security
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: trivy-results.sarif

Dependency Integrity Checks

We want to verify npm packages haven't been tampered with
before installing them in production.
# package.json: enforce integrity hashes
# npm already writes these to package-lock.json:
# "integrity": "sha512-abc123..."

# Audit against known vulnerabilities
npm audit --audit-level=high

# Check for suspicious packages (typosquatting, metadata anomalies)
npx socket --strict  # Socket.dev: detects supply chain risks

# In CI: never install from registry — use lockfile only
npm ci  # Reads package-lock.json, verifies integrity hashes

For applying broader security controls including container security policies, see the security testing guide and the Kubernetes operators guide for policy enforcement. For CI/CD pipeline security that validates artifact signing as part of deployment, the CI/CD advanced guide covers pipeline hardening. The Claude Skills 360 bundle includes DevSecOps skill sets for SBOM generation, artifact signing, and dependency hardening. Start with the free tier to try supply chain security configurations.

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free