Skip to content

Enforce configured targets in safe-output handlers - #62447

Merged
pelikhan merged 6 commits into
mainfrom
copilot/ensure-target-triggering-enforcement
Sep 21, 2026
Merged

pelikhan merged 6 commits into
mainfrom
copilot/ensure-target-triggering-enforcement

Conversation

Copilot AI commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Several safe-output handlers selected model-provided IDs before applying their configured target, allowing operations to escape the default triggering item or a fixed numeric target. link-sub-issue also dropped its parsed target during handler configuration.

Changes

  • Target enforcement

    • Apply target before model-provided IDs across merge, comment, close, review, assignment, milestone, and issue-field handlers.
    • Preserve explicit and temporary IDs only for target: "*".
    • Keep omitted targets equivalent to target: triggering.
  • Boundary validation

    • Validate hide-comment targets against the comment’s parent item and repository.
    • Enforce fixed and triggering targets for pull-request review threads, including legacy same-repository mode.
    • Reject review-thread operations without a triggering PR when using the default target.
  • Sub-issue configuration

    • Propagate link-sub-issue.target into runtime configuration.
    • Apply the target to the parent issue while retaining the model-provided sub-issue.
    • Enforce same-repository parent/sub-issue relationships.
  • Compiler validation

    • Register target validation for unassign-from-user, set-issue-type, set-issue-field, and resolve-pull-request-review-thread.
safe-outputs:
  close-issue:
    target: triggering # model-provided issue numbers are ignored
  assign-milestone:
    target: "123"      # always targets issue #123
  add-reviewer:
    target: "*"        # model-provided PR numbers are allowed

pr-sous-chef
Run: https://github.com/github/gh-aw/actions/runs/35656487865

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 27.7 AIC · ⊞ 9.6K · ◷
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Enforce configured targets in safe output handlers Enforce configured targets in safe-output handlers Sep 21, 2026
Copilot AI requested a review from pelikhan September 21, 2026 19:15
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot update safe-outputs specification and specification enforcing scripts

@github-actions

Copy link
Copy Markdown
Contributor

Great work on this security boundary hardening! 🎯 The safe-output target enforcement refactor looks solid — consistent application of target validation across merge, comment, close, review, assignment, milestone, and issue-field handlers, plus rigorous boundary checks for cross-repository and review-thread operations.

The changes are well-focused (35 files covering a single concern), comprehensive, and include test coverage. This is ready for review by the maintainers.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

Generated by ✅ Contribution Check · copilot · auto · 50.1 AIC · ⌖ 13.5 AIC · ⊞ 9.2K · ◷

@pelikhan
pelikhan marked this pull request as ready for review September 21, 2026 21:03
Copilot AI balanced review requested due to automatic review settings September 21, 2026 21:03

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.

Copilot review overview

🟡 Changes recommended

Target enforcement still has parent-type, forwarded-context, effective sub-issue, and PR-assignment correctness gaps.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 High severity · 4 Medium severity

Open (5)
What changed in this PR

Enforces configured safe-output targets before model-provided IDs and strengthens comment, review-thread, and sub-issue boundaries.

Changes:

  • Applies target resolution consistently across issue and pull-request handlers.
  • Adds parent/repository validation for comments, review threads, and sub-issues.
  • Expands compiler validation and regression coverage.
File Description
pkg/​workflow/​safe_outputs_validation.go Expands target validation.
pkg/​workflow/​safe_outputs_target_validation_test.go Tests added validators.
pkg/​workflow/​safe_outputs_handler_registry_issues.go Propagates sub-issue target.
pkg/​workflow/​link_sub_issue_handler_config_test.go Tests target propagation.
actions/​setup/​js/​unassign_from_user.test.cjs Updates target tests.
actions/​setup/​js/​unassign_from_user.cjs Enforces assignment target.
actions/​setup/​js/​set_issue_type.test.cjs Updates target scenarios.
actions/​setup/​js/​set_issue_type.cjs Enforces issue-type target.
actions/​setup/​js/​set_issue_field.test.cjs Updates target scenarios.
actions/​setup/​js/​set_issue_field.cjs Enforces issue-field target.
actions/​setup/​js/​safe_output_helpers.cjs Clarifies target API documentation.
actions/​setup/​js/​resolve_pr_review_thread.test.cjs Tests thread boundaries.
actions/​setup/​js/​resolve_pr_review_thread.cjs Enforces review-thread targets.
actions/​setup/​js/​merge_pull_request.test.cjs Updates merge target setup.
actions/​setup/​js/​merge_pull_request.cjs Enforces merge target.
actions/​setup/​js/​mark_pull_request_as_ready_for_review.test.cjs Updates ready-for-review tests.
actions/​setup/​js/​mark_pull_request_as_ready_for_review.cjs Enforces PR target.
actions/​setup/​js/​link_sub_issue.test.cjs Tests sub-issue targeting.
actions/​setup/​js/​link_sub_issue.cjs Targets parent issue.
actions/​setup/​js/​hide_comment.test.cjs Tests parent lookup behavior.
actions/​setup/​js/​hide_comment.cjs Validates comment parent.
actions/​setup/​js/​close_pull_request.test.cjs Updates close-PR tests.
actions/​setup/​js/​close_pull_request.cjs Enforces close-PR target.
actions/​setup/​js/​close_issue.test.cjs Updates close-issue tests.
actions/​setup/​js/​close_issue.cjs Enforces close-issue target.
actions/​setup/​js/​assign_to_user.test.cjs Updates assignment tests.
actions/​setup/​js/​assign_to_user.cjs Enforces assignee target.
actions/​setup/​js/​assign_to_agent.test.cjs Updates agent target tests.
actions/​setup/​js/​assign_to_agent.cjs Enforces agent target.
actions/​setup/​js/​assign_milestone.test.cjs Updates milestone tests.
actions/​setup/​js/​assign_milestone.cjs Enforces milestone target.
actions/​setup/​js/​add_reviewer.test.cjs Updates reviewer tests.
actions/​setup/​js/​add_reviewer.cjs Enforces reviewer target.
actions/​setup/​js/​add_comment.test.cjs Updates comment target tests.
actions/​setup/​js/​add_comment.cjs Enforces comment target.

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

