Skip to content

Docs: safe-outputs.app: permission narrowing + (?) implicit permission inflation #15274

@Yoyokrazy

Description

@Yoyokrazy

Created w Copilot :copilot: to poke around the codebase a bit to see how things worked under the hood for token minting. Less sure about the second point, might've missed something when looking around.

Two related but distinct issues with safe-outputs.app: token handling.


1. Undocumented permission narrowing

safe-outputs.app: automatically narrows minted GitHub App tokens per-job, but this is undocumented. The only mention of permission narrowing is under GH_AW_GITHUB_MCP_SERVER_TOKEN, which describes MCP server tokens — not safe-outputs tokens.

Users configuring app: for cross-repo operations have no way to know from the docs that:

  1. Each job mints its own independently-scoped token via actions/create-github-app-token with explicit permission-* fields
  2. Token permissions are narrowed to match the job's permissions: block
  3. Tokens are explicitly revoked at job end via DELETE /installation/token
  4. A shared org-wide GitHub App is safe to use because tokens are narrowed per-job

Relevant code

Docs to update

  • Safe Outputs — app: — Document the per-job narrowing, auto-revocation, and that a broadly-permissioned App is safe due to per-job scoping.
  • Tokens — Generalize the "permissions matching" statement to cover all app: configs, not just MCP server tokens.
  • Frontmatter Reference — Note that permissions are auto-narrowed per-job and tokens are auto-revoked.

2. create-pull-request hardcodes issues: write

For a workflow that only configures create-pull-request:, the compiled safe_outputs job mints a token with: permission-contents: write, permission-issues: write, permission-pull-requests: write.

The issues: write is hardcoded in the create-pull-request handler — see compiler_safe_outputs_job.go L201-202 (ContentsWriteIssuesWritePRWrite). This is because create-pull-request falls back to creating an issue if PR creation fails (e.g., org settings block it).

This is surprising when you expect only contents: write + pull-requests: write for a PR-only workflow — and there's no way to opt out.

Suggestions

  • Document which permissions each safe output type implicitly adds (a table in the Safe Outputs docs would help)
  • Consider making the fallback-to-issue opt-out-able, so users who don't need it can avoid issues: write

Relevant code

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions