Dependency Audit
Comprehensive dependency risk assessment: license compatibility analysis, maintenance
health scoring, CVE detection, bloat identification, and transitive dependency risk
mapping. Produces an actionable report with prioritized remediation steps organized by
urgency (security → license → maintenance → bloat).
Reference Files
| File |
Contents |
Load When |
references/license-compatibility.md |
License compatibility matrix, copyleft detection, commercial-safe licenses |
Always |
references/health-metrics.md |
Maintenance health indicators, scoring criteria, abandonment detection |
Always |
references/bloat-detection.md |
Identifying unused deps, duplicate functionality, heavy transitive trees |
Bloat analysis requested |
references/cve-sources.md |
CVE databases, advisory sources, vulnerability severity interpretation |
Security audit requested |
Prerequisites
- Access to the project's dependency files (
pyproject.toml, requirements.txt,
package.json, Cargo.toml, go.mod)
- Lock file (for exact versions and transitive dependencies)
- Project license (to determine compatibility requirements)
Workflow
Phase 1: Parse Dependency Tree
- Direct dependencies — Packages explicitly declared in the project.
- Transitive dependencies — Dependencies of dependencies. Often 10-50x the
direct count.
- Version constraints — Pinned (
==1.2.3), ranged (>=1.0,<2.0), or floating (*).
- Development vs production — Separate dev/test dependencies from production.
Tools:
- Python:
uv pip list, pip-audit, pipdeptree
- Node.js:
npm list --all, npm audit
- Rust:
cargo tree, cargo audit
Phase 2: Audit Licenses
For each dependency:
Identify the license — Check package metadata, LICENSE file, pyproject.toml.
Classify compatibility — Against the project's own license:
| License |
Commercial OK |
Copyleft |
Risk Level |
| MIT, BSD, ISC, Apache 2.0 |
Yes |
No |
Low |
| LGPL |
With care |
Weak |
Medium |
| GPL-2.0, GPL-3.0 |
No (unless GPL project) |
Strong |
High |
| AGPL |
No (unless AGPL project) |
Strong + network |
Critical |
| Unknown |
Cannot determine |
Unknown |
Critical |
Flag issues — Copyleft licenses in proprietary projects, unknown licenses,
license changes between versions.
Phase 3: Assess Maintenance Health
For each dependency, evaluate maintenance signals:
| Indicator |
Healthy |
Warning |
Abandoned |
| Last release |
< 6 months |
6-18 months |
> 18 months |
| Commits (90 days) |
10+ |
1-9 |
0 |
| Open issues response |
< 2 weeks |
2-8 weeks |
> 8 weeks or no response |
| Bus factor |
3+ maintainers |
2 |
1 |
| CI status |
Passing |
Flaky |
Failing or absent |
Phase 4: Check Security
Known CVEs — Check against advisory databases:
- Python:
pip-audit, PyPI advisory database
- Node.js:
npm audit, GitHub Advisory Database
- General: NVD (National Vulnerability Database)
Severity classification — CVSS score interpretation:
| CVSS Score |
Severity |
Action |
| 9.0-10.0 |
Critical |
Upgrade immediately |
| 7.0-8.9 |
High |
Upgrade within days |
| 4.0-6.9 |
Medium |
Upgrade within weeks |
| 0.1-3.9 |
Low |
Upgrade at convenience |
Fix availability — Is there a patched version? If not, what's the workaround?
Phase 5: Detect Bloat
- Unused dependencies — Dependencies imported nowhere in the codebase.
- Duplicate functionality — Multiple packages doing the same thing (2 HTTP clients,
2 JSON parsers).
- Heavy transitive trees — Packages that pull in dozens of sub-dependencies for
a simple feature.
- Size analysis — Large packages used for small functionality.
Phase 6: Report
Produce a prioritized report with action items.
Output Format
## Dependency Audit: {Project Name}
### Summary
| Metric | Count |
|--------|-------|
| Direct dependencies | {N} |
| Transitive dependencies | {N} |
| License issues | {N} |
| Maintenance concerns | {N} |
| Security vulnerabilities | {N} |
| Bloat candidates | {N} |
### License Compliance
| Package | Version | License | Compatible | Issue |
|---------|---------|---------|------------|-------|
| {pkg} | {ver} | MIT | Yes | None |
| {pkg} | {ver} | GPL-3.0 | No | Copyleft in proprietary project |
| {pkg} | {ver} | Unknown | Unknown | License not identifiable |
### Maintenance Health
| Package | Last Release | Commits (90d) | Maintainers | Status |
|---------|-------------|---------------|-------------|--------|
| {pkg} | {date} | {N} | {N} | {Healthy/Warning/Abandoned} |
### Security Vulnerabilities
| Package | Version | CVE | Severity | Fix Available | Fixed In |
|---------|---------|-----|----------|---------------|----------|
| {pkg} | {ver} | {CVE-ID} | {severity} | {Yes/No} | {version} |
### Bloat Analysis
| Package | Install Size | Used By | Recommendation |
|---------|-------------|---------|----------------|
| {pkg} | {size} | {usage description} | {Remove/Replace/Keep} |
### Action Items
#### Immediate (Security)
1. Upgrade {pkg} to {version} — fixes {CVE-ID} ({severity})
#### Short-term (License)
1. Review {pkg} GPL usage — may require license change or removal
#### Medium-term (Maintenance)
1. Find alternative to {pkg} — abandoned since {date}
#### Long-term (Bloat)
1. Remove {pkg} — unused in codebase
2. Replace {pkg} with lighter alternative
### Transitive Risk
- {direct-dep} depends on {transitive-dep} which has {issue}
Calibration Rules
- Production dependencies first. Dev/test dependencies have lower risk since they
don't ship to users. Audit production dependencies with higher scrutiny.
- Transitive risk is real. A direct dependency with MIT license may pull in a GPL
transitive dependency. Always check the full tree.
- Abandoned is not broken. A mature, stable library that hasn't been updated in a
year may be perfectly fine. Evaluate based on whether the library is "done" vs "neglected."
- Security is non-negotiable. Critical and High CVEs must be addressed immediately.
Medium CVEs should be tracked. Low CVEs can wait for the next dependency update cycle.
Error Handling
| Problem |
Resolution |
| No lock file available |
Audit based on declared dependencies. Note that transitive analysis is incomplete without a lock file. |
| License metadata missing |
Check the package's repository for LICENSE file. Note packages where license cannot be determined. |
| Package registry unavailable |
Work from cached metadata and local lockfile data. |
| Too many dependencies to audit manually |
Prioritize: production deps first, then direct deps, then transitive deps with known issues. |
When NOT to Audit
Push back if:
- The project is a prototype that won't ship — defer audit until production decision
- The user wants dependency updates, not audit — different task (dependabot, renovate)
- The project has no dependencies (pure standard library) — nothing to audit
Rationalizations
| Rationalization |
Reality |
| "It's a trusted package" |
Trust is not a security model — trusted packages get compromised (event-stream, ua-parser-js, colors.js) |
| "Only a minor version bump" |
Minor versions can introduce vulnerabilities, change behavior, or add transitive dependencies — semver is a promise, not a guarantee |
| "We don't use the vulnerable function" |
Transitive dependencies might — and attack surface includes any code loaded into the process |
| "The CVE is low severity" |
Low severity in isolation can be critical in your context — a "low" SSRF in an internal service with cloud metadata access is critical |
| "We'll update when there's a known exploit" |
Known exploits mean you're already behind — patch within SLA, not after breach |
| "Too many dependencies to audit" |
That's the problem, not an excuse — high dependency count IS a risk finding |
Red Flags
- Auditing only direct dependencies while ignoring transitive dependency tree
- Dismissing CVEs without checking if the vulnerable code path is reachable
- No license compatibility check — GPL in a proprietary codebase is a legal finding
- Accepting "no known vulnerabilities" from a single scanner without cross-referencing
- Ignoring dependency age — unmaintained packages with no updates in 2+ years are a risk
- Skipping lockfile analysis (pinned vs. floating versions)
Verification
1---2name: dependency-audit3description: Audits direct and transitive dependencies for license compliance, maintenance health, CVEs, abandoned packages, and bloat. Triggers on: "audit dependencies", "license check", "dependency health", "abandoned packages", "unused dependencies", "license compliance", "supply chain", "dependency risk".4---56# Dependency Audit78Comprehensive dependency risk assessment: license compatibility analysis, maintenance9health scoring, CVE detection, bloat identification, and transitive dependency risk10mapping. Produces an actionable report with prioritized remediation steps organized by11urgency (security → license → maintenance → bloat).1213## Reference Files1415| File | Contents | Load When |16| ------------------------------------- | -------------------------------------------------------------------------- | ------------------------ |17| `references/license-compatibility.md` | License compatibility matrix, copyleft detection, commercial-safe licenses | Always |18| `references/health-metrics.md` | Maintenance health indicators, scoring criteria, abandonment detection | Always |19| `references/bloat-detection.md` | Identifying unused deps, duplicate functionality, heavy transitive trees | Bloat analysis requested |20| `references/cve-sources.md` | CVE databases, advisory sources, vulnerability severity interpretation | Security audit requested |2122## Prerequisites2324- Access to the project's dependency files (`pyproject.toml`, `requirements.txt`,25 `package.json`, `Cargo.toml`, `go.mod`)26- Lock file (for exact versions and transitive dependencies)27- Project license (to determine compatibility requirements)2829## Workflow3031### Phase 1: Parse Dependency Tree32331. **Direct dependencies** — Packages explicitly declared in the project.342. **Transitive dependencies** — Dependencies of dependencies. Often 10-50x the35 direct count.363. **Version constraints** — Pinned (`==1.2.3`), ranged (`>=1.0,<2.0`), or floating (`*`).374. **Development vs production** — Separate dev/test dependencies from production.3839Tools:4041- Python: `uv pip list`, `pip-audit`, `pipdeptree`42- Node.js: `npm list --all`, `npm audit`43- Rust: `cargo tree`, `cargo audit`4445### Phase 2: Audit Licenses4647For each dependency:48491. **Identify the license** — Check package metadata, LICENSE file, pyproject.toml.502. **Classify compatibility** — Against the project's own license:5152 | License | Commercial OK | Copyleft | Risk Level |53 | ------------------------- | ------------------------ | ---------------- | ---------- |54 | MIT, BSD, ISC, Apache 2.0 | Yes | No | Low |55 | LGPL | With care | Weak | Medium |56 | GPL-2.0, GPL-3.0 | No (unless GPL project) | Strong | High |57 | AGPL | No (unless AGPL project) | Strong + network | Critical |58 | Unknown | Cannot determine | Unknown | Critical |59603. **Flag issues** — Copyleft licenses in proprietary projects, unknown licenses,61 license changes between versions.6263### Phase 3: Assess Maintenance Health6465For each dependency, evaluate maintenance signals:6667| Indicator | Healthy | Warning | Abandoned |68| -------------------- | -------------- | ----------- | ------------------------ |69| Last release | < 6 months | 6-18 months | > 18 months |70| Commits (90 days) | 10+ | 1-9 | 0 |71| Open issues response | < 2 weeks | 2-8 weeks | > 8 weeks or no response |72| Bus factor | 3+ maintainers | 2 | 1 |73| CI status | Passing | Flaky | Failing or absent |7475### Phase 4: Check Security76771. **Known CVEs** — Check against advisory databases:78 - Python: `pip-audit`, PyPI advisory database79 - Node.js: `npm audit`, GitHub Advisory Database80 - General: NVD (National Vulnerability Database)81822. **Severity classification** — CVSS score interpretation:8384 | CVSS Score | Severity | Action |85 | ---------- | -------- | ---------------------- |86 | 9.0-10.0 | Critical | Upgrade immediately |87 | 7.0-8.9 | High | Upgrade within days |88 | 4.0-6.9 | Medium | Upgrade within weeks |89 | 0.1-3.9 | Low | Upgrade at convenience |90913. **Fix availability** — Is there a patched version? If not, what's the workaround?9293### Phase 5: Detect Bloat94951. **Unused dependencies** — Dependencies imported nowhere in the codebase.962. **Duplicate functionality** — Multiple packages doing the same thing (2 HTTP clients,97 2 JSON parsers).983. **Heavy transitive trees** — Packages that pull in dozens of sub-dependencies for99 a simple feature.1004. **Size analysis** — Large packages used for small functionality.101102### Phase 6: Report103104Produce a prioritized report with action items.105106## Output Format107108```text109## Dependency Audit: {Project Name}110111### Summary112| Metric | Count |113|--------|-------|114| Direct dependencies | {N} |115| Transitive dependencies | {N} |116| License issues | {N} |117| Maintenance concerns | {N} |118| Security vulnerabilities | {N} |119| Bloat candidates | {N} |120121### License Compliance122123| Package | Version | License | Compatible | Issue |124|---------|---------|---------|------------|-------|125| {pkg} | {ver} | MIT | Yes | None |126| {pkg} | {ver} | GPL-3.0 | No | Copyleft in proprietary project |127| {pkg} | {ver} | Unknown | Unknown | License not identifiable |128129### Maintenance Health130131| Package | Last Release | Commits (90d) | Maintainers | Status |132|---------|-------------|---------------|-------------|--------|133| {pkg} | {date} | {N} | {N} | {Healthy/Warning/Abandoned} |134135### Security Vulnerabilities136137| Package | Version | CVE | Severity | Fix Available | Fixed In |138|---------|---------|-----|----------|---------------|----------|139| {pkg} | {ver} | {CVE-ID} | {severity} | {Yes/No} | {version} |140141### Bloat Analysis142143| Package | Install Size | Used By | Recommendation |144|---------|-------------|---------|----------------|145| {pkg} | {size} | {usage description} | {Remove/Replace/Keep} |146147### Action Items148149#### Immediate (Security)1501. Upgrade {pkg} to {version} — fixes {CVE-ID} ({severity})151152#### Short-term (License)1531. Review {pkg} GPL usage — may require license change or removal154155#### Medium-term (Maintenance)1561. Find alternative to {pkg} — abandoned since {date}157158#### Long-term (Bloat)1591. Remove {pkg} — unused in codebase1602. Replace {pkg} with lighter alternative161162### Transitive Risk163- {direct-dep} depends on {transitive-dep} which has {issue}164```165166## Calibration Rules1671681. **Production dependencies first.** Dev/test dependencies have lower risk since they169 don't ship to users. Audit production dependencies with higher scrutiny.1702. **Transitive risk is real.** A direct dependency with MIT license may pull in a GPL171 transitive dependency. Always check the full tree.1723. **Abandoned is not broken.** A mature, stable library that hasn't been updated in a173 year may be perfectly fine. Evaluate based on whether the library is "done" vs "neglected."1744. **Security is non-negotiable.** Critical and High CVEs must be addressed immediately.175 Medium CVEs should be tracked. Low CVEs can wait for the next dependency update cycle.176177## Error Handling178179| Problem | Resolution |180| --------------------------------------- | ------------------------------------------------------------------------------------------------------ |181| No lock file available | Audit based on declared dependencies. Note that transitive analysis is incomplete without a lock file. |182| License metadata missing | Check the package's repository for LICENSE file. Note packages where license cannot be determined. |183| Package registry unavailable | Work from cached metadata and local lockfile data. |184| Too many dependencies to audit manually | Prioritize: production deps first, then direct deps, then transitive deps with known issues. |185186## When NOT to Audit187188Push back if:189190- The project is a prototype that won't ship — defer audit until production decision191- The user wants dependency updates, not audit — different task (dependabot, renovate)192- The project has no dependencies (pure standard library) — nothing to audit193194## Rationalizations195196| Rationalization | Reality |197|---|---|198| "It's a trusted package" | Trust is not a security model — trusted packages get compromised (event-stream, ua-parser-js, colors.js) |199| "Only a minor version bump" | Minor versions can introduce vulnerabilities, change behavior, or add transitive dependencies — semver is a promise, not a guarantee |200| "We don't use the vulnerable function" | Transitive dependencies might — and attack surface includes any code loaded into the process |201| "The CVE is low severity" | Low severity in isolation can be critical in your context — a "low" SSRF in an internal service with cloud metadata access is critical |202| "We'll update when there's a known exploit" | Known exploits mean you're already behind — patch within SLA, not after breach |203| "Too many dependencies to audit" | That's the problem, not an excuse — high dependency count IS a risk finding |204205## Red Flags206207- Auditing only direct dependencies while ignoring transitive dependency tree208- Dismissing CVEs without checking if the vulnerable code path is reachable209- No license compatibility check — GPL in a proprietary codebase is a legal finding210- Accepting "no known vulnerabilities" from a single scanner without cross-referencing211- Ignoring dependency age — unmaintained packages with no updates in 2+ years are a risk212- Skipping lockfile analysis (pinned vs. floating versions)213214## Verification215216- [ ] Both direct and transitive dependencies scanned217- [ ] Vulnerability scanner output captured: `npm audit` / `pip-audit` / `cargo audit`218- [ ] Each CVE finding includes: severity, affected version range, upgrade path, reachability assessment219- [ ] License compatibility verified against project license220- [ ] Dependency age and maintenance status checked for top-level deps221- [ ] Lockfile present and version pinning verified — no floating ranges in production