Skip to content

add-comment and hide-comment safe outputs unconditionally request discussions:write permission #16500

@benvillalobos

Description

@benvillalobos

🤖 AI Assisted Bug Report

Problem

PR #15518 (fixing #15516) introduced computePermissionsForSafeOutputs to compute minimal permissions for the safe_outputs and conclusion jobs. However, the add-comment and hide-comment entries still use NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite(), which unconditionally includes discussions: write — even when no discussion-related safe outputs (create-discussion, close-discussion, update-discussion) are configured.

This causes the same 422 error that #15516 reported:

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

…when the GitHub App installation doesn't have the Discussions permission granted.

Root Cause

In pkg/workflow/safe_outputs_permissions.go:

if safeOutputs.AddComments != nil {
    permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite())
    //                                                        ^^^^^^^^^^^^^^^^
    //                                              discussions: write always included
}
if safeOutputs.HideComment != nil {
    permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite())
    //                                              same problem
}

The rationale is that add_comment.cjs can comment on discussions, not just issues/PRs. But if no discussion-related safe-output is configured, the agent will never target a discussion, so discussions: write is unnecessary.

The same pattern also exists in pkg/workflow/add_comment.go L124 (standalone handler permissions).

Impact

Any workflow using add-comment or hide-comment with a GitHub App that doesn't have Discussions permission will fail at the token generation step in the safe_outputs and conclusion jobs. The agent job completes successfully, but its output (comments, labels, assignments) is never applied.

Affected compiled output (lock.yml):

  • Job-level permissions: block includes discussions: write
  • create-github-app-token step includes permission-discussions: write

Workaround: Manually remove discussions: write and permission-discussions: write from the compiled lock file after every gh aw compile.

Suggested Fix

In safe_outputs_permissions.go, use NewPermissionsContentsReadIssuesWritePRWrite() (already exists at permissions_factory.go L83) instead:

if safeOutputs.AddComments != nil {
    permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite())
}
if safeOutputs.HideComment != nil {
    permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite())
}

discussions: write is already independently added when discussion-related safe outputs are configured:

if safeOutputs.CreateDiscussions != nil {
    permissions.Merge(NewPermissionsContentsReadIssuesWriteDiscussionsWrite())
}
if safeOutputs.CloseDiscussions != nil {
    permissions.Merge(NewPermissionsContentsReadDiscussionsWrite())
}
if safeOutputs.UpdateDiscussions != nil {
    permissions.Merge(NewPermissionsContentsReadDiscussionsWrite())
}

So workflows that actually use discussions will still get the permission via those entries.

Same fix should be applied to add_comment.go L124 for the standalone handler path.

Reproduction

  1. Create a workflow with add-comment but no discussion safe-outputs:
safe-outputs:
  app:
    app-id: ${{ secrets.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
    owner: 'myorg'
    repositories: ['myrepo']
  add-comment:
    target: "*"
    max: 1
  1. Use a GitHub App that does NOT have the Discussions permission
  2. gh aw compile
  3. Observe discussions: write in the lock file's safe_outputs and conclusion jobs
  4. Run the workflow — token generation fails with 422

Environment

Related

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions