/auditing-supply-chain
Audit software supply chain risk — dependency and transitive package review, typosquatting and dependency confusion, lockfile and SBOM analysis, CI/CD pipeline and GitHub Actions security, build provenance, and secrets exposure. Use when assessing third-party package risk,
$ npx -y skills add trilwu/secskills --skill auditing-supply-chain --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/auditing-supply-chain
Context preview
The summary Claude sees to decide when to auto-load this skill.
Audit software supply chain risk — dependency and transitive package review, typosquatting and dependency confusion, lockfile and SBOM analysis, CI/CD pipeline and GitHub Actions security, build provenance, and secrets exposure. Use when assessing third-party package risk,
SKILL.md
auditing-supply-chain.SKILL.mdname: auditing-supply-chain
description: Audit software supply chain risk — dependency and transitive package review, typosquatting and dependency confusion, lockfile and SBOM analysis, CI/CD pipeline and GitHub Actions security, build provenance, and secrets exposure. Use when assessing third-party package risk, reviewing a build pipeline, investigating a malicious package, or hardening release infrastructure.
verified: 2026-07-27
Auditing Supply Chain
Your build pipeline runs more untrusted code than your application does. A single unpinned action, a postinstall script, or a workflow with a writable token is a path from a stranger's commit to your production artifacts and your signing keys.
When to Use
- Assessing risk from third-party dependencies in an application
- Reviewing CI/CD pipelines, GitHub Actions, and release automation
- Investigating a suspicious or malicious package
- Producing or reviewing an SBOM
- Hardening build provenance and artifact signing
- Responding to a disclosed upstream compromise
When NOT to Use
- **Vulnerabilities in first-party code** — use `auditing-code-for-vulnerabilities`
- **Model and dataset provenance** — use `securing-ai-systems`
- **Cloud infrastructure posture generally** — use `exploiting-cloud-platforms`
for offensive assessment
- **An in-progress compromise** — use `responding-to-incidents`
- **Prioritizing which of many dependency CVEs to fix first** — use
`managing-vulnerabilities`; reachability analysis here feeds its ranking
Two Different Risks
Keep them separate; they need different responses.
| | **Known-vulnerable dependency** | **Malicious dependency** | | --- | --- | --- | | Detection | CVE databases, `npm audit`, `osv-scanner` | Behavioural review, install scripts, publisher anomalies | | Signal | Loud and well-tooled | Quiet; scanners usually miss it | | Response | Patch, or justify the risk | Incident — assume credentials on the build host are burned | | Time pressure | Days to weeks | Hours |
Most programs handle the first and are blind to the second. Give the second explicit attention.
Dependency Review
# Known vulnerabilities, ecosystem-agnostic
osv-scanner --lockfile=package-lock.json --lockfile=go.sum --lockfile=Cargo.lock
trivy fs --scanners vuln,secret,misconfig .
grype dir:.
# Ecosystem-native
npm audit --omit=dev && npm ls --all --depth=99 | wc -l # count transitives
pip-audit -r requirements.txt
cargo audit
govulncheck ./... # reachability-aware: only reports vulns you actually call
mvn dependency-check:check
`govulncheck`-style reachability analysis matters: a vulnerability in a code path you never execute is a patching task, not a risk. Prioritize by reachability plus exposure, not by CVSS alone.
**Transitive depth is the real surface.** Direct dependencies are chosen and reviewed; transitive ones are inherited. Count them, and know which maintainers you are implicitly trusting.
Detecting Malicious Packages
Triage signals, roughly in order of how strongly they indicate malice:
| Signal | How to check | | --- | --- | | Install-time script execution | `postinstall`/`preinstall` in package.json; `setup.py` with network or exec calls; `build.rs` | | Obfuscated or minified source in a non-minified package | Read the published tarball, not the repo — they differ | | Network calls at import/require time | Static grep for HTTP/DNS in module top-level | | Environment and credential access | Reads of `~/.aws`, `.npmrc`, `.git-credentials`, `process.env` dumps | | New maintainer or a version published from a new account | Registry metadata, publish history | | Name close to a popular package | Levenshtein distance against top-N package list | | Published artifact ≠ repository source | Compare the tarball to the tagged commit | | Version jump with no corresponding commits | Registry vs VCS history |
# Review what actually ships, not what the repo shows
npm pack <pkg> && tar -xzf <pkg>.tgz && rg -n 'child_process|eval\(|Buffer\.from\(.*base64|https?://' package/
pip download --no-deps --no-binary :all: <pkg> && tar -xzf <pkg>.tar.gz
rg -n 'os\.system|subprocess|urllib|requests|__import__|exec\(' <pkg>/setup.py
# Block install scripts by default in CI
npm ci --ignore-scripts
pip install --require-hashes -r requirements.txt**Dependency confusion**: if an internal package name is not also registered (or reserved) on the public registry, and the resolver can reach the public registry, an attacker can publish a higher version and win resolution.
# Enumerate internal-looking names and check public availability
rg -o '"@?[a-z0-9-]+/[a-z0-9-]+"' package.json | sort -u
# Fix: scoped registries with strict scope→registry mapping, and
# `.npmrc` / `pip.conf` that never falls back to the public index for
# internal scopes
Lockfiles and Pinning
- Lockfiles must be committed, reviewed in PRs, and CI must install **from**
the lockfile (`npm ci`, `pip install --require-hashes`, `cargo --locked`, `go mod verify`) rather than resolving fresh.
- A lockfile diff in a PR that touches packages unrelated to the change is a
review flag, not noise.
- Pin by integrity hash where the ecosystem supports it. Version pinning alone
does not protect against a re-published version in registries that permit it.
CI/CD Pipeline Security
This is where the highest-impact findings usually are.
GitHub Actions
# Unpinned third-party actions — anyone who controls the tag controls your CI
rg -n 'uses:\s+(?!actions/)[^@]+@(?!v?[0-9a-f]{40})' .github/workflows/
# The dangerous trigger: pull_request_target runs with repo secrets and
# write-capable tokens, in the base repo context
rg -n 'pull_request_target|workflow_run' -A15 .github/workflows/
# Script injection: untrusted event data interpolated directly into a shell
rg -n '\$\{\{\s*github\.event\.(issue|pull_request|comment|head_commit)' .github/workflows/Three findings to check for on every
Read more
name: auditing-supply-chain description: Audit software supply chain risk — dependency and transitive package review, typosquatting and dependency confusion, lockfile and SBOM analysis, CI/CD pipeline and GitHub Actions security, build provenance, and secrets exposure. Use when assessing third-party package risk, reviewing a build pipeline, investigating a malicious package, or hardening release infrastructure. verified: 2026-07-27
Auditing Supply Chain
Your build pipeline runs more untrusted code than your application does. A single unpinned action, a postinstall script, or a workflow with a writable token is a path from a stranger's commit to your production artifacts and your signing keys.
When to Use
- Assessing risk from third-party dependencies in an application
- Reviewing CI/CD pipelines, GitHub Actions, and release automation
- Investigating a suspicious or malicious package
- Producing or reviewing an SBOM
- Hardening build provenance and artifact signing
- Responding to a disclosed upstream compromise
When NOT to Use
- **Vulnerabilities in first-party code** — use `auditing-code-for-vulnerabilities`
- **Model and dataset provenance** — use `securing-ai-systems`
- **Cloud infrastructure posture generally** — use `exploiting-cloud-platforms`
for offensive assessment
- **An in-progress compromise** — use `responding-to-incidents`
- **Prioritizing which of many dependency CVEs to fix first** — use
`managing-vulnerabilities`; reachability analysis here feeds its ranking
Two Different Risks
Keep them separate; they need different responses.
| | **Known-vulnerable dependency** | **Malicious dependency** | | --- | --- | --- | | Detection | CVE databases, `npm audit`, `osv-scanner` | Behavioural review, install scripts, publisher anomalies | | Signal | Loud and well-tooled | Quiet; scanners usually miss it | | Response | Patch, or justify the risk | Incident — assume credentials on the build host are burned | | Time pressure | Days to weeks | Hours |
Most programs handle the first and are blind to the second. Give the second explicit attention.
Dependency Review
# Known vulnerabilities, ecosystem-agnostic osv-scanner --lockfile=package-lock.json --lockfile=go.sum --lockfile=Cargo.lock trivy fs --scanners vuln,secret,misconfig . grype dir:. # Ecosystem-native npm audit --omit=dev && npm ls --all --depth=99 | wc -l # count transitives pip-audit -r requirements.txt cargo audit govulncheck ./... # reachability-aware: only reports vulns you actually call mvn dependency-check:check
`govulncheck`-style reachability analysis matters: a vulnerability in a code path you never execute is a patching task, not a risk. Prioritize by reachability plus exposure, not by CVSS alone.
**Transitive depth is the real surface.** Direct dependencies are chosen and reviewed; transitive ones are inherited. Count them, and know which maintainers you are implicitly trusting.
Detecting Malicious Packages
Triage signals, roughly in order of how strongly they indicate malice:
| Signal | How to check | | --- | --- | | Install-time script execution | `postinstall`/`preinstall` in package.json; `setup.py` with network or exec calls; `build.rs` | | Obfuscated or minified source in a non-minified package | Read the published tarball, not the repo — they differ | | Network calls at import/require time | Static grep for HTTP/DNS in module top-level | | Environment and credential access | Reads of `~/.aws`, `.npmrc`, `.git-credentials`, `process.env` dumps | | New maintainer or a version published from a new account | Registry metadata, publish history | | Name close to a popular package | Levenshtein distance against top-N package list | | Published artifact ≠ repository source | Compare the tarball to the tagged commit | | Version jump with no corresponding commits | Registry vs VCS history |
# Review what actually ships, not what the repo shows
npm pack <pkg> && tar -xzf <pkg>.tgz && rg -n 'child_process|eval\(|Buffer\.from\(.*base64|https?://' package/
pip download --no-deps --no-binary :all: <pkg> && tar -xzf <pkg>.tar.gz
rg -n 'os\.system|subprocess|urllib|requests|__import__|exec\(' <pkg>/setup.py
# Block install scripts by default in CI
npm ci --ignore-scripts
pip install --require-hashes -r requirements.txt**Dependency confusion**: if an internal package name is not also registered (or reserved) on the public registry, and the resolver can reach the public registry, an attacker can publish a higher version and win resolution.
# Enumerate internal-looking names and check public availability rg -o '"@?[a-z0-9-]+/[a-z0-9-]+"' package.json | sort -u # Fix: scoped registries with strict scope→registry mapping, and # `.npmrc` / `pip.conf` that never falls back to the public index for # internal scopes
Lockfiles and Pinning
- Lockfiles must be committed, reviewed in PRs, and CI must install **from**
the lockfile (`npm ci`, `pip install --require-hashes`, `cargo --locked`, `go mod verify`) rather than resolving fresh.
- A lockfile diff in a PR that touches packages unrelated to the change is a
review flag, not noise.
- Pin by integrity hash where the ecosystem supports it. Version pinning alone
does not protect against a re-published version in registries that permit it.
CI/CD Pipeline Security
This is where the highest-impact findings usually are.
GitHub Actions
# Unpinned third-party actions — anyone who controls the tag controls your CI
rg -n 'uses:\s+(?!actions/)[^@]+@(?!v?[0-9a-f]{40})' .github/workflows/
# The dangerous trigger: pull_request_target runs with repo secrets and
# write-capable tokens, in the base repo context
rg -n 'pull_request_target|workflow_run' -A15 .github/workflows/
# Script injection: untrusted event data interpolated directly into a shell
rg -n '\$\{\{\s*github\.event\.(issue|pull_request|comment|head_commit)' .github/workflows/Three findings to check for on every
**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

