Skip to content

safe_outputs minted App token caps issues:* permission at workflow-level value, blocking add-comment / add-labels #30392

@norrietaylor

Description

@norrietaylor

Symptom

Workflow with safe-outputs.github-app: configured + add-comment and add-labels handlers fails at runtime: Resource not accessible by integration on the comment-create and label-add API calls.

Diagnosis

The minted installation token's permission-issues is read instead of write, even though the configured safe-output handlers (add-comment, add-labels) require write. Compiled lock.yml excerpt from the safe_outputs job:

- name: Generate GitHub App token
  uses: actions/create-github-app-token@v1
  with:
    permission-contents: read
    permission-issues: read           # ← should be write
    permission-organization-projects: write
    permission-pull-requests: write

Source pointer: pkg/workflow/safe_outputs_app_config.go::convertPermissionsToAppTokenFields reads a Permissions object and emits permission-* mint args. The Permissions object passed for the safe_outputs job appears to inherit from the workflow-level permissions: block rather than being computed from the configured safe-output handlers' actual scope needs.

Minimal repro

---
on: { issues: { types: [opened] } }
permissions:
  contents: read
  issues: read   # required: a separate validator rejects `issues: write`
                 # on the agent job when add-comment/add-labels are
                 # configured below ("The agent job must not have write
                 # permissions...All writes must go through safe-outputs").
engine: claude
safe-outputs:
  github-app:
    app-id: ${{ vars.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
    owner: my-org
  add-comment:
    max: 1
    issues: true
    pull-requests: false
    discussions: false
  add-labels:
    max: 4
    allowed: [routed]
---
You are a comment bot. On the triggering issue, post "hello" and apply
the `routed` label.

Compile, run on a fresh issue, observe Resource not accessible by integration from add-comment + add-labels.

Workarounds tried (none accepted)

  1. safe-outputs.github-app.permissions: { issues: write } — schema rejects: Unknown property: issues. 'issues' belongs under 'safe-outputs/add-comment', 'on/status-comment' or 'on/permissions'.
  2. safe-outputs.github-app.permissions: { permission-issues: write } — schema rejects: Unknown property: permission-issues.
  3. Workflow permissions: { issues: write } — validator (independent of strict mode) rejects: The agent job must not have write permissions. All writes must go through safe-outputs.
  4. add-comment.issues: true (boolean handler-level toggle) — already set; doesn't lift the cap.
  5. strict: false in frontmatter — disables strict mode, but the agent-permissions validator above runs unconditionally and still rejects issues: write.

The agent-no-write rule and the safe_outputs cap are mutually exclusive: the rule forces the workflow to declare issues: read, which then caps the safe_outputs job's mint to issues: read, which prevents add-comment / add-labels from working.

Expected behaviour

The safe_outputs job's permission-* mint args should be derived from the union of (a) the configured safe-output handlers' actually-required scopes — add-commentissues:write, add-labelsissues:write, etc. — and (b) the github-app permissions: overrides — NOT capped by the agent job's permissions: block.

Without that, safe-outputs.github-app: is non-functional for any workflow that uses both add-comment/add-labels AND the agent-no-write rule (which is most of them; the rule defaults on).

Suggested fixes (any one)

  1. Fix permission inference (preferred): the safe_outputs job's permission-* args come from the union of declared handlers' needs + github-app overrides, ignoring the agent's permissions block. (The agent-no-write rule already enforces the agent's read-only stance independently.)
  2. Document & accept a safe-outputs.github-app.permissions: key format that the JSON schema validator allows, so operators can override the cap manually. Today the parsed GitHubAppConfig.Permissions field is documented in source as "extra permission-* fields to merge into the minted token (nested wins over job-level)" but no key shape is accepted.
  3. Add a strict-mode-permissions: false opt-out that disables the agent-no-write rule for workflows that have audited the agent's tool surface (e.g., no bash: tool exposed) and accept the wider workflow-level permissions:.

(Fix 1 is the cleanest — removes a class of trap; fix 2 unblocks operators today; fix 3 is the escape valve.)

Environment

  • gh-aw v0.71.1
  • actions/create-github-app-token@v1 (action SHA 1b10c78c7865c340bc4f6099eb2f838309f1e8c3)
  • Strict mode default-on; tested also with strict: false (no effect on this validator)

Context

Caught while migrating an internal routing-agent workflow from a long-lived classic-PAT (WORKFLOW_TRIGGER_TOKEN) to a short-lived App installation token via safe-outputs.github-app:. The migration is otherwise clean — update-project and a custom safe-outputs.jobs.transfer-issue: (calling transferIssue GraphQL) both work correctly under the App token. Only add-comment and add-labels fail because of the issues:* cap.

Falling back to the PAT for this workflow's safe-outputs as a workaround. Glad to test fix candidates.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions