Skip to content

Comments

Fix push-to-pull-request-branch requesting unnecessary issues:write permission#16342

Merged
pelikhan merged 3 commits intomainfrom
copilot/fix-push-to-pr-branch-permissions
Feb 17, 2026
Merged

Fix push-to-pull-request-branch requesting unnecessary issues:write permission#16342
pelikhan merged 3 commits intomainfrom
copilot/fix-push-to-pr-branch-permissions

Conversation

Copy link
Contributor

Copilot AI commented Feb 17, 2026

Plan: Fix push-to-pull-request-branch unconditionally requesting issues:write

  • Understand the issue and codebase
    • Locate the permissions computation in safe_outputs_permissions.go
    • Understand how create-pull-request handles fallback-as-issue setting
    • Review existing tests for permissions
  • Fix the code
    • Update computePermissionsForSafeOutputs to use NewPermissionsContentsWritePRWrite() for push-to-pull-request-branch
    • Remove issues: write from push-to-pull-request-branch permissions
  • Update tests
    • Update push_to_pull_request_branch_test.go to verify correct permissions (remove issues:write check)
    • Add test case to safe_outputs_permissions_test.go for push-to-pull-request-branch
  • Validate changes
    • Run selective tests for modified code
    • Build and verify compiled workflow output
    • Verify both job-level and GitHub App token permissions are correct
    • Test with workflow containing both push-to-pull-request-branch and create-pull-request with fallback-as-issue: false
    • Format code and recompile all workflows

Summary

Fixed push-to-pull-request-branch safe output to only request contents: write and pull-requests: write permissions instead of unconditionally requesting issues: write.

Changes Made:

  1. pkg/workflow/safe_outputs_permissions.go: Changed push-to-pull-request-branch to use NewPermissionsContentsWritePRWrite() instead of NewPermissionsContentsWriteIssuesWritePRWrite()
  2. pkg/workflow/push_to_pull_request_branch_test.go: Updated test to verify that issues: write should NOT be present
  3. pkg/workflow/safe_outputs_permissions_test.go: Added test case explicitly verifying push-to-pull-request-branch only requires contents: write and pull-requests: write
  4. Workflow lock files: Recompiled 5 workflows that use push-to-pull-request-branch to remove issues: write permission

Verification:

  • All 16 push-to-pull-request-branch tests pass
  • All 21 permissions computation tests pass
  • Compiled workflows show correct permissions (no issues: write)
  • Both job-level and GitHub App token permissions are minimal
  • Recompilation updated 5 workflow lock files: changeset, contribution-check, issue-monster, mergefest, workflow-generator
Original prompt

This section details on the original issue you should resolve

<issue_title>push-to-pull-request-branch safe output unconditionally requests issues: write</issue_title>
<issue_description>## Problem

The compiled .lock.yml for a workflow using only push-to-pull-request-branch safe output unconditionally requests issues: write permission — both in the job's permissions: block and via permission-issues: write on the GitHub App token step.

This requires the GitHub App installation to have issues: write granted, even though push-to-pull-request-branch only pushes commits to an existing PR branch and has no reason to create or modify issues.

