Skip to content

Allow Copilot coding agents through the bot allowlist without collaborator lookup - #67238

Merged
pelikhan merged 5 commits into
mainfrom
copilot/fix-copilot-bot-status-check
Oct 10, 2026
Merged

pelikhan merged 5 commits into
mainfrom
copilot/fix-copilot-bot-status-check

Conversation

Copilot AI commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

on.bots: [Copilot] matches the Copilot coding agent, but activation rejects it when the collaborator API returns 404. The workflow then appears successful while its review jobs are skipped.

  • Authorization: Explicitly allowlisted Copilot and copilot-swe-agent identities bypass the collaborator lookup. Other bots retain the existing installation check and confused-deputy protections.
  • Documentation and coverage: Clarify the exception in the on.bots reference and add regressions for PR activation, trusted synchronization, and fork rejection.
on:
  pull_request:
  bots: [Copilot]

…okup

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix Copilot bot status check for non-collaborators Allow Copilot coding agents through the bot allowlist without collaborator lookup Oct 9, 2026
Copilot AI requested a review from pelikhan October 9, 2026 17:20
@pelikhan
pelikhan marked this pull request as ready for review October 9, 2026 19:34
Copilot AI balanced review requested due to automatic review settings October 9, 2026 19:34
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Generated by Ponytail Reviewer for #67238

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

No ADR enforcement needed for PR #67238: has_implementation_label=false and default_business_additions=0 (<=100 threshold, no custom .design-gate.yml). 3 files changed, none adding >100 lines in business logic directories.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

Prepared to submit a PR review for #67238 after local analysis.

🔎 Code quality review by PR Code Quality Reviewer

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The change intentionally modifies a security-sensitive authorization boundary and warrants final human review.

0 open findings

What changed in this PR

This PR fixes Copilot coding agent activation by exempting explicitly allowlisted built-in identities from collaborator lookup.

Changes:

  • Bypasses collaborator checks for known Copilot identities.
  • Preserves fork and confused-deputy protections.
  • Adds regression tests and documents the exception.
File Description
actions/​setup/​js/​check_membership.cjs Implements the Copilot authorization exception.
actions/​setup/​js/​check_membership.test.cjs Covers activation, synchronization, and fork rejection.
docs/​src/​content/​docs/​reference/​triggers.md Documents Copilot’s special allowlist behavior.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@github-actions github-actions Bot mentioned this pull request Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

Peek at saved memory (pr-code-quality-reviewer)
reviewed_at: 2026-10-09T19:40:38Z
review_event: REQUEST_CHANGES
top_themes:
  - incomplete Copilot alias coverage in bot allowlist bypass
files_reviewed:
  - actions/setup/js/check_membership.cjs
  - actions/setup/js/check_membership.test.cjs
  - actions/setup/js/check_permissions_utils.cjs
  - docs/src/content/docs/reference/triggers.md
  - pkg/workflow/bot_aliases_test.go
  - pkg/workflow/bots_test.go
  - pkg/constants/bot_constants.go
comment_count: 1

Note

This comment is managed by comment memory.

Expand the saved memory block to view or edit the persistent context for this thread.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 58.4 AIC · ⌖ 8.25 AIC · ⊞ 19.9K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes

The Copilot allowlist shortcut is still incomplete, so a supported on.bots: [copilot] configuration can keep failing for canonical Copilot actor IDs.

Blocking theme

The compiler expands the copilot alias to multiple identities, but this patch only special-cases three literal actor strings in the membership check. As a result, some canonical Copilot actors still hit the collaborator lookup path and are rejected as inactive, which means the regression described in the PR is only partially fixed.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 58.4 AIC · ⌖ 8.25 AIC · ⊞ 19.9K
Comment /review to run again

