security-maintenance
Triage and fix Dependabot alerts and CodeQL findings in the ai repository. Use when the user asks to address security vulnerabilities, fix Dependabot alerts, resolve CodeQL issues, or do security main
Files4
View on GitHubSKILL.md.claude/skills/security-maintenance/SKILL.md
GitHubWhat I do
I drive the security maintenance workflow for the ai repository to keep both dashboards at zero:
- Dependabot — https://github.com/Unique-AG/ai/security/dependabot
- CodeQL — https://github.com/Unique-AG/ai/security/code-scanning
When to use me
- "fix dependabot", "security maintenance", "fix vulnerabilities", "dependabot alerts", "CodeQL findings"
- Periodic security maintenance sessions
- After Dependabot auto-opens PRs (we do not merge those directly)
Release model — read first
Versions and changelogs are fully owned by release-please (config: release-please-config.json, manifest: .release-please-manifest.json). CI enforces this via .github/scripts/check-no-manual-release.sh, which fails any PR that modifies:
- any
CHANGELOG.md .release-please-manifest.json- the
version = "..."line in anypyproject.toml
Because of that:
- Never edit
CHANGELOG.mdor bumpversionby hand. Do not use therelease-processskill to justify manual edits in security PRs — that skill documents automation, not hand bumps. - Drive the next release entries through conventional commit subjects (see
git-conventional-commits). For Dependabot/CodeQL fixes usefix(<scope>): ...so release-please groups them under "Bug Fixes". Usechore(deps): ...only for risk-free dep bumps you don't want to surface in user-facing notes (it's hidden in the changelog). - One commit per PR is fine; release-please derives bumps per workspace package from the commit subject + changed paths.
Dependabot workflow
Never merge Dependabot auto-PRs. Use constraint-dependencies in the root pyproject.toml instead.
- List alerts — see gh commands reference. Always paginate (
gh api --paginate); the Dependabot endpoint is cursor-paged and a singleper_page=100call silently caps at 100. - Find fix version from the alert JSON.
- Add/bump
constraint-dependenciesin rootpyproject.tomlwith"<package>>=<fixed-version>". - Handle
exclude-newerconflicts — if the fix version is within the 2-week rolling window, add anexclude-newer-packagetimestamp (day after latest PyPI upload). See exclude-newer reference. - Prune stale
exclude-newer-packageentries — remove any timestamp older than 2 weeks (redundant, global window already covers it). Keep= falseentries. - Relock —
uv lock --refresh. If resolution fails, bump the timestamp and retry. - Branch and commit — branch
fix/dependabot-<pkg>-<ver>(single CVE) orfix/security-<date>(batch). Subject:fix(deps): bump <pkg> to >=<ver> (GHSA-xxxx)orfix(security): batch dependabot fixes <date>. Do not touchCHANGELOG.mdor anyversion = ...field — release-please will pick the commit up on the next standing Release PR. - Open PR, then close Dependabot auto-PRs after merge (they won't auto-close because we ship via constraints, not by merging their lockfile bump).
CodeQL workflow
- List findings — see gh commands reference. Paginate the same way.
- Read the rule and flagged code in context.
- Fix the code — see common CodeQL patterns.
- Branch and PR — same shape as Dependabot. Use
fix(<package-or-area>): <what was hardened> (CodeQL <rule-id>). Again: no manual changelog/version edits.
Batch session
- List all Dependabot alerts and CodeQL findings (paginated).
- Prune stale
exclude-newer-packageentries. - Fix Dependabot alerts (mechanical: constraints + relock).
- Fix CodeQL findings (code changes).
- Single branch for related fixes, separate branches for unrelated areas.
- Commit with
fix(...)subjects so release-please attributes bumps to the right workspace package(s) on the next Release PR. - Create PR(s), let CI run
check-no-manual-release.sh, then close any resolved Dependabot auto-PRs after merge.
Tips
- Never merge Dependabot auto-PRs —
constraint-dependenciespersists across relocks; auto-PRs only edituv.lock. - Never touch
CHANGELOG.md,.release-please-manifest.json, orversion = ...—check-no-manual-release.shwill block the PR. - Use
fix(...)notchore(deps): ...when you want the fix to appear in user-facing release notes;choreis hidden by the changelog config. - Round timestamps up — day after latest artifact upload (
uvuses strict<on individual wheel upload times). - Batch when possible — one PR reduces noise; release-please still attributes per workspace package.
- Prune stale timestamps — entries older than the 2-week window are redundant.
- Check both dashboards — Dependabot and CodeQL are independent.