Unlike create-pull-request, which has a documented fallback-to-issue behavior (and now supports fallback-as-issue: false per #15274), push-to-pull-request-branch does not accept fallback-as-issue — attempting to set it produces:

error: Unknown property: fallback-as-issue. Valid fields are: branch, commit-title-suffix, github-token, if-no-changes, labels, staged, target, title-prefix

Reproduction

  1. Create a workflow with only push-to-pull-request-branch:
---
name: Example
on:
  pull_request:
    types: [opened, synchronize]
    paths:
      - some/file.tf

safe-outputs:
  app:
    app-id: ${{ vars.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
  push-to-pull-request-branch:
---
# My Workflow
Push changes to the PR branch.
  1. Compile: gh aw compile
  2. Observe the compiled .lock.yml contains:
    permissions:
      contents: write
      issues: write        # <-- not needed
      pull-requests: write

    steps:
      - name: Generate GitHub App token
        uses: actions/create-github-app-token@...
        with:
          permission-contents: write
          permission-issues: write        # <-- not needed
          permission-pull-requests: write

Impact

If the GitHub App installation does not have issues: write granted, the safe outputs job fails with:

RequestError [HttpError]: The permissions requested are not granted to this installation.

Expected behavior

push-to-pull-request-branch should only request contents: write and pull-requests: write (to push to the branch and interact with the PR). There is no issue-related fallback behavior for this safe output type, so issues: write should not be required.

Related

Version

gh aw version: v0.45.4
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…ll-requests:write

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix permissions for push-to-pull-request-branch safe output Fix push-to-pull-request-branch requesting unnecessary issues:write permission Feb 17, 2026
Copilot AI requested a review from pelikhan February 17, 2026 13:33
@pelikhan
Copy link
Contributor

@copilot format and recompile

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

Copilot AI commented Feb 17, 2026

@copilot format and recompile

Done. Formatted code and recompiled all workflows. The recompilation updated 5 workflow lock files to remove issues: write permission from jobs using push-to-pull-request-branch. (0311b16)

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw Plw-4Nq/U0ke7I_e-C (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw _value&#34;].&#34;\n&#34;; (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v2
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v2 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/11bd71901bbe5b1630ceea73d27597364c9af683 --jq .object.sha (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha t} (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha on&#39; --ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha on&#39; --ignore-path ../../../.pret.prettierignore (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v7
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v7 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v7 --jq .object.sha on&#39; --ignore-patremote.origin.url (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/4dc6199c7b1a012772edbd06daecab0f50c9053c --jq .object.sha on&#39; --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v5 --jq .object.sha js/**/*.json&#39; ---p (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v5 --jq .object.sha js/**/*.json&#39; --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha h ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha t} (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha h ../../../.pret.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq .object.sha t} (http block)
  • https://api.github.com/repos/anchore/sbom-action/git/ref/tags/v0
    • Triggering command: /usr/bin/gh gh api /repos/anchore/sbom-action/git/ref/tags/v0 --jq .object.sha on&#39; --ignore-patremote.origin.url (http block)
    • Triggering command: /usr/bin/gh gh api /repos/anchore/sbom-action/git/ref/tags/v0 --jq .object.sha on&#39; --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/docker/build-push-action/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/docker/build-push-action/git/ref/tags/v6 --jq .object.sha on&#39; --ignore-patremote.origin.url (http block)
    • Triggering command: /usr/bin/gh gh api /repos/docker/build-push-action/git/ref/tags/v6 --jq .object.sha on&#39; --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/docker/login-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq .object.sha on&#39; --ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq .object.sha on&#39; --ignore-pat-delete (http block)
  • https://api.github.com/repos/docker/metadata-action/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/docker/metadata-action/git/ref/tags/v5 --jq .object.sha on&#39; --ignore-patremote.origin.url (http block)
  • https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha on&#39; --ignore-patremote.origin.url (http block)
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha on&#39; --ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/c4e091835c7a94dc7d3acb8ed3ae145afb4995f3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/c4e091835c7a94dc7d3acb8ed3ae145afb4995f3 --jq .object.sha (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/-
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/- --jq .object.sha (http block)
  • https://api.github.com/user
    • Triggering command: /usr/bin/gh gh api user --jq .login (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@pelikhan pelikhan marked this pull request as ready for review February 17, 2026 13:51
Copilot AI review requested due to automatic review settings February 17, 2026 13:51
@pelikhan pelikhan merged commit 7d21e80 into main Feb 17, 2026
91 checks passed
@pelikhan pelikhan deleted the copilot/fix-push-to-pr-branch-permissions branch February 17, 2026 13:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an issue where the push-to-pull-request-branch safe output unconditionally requested issues: write permission even though it only pushes commits to PR branches and doesn't create or modify issues.

Changes:

  • Updated permission requirements for push-to-pull-request-branch to only request contents: write and pull-requests: write
  • Added comprehensive test coverage to verify the correct permissions
  • Recompiled affected workflow lock files to remove unnecessary issues: write permission

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
pkg/workflow/safe_outputs_permissions.go Changed push-to-pull-request-branch to use NewPermissionsContentsWritePRWrite() instead of NewPermissionsContentsWriteIssuesWritePRWrite()
pkg/workflow/push_to_pull_request_branch_test.go Updated test to verify that issues: write should NOT be present in generated workflow
pkg/workflow/safe_outputs_permissions_test.go Added explicit test case verifying push-to-pull-request-branch only requires contents and pull-requests write permissions
.github/workflows/changeset.lock.yml Recompiled workflow - removed issues: write from safe_outputs and conclusion jobs
.github/workflows/mergefest.lock.yml Recompiled workflow - removed issues: write from safe_outputs and conclusion jobs
.github/workflows/contribution-check.lock.yml Recompiled workflow - includes unrelated side effect from recompilation (additional env vars for pre_activation outputs)
.github/workflows/issue-monster.lock.yml Recompiled workflow - includes unrelated side effect from recompilation (assign_to_agent tool description update for pull_request_repo parameter)
.github/workflows/workflow-generator.lock.yml Recompiled workflow - includes unrelated side effect from recompilation (assign_to_agent tool description update for pull_request_repo parameter)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

push-to-pull-request-branch safe output unconditionally requests issues: write

2 participants