Comment thread actions/setup/js/check_membership.cjs Outdated
const botStatus = await checkBotStatus(actorToValidate, owner, repo);
// Built-in Copilot agents are not repository collaborators; the explicit allowlist
// is sufficient for their GitHub-provided actor identities.
const isBuiltInCopilot = actorToValidate === "Copilot" || actorToValidate === "copilot-swe-agent" || actorToValidate === "copilot-swe-agent[bot]";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bypass only recognizes three hard-coded actor strings, so supported Copilot aliases like copilot and @app/copilot-swe-agent still fall through to checkBotStatus() and get rejected as bot_not_active.

💡 Why this blocks the fix

The compiler already expands on.bots: [copilot] to the full Copilot family (copilot-swe-agent, Copilot, copilot, @app/copilot-swe-agent). With the current check, only Copilot, copilot-swe-agent, and copilot-swe-agent[bot] bypass the collaborator lookup, so two canonical identities that the product explicitly emits remain broken.

Please derive this exception from the same normalized Copilot alias set the compiler uses, or at least include every expanded identifier after stripping an optional [bot] suffix, so the auth path cannot drift again.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fb33cbd: the membership check now recognizes every compiler-supplied Copilot alias after [bot] normalization and only allows a conclusive collaborator 404. Regression coverage exercises the full alias family.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /codebase-design on the core change in check_membership.cjs. Tests and docs look solid; flagging one maintainability concern worth addressing before merge.

📋 Key Themes & Highlights

Key Themes

  • Duplicated identity list: the new isBuiltInCopilot check hardcodes a third list of Copilot identifiers (Copilot, copilot-swe-agent, copilot-swe-agent[bot]) that overlaps but doesn't match pkg/constants.CopilotBotNames (which also has copilot and @app/copilot-swe-agent). Future aliases added there won't automatically get the bypass here, silently reintroducing #67157 for them.
  • Bypasses existing conclusive-lookup pattern: the PR could reuse the already-tested installationCheckOptional bypass (used for repository_dispatch) instead of skipping checkBotStatus entirely, keeping one code path for "App identity isn't a collaborator" rather than two.
  • Minor duplication: the three-literal === chain could use the existing canonicalizeBotIdentifier helper already imported in this file.

Positive Highlights

  • ✅ Confused-deputy protection is correctly preserved — fork-PR synchronization from an allowlisted Copilot actor is still denied before authorization (verified by the new "deny allowlisted Copilot synchronizing a fork PR" test).
  • ✅ Good regression coverage: it.each over all three literal identities, plus a negative test (copilot[bot]) confirming the bypass doesn't over-match similar-looking bots.
  • ✅ Docs update in triggers.md clearly explains the exception alongside the existing collaborator-lookup rules.

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 136.1 AIC · ⌖ 14.7 AIC · ⊞ 10.1K
Comment /matt to run again

