GitHub Copilot Vulnerable Dependency Remediation
Opus 4.7
Model compatibility is recorded; source facts remain human-verifiable.
A three-part bundle — a .github/copilot-instructions.md
addendum, a GitHub issue template, and an explicit assignment step after the
finding is validated. Together they shape
the GitHub Copilot cloud agent into a narrow, reviewable dependency
remediator: one finding per issue, one draft PR per issue, no
auto-merge.
Rechecked August 23, 2026: leftover CVE dumps stay development /
noindex. Do not invent a named floor. Dependabot-to-agent
assignment is generally available for Copilot, Claude, and Codex
and still requires GitHub Code Security plus a Copilot plan with
coding-agent access. That is not the same as one-step Autofix.
The Copilot issue-assignment and agent-tasks APIs remain public
preview. Frontmatter model strings stay metadata, not prompt
pins.
What this prompt does
When the scanner (or a developer) creates an issue from the
security-remediation-dep.yml template and labels it
copilot-remediate, the label routes the issue for validation; it does not
start the GitHub Copilot cloud agent. After an authorized reviewer confirms the
advisory, affected package, repository, and scope, they explicitly assign the
issue to Copilot. The cloud agent then reads the repository-level instructions,
applies the minimum viable
version bump in the affected manifest + lockfile, runs CI, and
opens a draft PR linked back to the issue. The agent respects
the house rules — no major bumps, no lockfile-only edits, no
disabling of tests.
Inputs: finding id + affected package (from the issue body),
repository-level instructions (from .github/copilot-instructions.md).
Outputs: a draft PR linked to the issue, passing CI, and a
human reviewer assigned via CODEOWNERS.
When to use it
- You want the shortest-setup remediation path. GitHub-native, no separate orchestration layer.
- Your scanner already supports projecting findings into GitHub Issues (CodeQL, Snyk, Semgrep, Dependabot alerts converted to issues).
- You have branch protection on
mainthat requires review and green CI, so the “agent opens a draft PR” pattern is safe.
Don’t use it for:
- Major version migrations — the repository instructions refuse.
- Cross-repo fanouts — each repo needs its own instructions and dispatch policy; this prompt is per-repo.
- First-party SAST findings — use the SDE remediation recipe.
Inputs
- GitHub issue template fields: finding id, affected package, severity,
advisory URLs, scanner notes, workspace hint, direct/transitive evidence, and
a
copilot-remediaterouting label that does not itself dispatch the agent. - Repository instructions from
.github/copilot-instructions.md, issue body, CODEOWNERS, branch protection, required CI, PR labeling rules, and reviewer routing. - Dependency evidence: manifests, lockfiles, package manager, dependency tree, current version, patched range, direct parent for transitive fixes, and ecosystem-specific update commands.
- Verification evidence: documented lint/test commands, CI status, scanner re-run output, lockfile diff, refused-fix issue comments, and revert instructions.
- Triage evidence for major bump, prerelease-only, package-not-installed, tests failing, unavailable patch, monorepo workspace scope, and branch or CODEOWNERS restrictions.
The prompt
Two files are checked in to the repository; a validated issue is then dispatched through an explicit assignment step.
.github/copilot-instructions.md — dependency remediation addendum
Append this to your existing copilot-instructions.md:
## Vulnerable dependency remediation
When working on an issue labeled `copilot-remediate` whose body
includes a finding id (CVE- / GHSA-), follow these rules.
### Scope
- ONE finding per PR. Never bundle multiple advisories.
- Branch: `copilot/<finding-id>`.
- Commit: Conventional Commits: `fix(sec): bump <pkg> from <old>
to <new> (<finding-id>)`.
### Version bump policy
- Pick the LOWEST version in the advisory's patched range.
- NEVER bump across a major-version boundary. If the only fix
is a major bump, post a comment on the issue explaining why
(direct dep vs transitive, breaking changes expected) and
stop — do not push a PR.
- Pre-release / rc / beta versions are off by default. If the
advisory lists only a pre-release fix, comment on the issue
and stop.
### Tooling
- Use the native package manager to apply the bump. Never
hand-edit the lockfile.
- After the bump, run the lint and test commands documented at
the top of this file. If they fail because of the bump,
revert, comment on the issue with the failing tests, and stop.
### Paths you may NOT touch
- `db/migrations/**` — any DB migration.
- `infra/terraform/**` — infra-as-code.
- `**/*.generated.*` — generated code.
- Any CI workflow, except to update a pinned action version in
response to a CVE on that action.
### PR shape
- Title: `fix(sec): bump <pkg> to <ver> (<finding-id>)`.
- Body: link the issue (`Closes #NNN`), finding id + link to
advisory, old → new version, direct vs transitive, test
command + pass evidence, one-line revert instructions.
- Keep the PR as DRAFT. Never mark ready-for-review. Never
enable auto-merge.
.github/ISSUE_TEMPLATE/security-remediation-dep.yml
name: Security — Dependency remediation
description: Open a remediation task for a single CVE / GHSA finding.
title: "Remediate: <finding-id> in <package>"
labels: ["copilot-remediate", "security"]
assignees: []
body:
- type: input
id: finding_id
attributes:
label: Finding id
description: CVE id, GHSA id, or scanner-assigned id.
placeholder: CVE-2026-1234
validations:
required: true
- type: input
id: package
attributes:
label: Affected package
description: Package name (best-effort hint from the scanner).
placeholder: "@example/unsafe-parser"
validations:
required: true
- type: dropdown
id: severity
attributes:
label: Advisory severity
options: [critical, high, medium, low]
validations:
required: true
- type: textarea
id: advisory_url
attributes:
label: Advisory link(s)
description: Paste the GHSA / CVE / NVD URL.
validations:
required: true
- type: textarea
id: notes
attributes:
label: Notes for the agent
description: Anything the scanner couldn't auto-populate.
placeholder: |
- Dependency is transitive via "express@4".
- Workspace package `apps/web` is the caller.
validations:
required: false
Dispatch the validated issue
Creating or labeling the issue does not start the cloud agent. First confirm that the advisory is authoritative, the package is installed, and the issue is in the repository that owns the fix. Then choose one supported mechanism:
- Manual assignment (recommended): select Copilot from the issue’s assignee list and review the target repository, starting branch, and additional instructions. See GitHub’s issue-assignment workflow.
- API assignment after validation: assign
copilot-swe-agent[bot]and send the supportedagent_assignmentobject. The API is a public preview; use GitHub’s current REST or GraphQL contract. - Copilot automation only for a trusted intake: eligible private and internal repositories can use an issue-created automation with a narrow search filter and least-privilege tools. Do not connect raw third-party scanner output directly to an autonomous code-writing session. Preserve the default protection against events created by users without write access. See Copilot automations.
The copilot-remediate label is a routing and filter signal only. Do not rely
on an assign-copilot.yml Action, an @copilot alias, or
assignees: ["copilot"] in the issue template.
Once the session starts, the GitHub Copilot cloud agent reads:
- The repo-level
copilot-instructions.md(house rules + the dependency addendum above). - The issue body (finding id, package, advisory link).
It produces a draft PR on copilot/<finding-id> that either
fixes the finding or posts a comment explaining why the fix was
refused (major bump required, pre-release only, tests fail).
Verification
- Rechecked 2026-08-21 against GitHub’s current Copilot Autofix and Copilot cloud agent (“Assign to Copilot”) workflow.
- Creating or labeling an issue still does not start the agent; an authorized reviewer must assign the issue after validation.
- One finding still produces one draft PR or a refusal comment.
Output contract
Return one of:
- A draft PR linked to the issue that remediates one advisory-driven dependency path, uses the native package manager, touches only allowed manifest/lockfile artifacts, records test evidence, follows branch/commit/title/body rules, and routes to CODEOWNERS review.
- An issue comment without code changes when the package is not installed, the fix requires a disallowed major bump, only a prerelease exists, tests fail, the scope is ambiguous, or the finding belongs to another repo/workspace.
The output must list finding id, package, advisory link, old/new version, direct/transitive status, files touched, tests/CI evidence, PR URL or refusal reason, and reviewer routing. It must not mark the PR ready, auto-merge, edit forbidden paths, disable tests, or bundle multiple advisories.
Related recipes
- Vulnerable Dependency Remediation
- Codex vulnerable dependency remediation
- Cursor vulnerable dependency remediation
Known limitations
- Instructions are a prompt, not enforcement. Pair this with
strict branch protection +
CODEOWNERSrouting on any path the agent must not touch. The addendum’s “paths you may NOT touch” list is advisory;CODEOWNERSmakes it a hard gate. - Single-manifest assumption. For monorepos, file one issue per affected workspace so the agent has a narrow scope.
- Transitive fixes. The agent can only hoist a transitive fix by bumping a parent; if the parent requires a major bump, the addendum forces a stop. That’s the correct behavior, but expect more “refused” comments than raw PRs for older ecosystems.
- Scanner projection cadence matters. If your scanner
projects every low-severity finding into an issue, the Copilot
review queue will balloon. Gate projection on severity
high | criticaland label drift manually.
Changelog
- 2026-04-21 — v1, first published. Covers Node / Python / Go lockfiles. Major-bump refusal is intentional.