Skip to content

safe-outputs: update-project co-presence regresses handler-derived issues:write to issues:read in minted App token #30733

@norrietaylor

Description

@norrietaylor

Symptom

Workflow with safe-outputs.github-app: + add-comment + add-labels + update-project configured produces permission-issues: read in the minted App-token mint args. Without update-project, the same shape correctly produces permission-issues: write (per the fix landed in #30437 / v0.71.6).

Effect at runtime: add-comment and add-labels 403 with Resource not accessible by integration, identical to the pre-#30437 symptom on a more limited config.

Diagnosis

#30437 fixed handler-derived permission computation for the simpler case (add-comment + add-labels alone). Adding update-project re-caps the issues:* permission at the workflow-level value (which is forced to issues: read by the agent-no-write rule, same as the original #30392 case).

The schema-level escape hatch added in the same PR (safe-outputs.github-app.permissions:) is rejected by the validator when used with issues: — the schema treats issues as belonging only to safe-outputs/add-comment, on/status-comment, or on/permissions:

error: Unknown property: issues. 'issues' belongs under 'safe-outputs/add-comment', 'on/status-comment' or 'on'

So neither the handler-derived path nor the manual override path recovers issues: write when update-project is in the safe-outputs block.

Minimal repro (gh-aw v0.72.0)

---
on:
  issues:
    types: [opened]
permissions:
  contents: read
  issues: read   # forced by agent-no-write rule when add-comment is configured
engine: claude
safe-outputs:
  github-app:
    app-id: \${{ vars.APP_ID }}
    private-key: \${{ secrets.APP_PRIVATE_KEY }}
    owner: my-org
    repositories:
      - \${{ github.event.repository.name }}
  add-comment:
    issues: true
  add-labels:
    allowed: [routed]
  update-project:
    max: 1
    project: https://github.com/orgs/my-org/projects/1
---
hello

Compile and inspect the safe_outputs job's mint step:

gh aw compile --approve
grep 'permission-issues' .github/workflows/<name>.lock.yml

Result: permission-issues: read (expected: write).

Remove update-project: from the safe-outputs: block and recompile — permission-issues: write is correctly emitted. Behavior is reproducible: bisect via toggling only the update-project block.

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'.
  2. safe-outputs.github-app.permissions: { permission-issues: write } — schema rejects: Unknown property: permission-issues.
  3. safe-outputs.github-app.permissions: { members: read } — accepted (per docs example); does not change permission-issues, which stays read.
  4. Workflow-level permissions: { issues: write } — agent-no-write validator rejects: The agent job must not have write permissions. All writes must go through safe-outputs.

Asks

  1. Treat update-project's issues requirement (update-project writes to projects, not issues directly, but in the cap-computation path it appears to merge against the workflow-level issues: read rather than ignoring it). Either:
  2. Or: accept issues: under safe-outputs.github-app.permissions: as a manual override so workflows hitting this gap can recover.

References

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