Dependabot alerts triaging
Skill NASA-PDS/pds-agent-skills/static/marketplace/skills/dependabot-alerts-triaging
Analyze GitHub Dependabot dependency vulnerability alerts and suggest triage decisions (dismiss/fix/escalate) with explanations. Use when the user needs help reviewing Dependabot alerts, deciding whether dependencies are exploitable, or triaging CVEs across NASA PDS repositories.From its SKILL.md
npx -y skills add NASA-PDS/pds-agent-skills --skill dependabot-alerts-triagingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 6 commands, including `jq -r '[.alerts[].repository] | unique[]' alerts.json` and 5 more.
SKILL.md
17.3 KB, ~4.6k tokens by cl100k_base, as published. Nobody here has run it
Dependabot Alerts Triaging Skill
This skill helps you make informed triage decisions on GitHub Dependabot dependency vulnerability alerts by analyzing each CVE — one at a time — in the context of how the affected package is actually used in NASA-PDS code. You review and approve every decision before anything is recorded or applied.
Prerequisites
- JSON export from
dependabot-alerts-exportingskill ghCLI authenticated (for creating outlaw-tracker issues)- Local clones of affected repositories (strongly recommended — see Step 1a)
Workflow Position
1. dependabot-alerts-exporting → Export alerts to JSON
2. dependabot-alerts-triaging → THIS SKILL: Analyze & decide one by one
3. dismiss-alerts.mjs → Apply dismissal decisions to GitHub
Triage Actions
| Action | When to Use | GitHub API Value |
|---|---|---|
| fix | Patched version available; upgrade is feasible | Keep open, create outlaw-tracker issue |
| tolerable_risk | Real CVE but attack vector doesn't apply to PDS usage | tolerable_risk |
| inaccurate | CVE doesn't affect this package/version, or vulnerable function is never called | inaccurate |
| no_bandwidth | Real issue, acceptable risk for now, defer to backlog | no_bandwidth |
Workflow
Step 1: Load the Export
Ask the user for the path to their Dependabot alerts JSON file. Parse it and show a brief summary:
Loaded 5 alerts for nasa-pds/registry-legacy-solr
HIGH: 1
MEDIUM: 3
LOW: 1
I'll go through each one individually, starting with the highest severity.
Ready? [yes]
Wait for the user to confirm before starting.
Step 1a: Clone Affected Repositories
Before presenting any alerts, identify the unique repositories in the export and clone them into /tmp. A local clone enables fast grep searches across all source files — much faster and more thorough than the GitHub Search API, which is rate-limited and only indexes certain file types.
# Get unique repos from the export
jq -r '[.alerts[].repository] | unique[]' alerts.json
# Shallow-clone each one
git clone --depth=1 https://github.com/NASA-PDS/<repo>.git /tmp/<repo>
After cloning, check for a CLAUDE.md in each repo — it often contains architecture notes, production deployment details, known breaking-change warnings, and dependency constraints that directly inform triage decisions:
cat /tmp/<repo>/CLAUDE.md 2>/dev/null || echo "No CLAUDE.md"
Read and internalize this context before starting the alert-by-alert triage.
Step 2: Order the Queue
Sort alerts: CRITICAL → HIGH → MEDIUM → LOW. Within the same severity, sort by CVSS score descending.
If the same CVE appears in multiple repos, note it when presenting the first instance ("This CVE also affects 2 other repos — after you decide here, I can apply the same decision to those"). Present each repo's alert individually — never assume the same decision applies without the user confirming.
Step 3: Triage Each Alert — One at a Time
Present one alert using this format, then stop and wait:
Alert #1/5 — nasa-pds/registry-legacy-solr — Alert #33
────────────────────────────────────────────────────────
Package: lxml (pip)
Severity: HIGH — CVSS 7.5
CVE: CVE-2026-41066
Advisory: https://github.com/advisories/GHSA-xxxx-xxxx-xxxx
Alert URL: https://github.com/NASA-PDS/registry-legacy-solr/security/dependabot/33
Vulnerable: < 6.1.0 | Fixed: 6.1.0
Manifest: src/main/resources/requirements.txt (runtime)
WHAT IS IT:
lxml's iterparse() and ETCompatXMLParser() use a default libxml2 configuration
that allows XML External Entity (XXE) processing. If untrusted XML is passed to
these functions, an attacker can read arbitrary local files or trigger SSRF.
WHAT I FOUND IN THE REPO:
[Search the repo for lxml imports and usages. Report specifically:
- Which functions are called (parse, iterparse, fromstring, etc.)
- Whether the input comes from user-supplied data or internal sources
- E.g.: "lxml.etree.parse() is called on PDS4 labels in src/harvest/xml_parser.py.
Labels are submitted by external users — XXE is reachable."]
EXPLOITABILITY:
[Based on the code findings, assess whether the vulnerable API is reachable
with attacker-controlled input. Be specific.
E.g.: "HIGH — external XML is parsed without disabling entity resolution."]
MY RECOMMENDATION:
Action: fix
Reason: Patch available (6.1.0). Runtime dep. Likely reachable with external XML.
Comment: "CVE-2026-41066: lxml XXE via iterparse(). Upgrade to >=6.1.0.
— Triaged with assistance from Claude"
Confidence: medium (awaiting code confirmation)
outlaw-tracker: YES
Do you want to:
1. ✅ Fix — keep open + create outlaw-tracker issue
2. 🟡 Dismiss — tolerable_risk (attack vector not applicable to PDS)
3. 🟡 Dismiss — inaccurate (vulnerable function not used / CVE doesn't apply)
4. 🟡 Dismiss — no_bandwidth (real issue, defer)
5. 🔍 Investigate more first
6. ⏭️ Skip for now
Do not present the next alert until the user responds to this one.
If the user picks option 5 (investigate more), search the repository using available tools:
- Look for imports and usages of the flagged package/function
- Check if the dep appears in test/dev scope only
- Check the manifest for version pinning and transitive dep chains
- Report findings clearly, then re-present options 1–6.
Step 4: Record the Decision
After the user responds, immediately update the triage field for that alert in the working JSON and confirm:
✅ Recorded: dismiss (inaccurate) — lxml is only used via lxml.etree.fromstring() on
internally-generated XML, not user input. Vulnerable iterparse() is never called.
Progress: 1/5 done — 4 remaining
Fill the triage object:
{
"triage": {
"action": "dismiss",
"dismissedReason": "inaccurate",
"comment": "lxml.iterparse() is never called in this repo. Only fromstring() is used on internally-generated XML. — Triaged with assistance from Claude",
"githubIssueUrl": null,
"reviewer": "jordanpadams",
"triageDate": "2026-04-23T15:30:00Z",
"confidence": "high"
}
}
Valid dismissedReason values (GitHub API):
tolerable_risk— Risk is real but acceptable in PDS contextinaccurate— CVE doesn't apply (wrong function, version confusion, not used)no_bandwidth— Real issue, low priority, deferred
Step 5: Create outlaw-tracker Issue (When action = fix)
When the user approves fix, immediately create a GitHub issue before moving to the next alert. Write the body to /tmp/dependabot_issue_body.md using the Write tool, then:
gh issue create \
--repo NASA-PDS/outlaw-tracker \
--title "CVE-YYYY-NNNNN: <package> vulnerability in NASA-PDS/<repo>" \
--label "security" \
--body-file /tmp/dependabot_issue_body.md
Issue body must include:
- CVE ID and GHSA ID
- Affected repository and manifest path
- Affected package, vulnerable version range, and patched version
- CVSS score and severity
- Brief description of the vulnerability and attack vector
- Exploitability assessment from the code investigation
- Recommended fix command (e.g.,
pip install "lxml>=6.1.0") - Link to the Dependabot alert
- Link to the GitHub advisory
Record the returned issue URL in triage.githubIssueUrl. Confirm the issue was created, then immediately advance to the next alert.
All comments must end with:
— Triaged with assistance from Claude
Step 6: Advance to the Next Alert
After recording a decision (and creating any outlaw-tracker issue), present the next alert using the same Step 3 format. Repeat until all alerts are done or the user says stop.
Step 7: Track Metrics — Update After Every Alert
Maintain two metric files throughout the session, updating them immediately after each alert decision. Do not wait until the end.
Create at Session Start
dependabot-triage-metrics.json — structured data for programmatic access:
{
"triageSession": {
"startDate": "2026-04-23T15:00:00Z",
"organization": "nasa-pds",
"totalRepositoriesScanned": 1,
"totalAlertsExported": 5,
"bySeverity": { "critical": 0, "high": 1, "medium": 3, "low": 1 },
"repositoriesTriaged": 0,
"alertsTriaged": 0,
"alertsRemaining": 5,
"tokenUsage": {
"total": 0,
"notes": "Update after each repository — check Claude Code token counter"
}
},
"remediationSummary": {
"fix": 0,
"tolerable_risk": 0,
"inaccurate": 0,
"no_bandwidth": 0,
"skipped": 0,
"outlaw_tracker_issues_created": 0
},
"repositoryDetails": []
}
DEPENDABOT_TRIAGE_METRICS.md — human-readable dashboard:
# Dependabot Triage Metrics
**Session Date:** 2026-04-23
**Organization:** nasa-pds
**Status:** In Progress
---
## 📊 Overall Statistics
| Metric | Count |
|--------|-------|
| **Total Repositories Scanned** | 1 |
| **Total Alerts Exported** | 5 |
| ├─ Critical | 0 |
| ├─ High | 1 |
| ├─ Medium | 3 |
| └─ Low | 1 |
| **Alerts Triaged** | 0 |
| **Alerts Remaining** | 5 |
| **Token Usage** | 0 |
---
## 🎯 Remediation Summary
| Decision | Count | % |
|----------|-------|---|
| **fix** | 0 | 0% |
| **tolerable_risk** | 0 | 0% |
| **inaccurate** | 0 | 0% |
| **no_bandwidth** | 0 | 0% |
| **outlaw-tracker Issues Created** | 0 | — |
---
## 📁 Repository Details
_(none yet)_
---
_Last Updated: 2026-04-23T15:00:00Z_
Update After Each Alert Decision
After recording each alert's decision:
- Increment
alertsTriagedand decrementalertsRemaining - Increment the matching
remediationSummarycounter - If action =
fix, incrementoutlaw_tracker_issues_createdand record the URL - Add or update the repository entry in
repositoryDetails[] - Update all counts in
DEPENDABOT_TRIAGE_METRICS.md - Update token usage — check the Claude Code token counter after each repository and add to
triageSession.tokenUsage.total
Repository Detail Entry Format
{
"repository": "nasa-pds/registry-legacy-solr",
"triagedDate": "2026-04-23T15:30:00Z",
"totalAlerts": 5,
"bySeverity": { "high": 1, "medium": 3, "low": 1 },
"decisions": {
"fix": 1,
"inaccurate": 1,
"no_bandwidth": 2,
"tolerable_risk": 1
},
"outlaw_tracker_issues": [
{
"issueNumber": 22,
"url": "https://github.com/NASA-PDS/outlaw-tracker/issues/22",
"title": "CVE-2026-25645: requests vulnerability in NASA-PDS/registry-legacy-solr",
"relatedAlerts": [29]
}
],
"alertDetails": [
{
"alertNumber": 33,
"package": "lxml",
"severity": "high",
"cveId": "CVE-2026-41066",
"decision": "inaccurate",
"rationale": "lxml never imported or used in codebase"
}
]
}
Step 8: Session Summary and Save
When all alerts are triaged (or the user types "done"/"save"), show a final summary and write the updated JSON:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Triage Complete — nasa-pds/registry-legacy-solr
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Total: 5
fix: 1 → outlaw-tracker issues: #22
inaccurate: 1
tolerable_risk: 1
no_bandwidth: 2
skipped: 0
Saved:
dependabot-registry-legacy-solr-triaged.json
dependabot-triage-metrics.json
DEPENDABOT_TRIAGE_METRICS.md
Next — apply dismissals:
node scripts/dismiss-alerts.mjs dependabot-registry-legacy-solr-triaged.json --dry-run
Write the updated alerts JSON appending -triaged before .json.
Step 9: Apply Dismissals
Offer to run the dismissal script after saving:
# Preview first
node scripts/dismiss-alerts.mjs dependabot-alerts-triaged.json --dry-run
# Apply
node scripts/dismiss-alerts.mjs dependabot-alerts-triaged.json
The script PATCHes each alert where triage.action === "dismiss" via the GitHub API with the recorded dismissedReason and comment. Requires GITHUB_TOKEN (same as the export step).
Step 10: Create a PR on outlaw-tracker with Triage Results
After dismissals are applied, commit the triage artifacts to NASA-PDS/outlaw-tracker and open a pull request so the session is permanently recorded and reviewable.
Files to include
dependabot-alerts-triaged.json— full alert data with triage decisionsdependabot-triage-metrics.json— structured session metricsDEPENDABOT_TRIAGE_METRICS.md— human-readable dashboard
Steps
# 1. Detect whether we're already inside the outlaw-tracker repo
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
REMOTE=$(git remote get-url origin 2>/dev/null)
if echo "$REMOTE" | grep -q "outlaw-tracker"; then
# Already in the repo — use it directly
OUTLAW_DIR="$REPO_ROOT"
else
# Clone it
git clone --depth=1 https://github.com/NASA-PDS/outlaw-tracker.git /tmp/outlaw-tracker
OUTLAW_DIR="/tmp/outlaw-tracker"
fi
cd "$OUTLAW_DIR"
# 2. Create a branch named for the session date and scope
BRANCH="dependabot-triage-$(date +%Y%m%d)"
git checkout -b "$BRANCH"
# 3. Create the triage-reports directory structure
REPORT_DIR="triage-reports/dependabot/$(date +%Y%m%d)"
mkdir -p "$REPORT_DIR"
# 4. Copy triage artifacts into the report directory
cp /path/to/dependabot-alerts-triaged.json "$REPORT_DIR/"
cp /path/to/dependabot-triage-metrics.json "$REPORT_DIR/"
cp /path/to/DEPENDABOT_TRIAGE_METRICS.md "$REPORT_DIR/"
# 5. Commit
git add "$REPORT_DIR"
git commit -m "Add Dependabot triage results for nasa-pds (<date>)
Triaged <N> alerts across <M> repositories.
fix: <N> (outlaw-tracker issues created: <N>)
inaccurate: <N>
tolerable_risk: <N>
no_bandwidth: <N>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>"
# 6. Push
git push -u origin "$BRANCH"
PR Body
Write the PR body to /tmp/triage_pr_body.md using the Write tool, then create the PR:
gh pr create \
--repo NASA-PDS/outlaw-tracker \
--base main \
--head "$BRANCH" \
--title "Dependabot triage results — nasa-pds (<date>)" \
--body-file /tmp/triage_pr_body.md \
--label "security"
The PR body should include:
- Session date and organization
- Summary table (total alerts, decisions breakdown, outlaw-tracker issues created)
- Links to each outlaw-tracker issue created during the session
- List of repositories triaged with alert counts
- Token usage for the session
- Note that dismissals have already been applied to GitHub
## Summary
Dependabot triage session for `nasa-pds` organization on <date>.
| Metric | Count |
|--------|-------|
| Repositories triaged | <N> |
| Total alerts | <N> |
| fix | <N> |
| inaccurate | <N> |
| tolerable_risk | <N> |
| no_bandwidth | <N> |
| outlaw-tracker issues created | <N> |
| Token usage | <N> |
## outlaw-tracker Issues Created
- #<N> — CVE-XXXX-XXXXX: <package> in <repo>
## Repositories Triaged
- `nasa-pds/<repo>` — <N> alerts (<N> fix, <N> dismissed)
## Artifacts
- `triage-reports/dependabot/<date>/dependabot-alerts-triaged.json`
- `triage-reports/dependabot/<date>/dependabot-triage-metrics.json`
- `triage-reports/dependabot/<date>/DEPENDABOT_TRIAGE_METRICS.md`
Dismissals have been applied to GitHub via the Dependabot API.
— Triaged with assistance from Claude
Common False Positive Patterns
inaccurate — not used
- The vulnerable function/method is never imported or called in the codebase
- The package is a transitive dep of a dev-only tool (jest, webpack, sphinx)
- The package appears only in
devDependencies/requirements-dev.txt, not in the production artifact
tolerable_risk
- CVE requires network exposure but the tool only runs locally (CLI validators, data pipeline tools)
- CVE requires unauthenticated access but PDS services require auth
- CVSS inflated — network-accessible vector described in advisory doesn't match PDS deployment model
- No patch available and the code is EOL legacy with no active maintainer
inaccurate — version or advisory mismatch
- Advisory later withdrawn or revised
- Fix already backported to the installed version
no_bandwidth
- Real vulnerability, no patch available, EOL library (e.g., commons-lang 2.x)
- Low CVSS, low exploitability, lower priority than other active work
Notes
- One at a time, always — never present multiple alerts at once; wait for the user to respond to each
- Investigate before guessing — use available tools to read the code; a specific finding beats a generic assessment
- "legacy" repo names are a signal —
no_bandwidthandtolerable_riskare more likely appropriate; call this out explicitly - Same CVE, multiple repos — mention cross-repo impact, but confirm the decision per repo unless the user says "apply to all"
- When unsure — say so and recommend human review; a missed real vulnerability is worse than over-caution
What ships with it: 1 file
5.8 KB alongside SKILL.md, 1 of them executable
scripts/
- dismiss-alerts.mjsruns5.8 KB