Comment thread actions/setup/js/check_membership.cjs Outdated
const botStatus = await checkBotStatus(actorToValidate, owner, repo);
// Built-in Copilot agents are not repository collaborators; the explicit allowlist
// is sufficient for their GitHub-provided actor identities.
const isBuiltInCopilot = actorToValidate === "Copilot" || actorToValidate === "copilot-swe-agent" || actorToValidate === "copilot-swe-agent[bot]";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] This hardcodes a third, independent list of "built-in Copilot" identities (Copilot, copilot-swe-agent, copilot-swe-agent[bot]) that must stay in sync with pkg/constants.CopilotBotNames (which also includes copilot and @app/copilot-swe-agent). It also completely skips checkBotStatus instead of reusing the already-tested "conclusively not a collaborator" bypass (installationCheckOptional) used for repository_dispatch — that path addresses the same root cause (GitHub App identities aren't collaborators) without a brand-new, unverified branch.

💡 Why this matters

The root cause of #67157 is "GitHub App/bot identities aren't repository collaborators, so the lookup 404s." That's exactly what installationCheckOptional already solves for repository_dispatch, with real verification (a 404 from the API, not an actor-name string match) and test coverage for the "lookup fails → not authorized" case. This PR instead adds a second, hand-maintained identity list that bypasses the API call entirely:

  • If pkg/constants.CopilotBotNames gains a new alias later (it already has copilot and @app/copilot-swe-agent), this list silently falls out of sync and those aliases regress back to the original 404 bug.
  • Skipping checkBotStatus means zero API verification occurs for Copilot — a typo'd or spoofed actorToValidate string match would be the only protection, whereas the existing installationCheckOptional pattern still requires a conclusive 404 (not a transient error) before authorizing.

Consider either: (a) extracting a shared isBuiltInCopilotIdentity helper backed by the same canonical list the Go compiler uses (or passing it through as a generated constant), or (b) setting installationCheckOptional: true for Copilot's pull_request/pull_request_target paths and reusing the existing conclusively-not-a-collaborator logic instead of a full bypass.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fb33cbd: Copilot aliases now come from constants.CopilotBotNames, are matched using canonicalizeBotIdentifier, and reuse the existing installationCheckOptional path, which still denies transient lookup errors.

Comment thread actions/setup/js/check_membership.cjs Outdated
const botStatus = await checkBotStatus(actorToValidate, owner, repo);
// Built-in Copilot agents are not repository collaborators; the explicit allowlist
// is sufficient for their GitHub-provided actor identities.
const isBuiltInCopilot = actorToValidate === "Copilot" || actorToValidate === "copilot-swe-agent" || actorToValidate === "copilot-swe-agent[bot]";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] The three-way literal string comparison (actorToValidate === "Copilot" || actorToValidate === "copilot-swe-agent" || actorToValidate === "copilot-swe-agent[bot]") duplicates logic that canonicalizeBotIdentifier already exists to solve elsewhere in this same file's import list.

💡 Suggested simplification
const canonicalActor = canonicalizeBotIdentifier(actorToValidate);
const isBuiltInCopilot = canonicalActor === "Copilot" || canonicalActor === "copilot-swe-agent";

This reduces three branches to two, matches the existing canonicalization convention used by isAllowedBot/checkBotStatus in check_permissions_utils.cjs, and automatically covers any future [bot]-suffixed variant without needing a third literal added by hand.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fb33cbd: actor and configured alias names now use the existing canonicalizeBotIdentifier helper, including optional [bot] suffixes.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Change type: bug_fix (correctness fix to confused-deputy / bot-allowlist authorization logic)
Impeccable modes applied: harden, audit

The fix correctly scopes the collaborator-lookup bypass to only the three canonical built-in Copilot actor identities, applied after isAllowedBot() gating — so the existing confused-deputy, cross-repo PR, and Dependabot protections are untouched. Test coverage is solid: trusted-author synchronize, fork-PR rejection, all three literal identity forms, and a negative case (copilot[bot]) confirming the bypass doesn't over-match similar-looking actors.

One non-blocking maintainability note left inline: the literal identity list duplicates constants.CopilotBotNames in Go; consider a shared source of truth or a cross-reference comment so future additions to the canonical list aren't missed here.

No blocking issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 124.1 AIC · ⌖ 13.1 AIC · ⊞ 8.1K

Comment thread actions/setup/js/check_membership.cjs Outdated
const botStatus = await checkBotStatus(actorToValidate, owner, repo);
// Built-in Copilot agents are not repository collaborators; the explicit allowlist
// is sufficient for their GitHub-provided actor identities.
const isBuiltInCopilot = actorToValidate === "Copilot" || actorToValidate === "copilot-swe-agent" || actorToValidate === "copilot-swe-agent[bot]";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This literal identity list ("Copilot", "copilot-swe-agent", "copilot-swe-agent[bot]") duplicates knowledge already centralized in Go as constants.CopilotBotNames (copilot-swe-agent, Copilot, copilot, @app/copilot-swe-agent) and used for on.bots: [Copilot] expansion. If that canonical list ever changes (e.g. a new runtime alias is added), this JS check silently drifts out of sync and either over- or under-grants the collaborator-lookup bypass.