Comment thread actions/setup/js/hide_comment.cjs Outdated
Comment on lines +221 to +224
let expectedNumber;
if (targetConfig === "triggering") {
const invocationContext = resolveInvocationContext(context);
expectedNumber = invocationContext.eventPayload?.issue?.number ?? invocationContext.eventPayload?.pull_request?.number ?? invocationContext.eventPayload?.discussion?.number;

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 de83120: resolveCommentNodeId() now tracks the resolved parent's kind ("issue" or "discussion") alongside its number, and the target: "triggering" check rejects mismatches between the two independent numbering sequences.

// Defer if issue_number is a temporary ID that hasn't been resolved yet
// Strip leading '#' so both 'aw_abc1' and '#aw_abc1' (canonical validator form) are handled
if (message.issue_number != null) {
if (targetConfig === "*" && message.issue_number != null) {

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 de83120: the issue_number/pull_number mutual-exclusivity check now only runs when targetConfig === "*".

Comment on lines 158 to +174
const subIssueNumber = subResolved.resolved?.number;
const parentTarget = resolveTarget({
targetConfig,
item: targetItem,
context,
itemType: HANDLER_TYPE,
supportsIssue: true,
});
if (!parentTarget.success) {
return {
parent_issue_number: item.parent_issue_number,
sub_issue_number: item.sub_issue_number,
success: false,
error: parentTarget.error,
};
}
const parentIssueNumber = parentTarget.number;

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 de83120: added a post-target-resolution check that rejects when the effective parent/sub-issue numbers are equal, instead of only validating the raw model-provided parent.

Comment on lines +440 to +445
if (resolveTarget === "triggering") {
if (!triggeringPRNumber) {
core.warning("Cannot resolve review thread: not running in a pull request context");
return {
success: false,
error: repoValidation.error,
error: "Cannot resolve review threads outside of a pull request context",

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 de83120: triggeringPRNumber is now derived from resolveInvocationContext(context).eventPayload so forwarded invocations (workflow_dispatch/aw_context, repository_dispatch) are correctly recognized.

Comment thread actions/setup/js/unassign_from_user.cjs Outdated
item: unassignItem,
context,
itemType: HANDLER_TYPE,
supportsIssue: true,

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 de83120: switched to the helper's both-issue-and-PR mode (supportsPR: true) so the default target continues to work for triggering PRs.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

pr-sous-chef
@copilot This PR still needs forward progress before a maintainer can merge it.

Please address the open review follow-ups below, refresh the branch if needed, and then run the pr-finisher skill.

Open review follow-ups (newest first):

I also requested a branch refresh for this PR.
Run: https://github.com/github/gh-aw/actions/runs/35656487865

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 27.7 AIC · ⊞ 9.6K · ◷
Comment /souschef to run again

Comment on lines +221 to +245
let expectedNumber;
if (targetConfig === "triggering") {
const invocationContext = resolveInvocationContext(context);
expectedNumber = invocationContext.eventPayload?.issue?.number ?? invocationContext.eventPayload?.pull_request?.number ?? invocationContext.eventPayload?.discussion?.number;
if (!expectedNumber) {
return {
success: false,
error: 'Target is "triggering" but not running in issue, pull request, or discussion context',
};
}
} else if (targetConfig !== "*") {
expectedNumber = Number(targetConfig);
if (!Number.isInteger(expectedNumber) || expectedNumber <= 0) {
return {
success: false,
error: `Invalid target configuration: ${targetConfig}`,
};
}
}
if (expectedNumber && resolvedComment.itemNumber !== expectedNumber) {
return {
success: false,
error: `Comment belongs to item #${resolvedComment.itemNumber}, but target is #${expectedNumber}`,
};
}

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.

Addressed in de83120 and reinforced by e5380ea: hide_comment now validates the resolved comment parent kind as well as repository/number, and the shared target regression suite/conformance checks cover configured-target enforcement.

…get Authorization sections

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

Copy link
Copy Markdown
Collaborator

@copilot update safe-outputs specification and specification enforcing scripts

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor Author

@copilot update safe-outputs specification and specification enforcing scripts

Updated the safe-output specification and added enforcement tests for set_issue_type and set_issue_field in 7664e4e.

@copilot update safe-outputs specification and specification enforcing scripts

Updated the safe-output specification and added enforcement tests for set_issue_type and set_issue_field in 7664e4e.

pr-sous-chef
@copilot This PR still needs forward progress before a maintainer can merge it.
...

Ran the PR-finisher pass. Local validation is green; existing Copilot review threads already have substantive responses but remain unresolved, and the current GitHub Advanced Security check is still in progress.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot ensure systematic test suite and fail safe runtime assertion to prevent regression

Copilot AI and others added 2 commits September 21, 2026 22:31
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot ensure systematic test suite and fail safe runtime assertion to prevent regression

Implemented in e5380ea/700589a: added systematic safe-output target authorization conformance checks, updated the safe-outputs spec to require target regression testing, and added a fail-safe runtime target authorization invariant with shared JS regression coverage. Local final validation passed (make agent-report-progress).

@pelikhan
pelikhan merged commit abc510c into main Sep 21, 2026
45 checks passed
@pelikhan
pelikhan deleted the copilot/ensure-target-triggering-enforcement branch September 21, 2026 23:18
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.89.20

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.

5 participants