|
| 1 | +--- |
| 2 | +name: audit-dependencies |
| 3 | +description: Use when fixing dependency vulnerabilities, running pnpm audit, or when the audit-dependencies CI check fails |
| 4 | +user-invocable: true |
| 5 | +disable-model-invocation: true |
| 6 | +argument-hint: "critical|high|moderate|low" |
| 7 | +--- |
| 8 | + |
| 9 | +# Audit Dependencies |
| 10 | + |
| 11 | +## Overview |
| 12 | + |
| 13 | +Fix dependency vulnerabilities reported by `.github/workflows/audit-dependencies.sh`. Always prefer direct dependency bumps over pnpm overrides. Every override requires justification for why a direct bump isn't feasible. |
| 14 | + |
| 15 | +## Core Workflow |
| 16 | + |
| 17 | +```dot |
| 18 | +digraph audit { |
| 19 | + "Run audit script" [shape=box]; |
| 20 | + "Group by package" [shape=box]; |
| 21 | + "Trace dependency chain" [shape=box]; |
| 22 | + "Can bump direct dep?" [shape=diamond]; |
| 23 | + "Research breaking changes" [shape=box]; |
| 24 | + "Breaking changes acceptable?" [shape=diamond]; |
| 25 | + "Apply direct bump" [shape=box]; |
| 26 | + "Apply pnpm override" [shape=box]; |
| 27 | + "More packages?" [shape=diamond]; |
| 28 | + "Install and verify" [shape=box]; |
| 29 | + "Build and verify" [shape=box]; |
| 30 | + "Commit and create PR" [shape=box]; |
| 31 | +
|
| 32 | + "Run audit script" -> "Group by package"; |
| 33 | + "Group by package" -> "Trace dependency chain"; |
| 34 | + "Trace dependency chain" -> "Can bump direct dep?"; |
| 35 | + "Can bump direct dep?" -> "Research breaking changes" [label="yes"]; |
| 36 | + "Can bump direct dep?" -> "Apply pnpm override" [label="no - explain why"]; |
| 37 | + "Research breaking changes" -> "Breaking changes acceptable?"; |
| 38 | + "Breaking changes acceptable?" -> "Apply direct bump" [label="yes"]; |
| 39 | + "Breaking changes acceptable?" -> "Apply pnpm override" [label="no - explain why"]; |
| 40 | + "Apply direct bump" -> "More packages?"; |
| 41 | + "Apply pnpm override" -> "More packages?"; |
| 42 | + "More packages?" -> "Trace dependency chain" [label="yes"]; |
| 43 | + "More packages?" -> "Install and verify" [label="no"]; |
| 44 | + "Install and verify" -> "Build and verify"; |
| 45 | + "Build and verify" -> "Commit and create PR"; |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +## Step-by-Step |
| 50 | + |
| 51 | +### 1. Run the Audit Script |
| 52 | + |
| 53 | +```bash |
| 54 | +./.github/workflows/audit-dependencies.sh $ARGUMENTS |
| 55 | +``` |
| 56 | + |
| 57 | +`$ARGUMENTS` is the severity passed to the skill (defaults to `high` if omitted). The script runs `pnpm audit --prod --json` and filters for actionable vulnerabilities (those with a patched version available). `high` includes `critical`. |
| 58 | + |
| 59 | +Parse the output to build a deduplicated list of vulnerable packages with: |
| 60 | + |
| 61 | +- Package name and current version |
| 62 | +- Fixed version requirement |
| 63 | +- Full dependency chain (e.g., `packages/plugin-sentry > @sentry/nextjs > rollup`) |
| 64 | + |
| 65 | +### 2. For Each Vulnerable Package |
| 66 | + |
| 67 | +#### Trace the dependency chain |
| 68 | + |
| 69 | +Identify whether the vulnerable package is: |
| 70 | + |
| 71 | +- **Direct dependency**: Listed in a workspace package's `package.json` |
| 72 | +- **Transitive dependency**: Pulled in by another package |
| 73 | + |
| 74 | +#### Try direct bump first |
| 75 | + |
| 76 | +For transitive deps, walk up the chain to find the nearest package you control: |
| 77 | + |
| 78 | +1. Check if bumping the **parent package** resolves the vulnerability |
| 79 | + - `pnpm view <parent>@latest dependencies.<vulnerable-pkg>` |
| 80 | + - Check intermediate versions too (the fix may exist in a minor bump) |
| 81 | +2. If the parent bump resolves it, research breaking changes: |
| 82 | + - Check changelogs/release notes |
| 83 | + - Search GitHub issues for compatibility problems |
| 84 | + - Review the API surface used in this repo (read the source files) |
| 85 | + - Check if the version range crosses a major version boundary |
| 86 | +3. Present findings to user with risk assessment |
| 87 | + |
| 88 | +**Parallelize research**: When multiple packages need breaking change analysis, dispatch parallel agents (one per package) to research simultaneously. |
| 89 | + |
| 90 | +#### Fall back to override only when justified |
| 91 | + |
| 92 | +Add a scoped pnpm override in root `package.json` only when: |
| 93 | + |
| 94 | +- No version of the parent package fixes the vulnerability |
| 95 | +- The parent bump has high breaking change risk (major API changes, no test coverage, requires code changes across many files) |
| 96 | +- The user explicitly decides to defer the parent bump to a separate PR |
| 97 | + |
| 98 | +Override format: `"<parent>><vulnerable-pkg>": "<fixed-version>"` |
| 99 | + |
| 100 | +Before adding any override, verify the target version exists: |
| 101 | + |
| 102 | +```bash |
| 103 | +pnpm view <pkg>@<version> version |
| 104 | +``` |
| 105 | + |
| 106 | +### 3. Apply Fixes |
| 107 | + |
| 108 | +- Edit `package.json` files for direct bumps |
| 109 | +- Edit root `package.json` `pnpm.overrides` for overrides (keep alphabetical) |
| 110 | +- If a direct bump changes behavior, update consuming code (e.g., adding `allowOverwrite: true` when an API default changes) |
| 111 | + |
| 112 | +### 4. Install and Verify |
| 113 | + |
| 114 | +```bash |
| 115 | +pnpm install |
| 116 | +``` |
| 117 | + |
| 118 | +If install fails due to native build errors (e.g., `better-sqlite3`), fall back to: |
| 119 | + |
| 120 | +```bash |
| 121 | +pnpm install --ignore-scripts |
| 122 | +``` |
| 123 | + |
| 124 | +Then re-run the audit script with the same severity: |
| 125 | + |
| 126 | +```bash |
| 127 | +./.github/workflows/audit-dependencies.sh $ARGUMENTS |
| 128 | +``` |
| 129 | + |
| 130 | +The audit script must exit 0. If vulnerabilities remain, check for additional instances of the same dependency in other workspace packages. |
| 131 | + |
| 132 | +### 5. Build and Verify |
| 133 | + |
| 134 | +```bash |
| 135 | +pnpm run build:core |
| 136 | +``` |
| 137 | + |
| 138 | +For packages with changed dependencies, also run their specific build: |
| 139 | + |
| 140 | +```bash |
| 141 | +pnpm run build:<package-name> |
| 142 | +``` |
| 143 | + |
| 144 | +### 6. Look Up CVEs |
| 145 | + |
| 146 | +For each fixed vulnerability, find the GitHub Security Advisory (GHSA): |
| 147 | + |
| 148 | +- Check `https://github.com/<org>/<repo>/security/advisories` for each package |
| 149 | +- Search the web for `<package-name> GHSA <fixed-version>` |
| 150 | +- Record: GHSA ID, CVE ID, severity, one-line description |
| 151 | +- Prefer GHSA links (`https://github.com/advisories/GHSA-xxxx-xxxx-xxxx`) over NVD links |
| 152 | + |
| 153 | +**Parallelize CVE lookups**: Dispatch parallel agents to search for CVEs across all packages simultaneously. |
| 154 | + |
| 155 | +### 7. Commit and Create PR |
| 156 | + |
| 157 | +Commit with conventional commit format: |
| 158 | + |
| 159 | +``` |
| 160 | +fix(deps): resolve $ARGUMENTS severity audit vulnerabilities |
| 161 | +``` |
| 162 | + |
| 163 | +Create PR using `gh pr create` with this body structure: |
| 164 | + |
| 165 | +```markdown |
| 166 | +# Overview |
| 167 | + |
| 168 | +[What the PR fixes, mention `pnpm audit --prod`] |
| 169 | + |
| 170 | +## Key Changes |
| 171 | + |
| 172 | +- **[Package name] in [workspace path]** |
| 173 | + - [old version] → [new version]. Fixes [GHSA-xxxx-xxxx-xxxx](https://github.com/advisories/GHSA-xxxx-xxxx-xxxx) ([description]). |
| 174 | + - [Why this approach: direct bump because X / override because Y] |
| 175 | + - [Any code changes required by the bump] |
| 176 | + |
| 177 | +## Design Decisions |
| 178 | + |
| 179 | +[Why direct bumps were preferred, justification for any remaining overrides] |
| 180 | +``` |
| 181 | + |
| 182 | +## Common Mistakes |
| 183 | + |
| 184 | +| Mistake | Fix | |
| 185 | +| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | |
| 186 | +| Jumping straight to overrides | Always check if bumping the parent resolves it first | |
| 187 | +| Not checking all workspace packages | Same dep may appear in multiple `package.json` files (e.g., `changelogen` in both `tools/releaser` and `tools/scripts`) | |
| 188 | +| Overriding with a nonexistent version | Verify the target version exists with `pnpm view` before installing | |
| 189 | +| Not falling back to `--ignore-scripts` | Pre-existing native build failures block `pnpm install`; use `--ignore-scripts` to get lockfile updated | |
| 190 | +| Missing code changes for breaking bumps | If a bump changes API defaults, update the calling code | |
| 191 | +| Forgetting advisory links in PR | Always look up and include GHSA links for each vulnerability | |
0 commit comments