Consider deriving this list from a shared JS constant (mirroring bot_constants.go) or adding a code comment/test that explicitly cross-references constants.CopilotBotNames so a future update to one is caught by review of the other.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fb33cbd: the compiler passes the canonical constants.CopilotBotNames list to membership validation, so the JavaScript authorization check no longer maintains a separate identity list.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.
  2. Review (actions/setup/js/check_membership.cjs:37): This bypass only recognizes three hard-coded actor strings, so supported Copilot aliases like copilot and @app/copilot-swe-agent still fall through to checkBotStatus() and get rejected as bot_not_active. - Allow Copilot coding agents through the bot allowlist without collaborator lookup #67238 (comment)
  3. Review (actions/setup/js/check_membership.cjs:37): [/diagnosing-bugs] This hardcodes a third, independent list of "built-in Copilot" identities (Copilot, copilot-swe-agent, copilot-swe-agent[bot]) that must stay in sync with pkg/constants.CopilotBotNames (which also includes copilot and @app/copilot-swe-agent). It also completely skips checkBotStatus instead of reusing the already-tested "conclusively not a collaborator" bypass (installationCheckOptional) used for repository_dispatch. - Allow Copilot coding agents through the bot allowlist without collaborator lookup #67238 (comment)
  4. Review (actions/setup/js/check_membership.cjs:37): [/codebase-design] The three-way literal string comparison (actorToValidate === "Copilot" || actorToValidate === "copilot-swe-agent" || actorToValidate === "copilot-swe-agent[bot]") duplicates logic that canonicalizeBotIdentifier already exists to solve elsewhere in this same file's import list. - Allow Copilot coding agents through the bot allowlist without collaborator lookup #67238 (comment)
  5. Review (actions/setup/js/check_membership.cjs:37): This literal identity list duplicates knowledge already centralized in Go as constants.CopilotBotNames. If that canonical list ever changes, this JS check silently drifts out of sync and either over- or under-grants the collaborator-lookup bypass. - Allow Copilot coding agents through the bot allowlist without collaborator lookup #67238 (comment)
  6. Fix failing check JS Tests (shard 4/4) (FAILURE): https://github.com/github/gh-aw/actions/runs/37981205311/job/113992107430.

Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI.

Sous-chef head: f7d2328
Sous-chef work: 22e3f35499d093214ade21640dfef9db369516c2524efeb2dc3b014dbf2ab594 31f7e812d45f0792093269b7b90445aa9803225a204ec130694b9ceb0227d7cc a236ed442f8b1092cb36e15a3749e94812ffaae6c2e3e09c9ab6efbcebfcda3e b9c0463db82d20601ae1d30ba34d261caf43fa4339d426f2a8c3dbe8f026ef14 cfba07253b637cb6edc3a25e15838fa99fde0494327db994f5525e27d78bc0db
Sous-chef state: 563ec04c8829aabb31e7f7015eaa359d1b6bb13220d4344cdac4774d5abbfc20

Generated by 👨‍🍳 PR Sous Chef · pi · haiku45 · 11.9 AIC · ⌖ 7.33 AIC · ⊞ 1K · ◷
Comment /souschef to run again

Copilot AI and others added 2 commits October 9, 2026 20:53
…ot-status-check

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.

Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI.

Sous-chef head: fb33cbd
Sous-chef work:
Sous-chef state: 2b67e119d6c63c79338d82d17d41bc22c4b3f2007c0196c78b640f0b64fb0b18

Generated by 👨‍🍳 PR Sous Chef · pi · haiku45 · 4.26 AIC · ⌖ 7.98 AIC · ⊞ 1K · ◷
Comment /souschef to run again

…ot-status-check

# Conflicts:
#	actions/setup/js/work_queue_compaction.test.cjs

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
@pelikhan
pelikhan merged commit 6976a37 into main Oct 10, 2026
46 checks passed
@pelikhan
pelikhan deleted the copilot/fix-copilot-bot-status-check branch October 10, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

on.bots entry for the Copilot coding agent is ignored: bot status check requires a collaborator that does not exist

4 participants