You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Creates PRs with code changes. Falls back to issue if creation fails (e.g., org settings block it). `expires` field (same-repo only) auto-closes after period: integers (days) or `2h`, `7d`, `2w`, `1m`, `1y` (hours < 24 treated as 1 day).
631
+
Creates PRs with code changes. By default, falls back to creating an issue if PR creation fails (e.g., org settings block it). Set `fallback-as-issue: false` to disable this fallback and avoid requiring `issues: write` permission. `expires` field (same-repo only) auto-closes after period: integers (days) or `2h`, `7d`, `2w`, `1m`, `1y` (hours < 24 treated as 1 day).
632
632
633
633
```yaml wrap
634
634
safe-outputs:
@@ -641,6 +641,7 @@ safe-outputs:
641
641
if-no-changes: "warn" # "warn" (default), "error", or "ignore"
642
642
target-repo: "owner/repo" # cross-repository
643
643
base-branch: "vnext" # target branch for PR (default: github.ref_name)
The `base-branch` field specifies which branch the pull request should target. This is particularly useful for cross-repository PRs where you need to target non-default branches (e.g., `vnext`, `release/v1.0`, `staging`). When not specified, defaults to the workflow's branch (`github.ref_name`).
@@ -656,7 +657,7 @@ safe-outputs:
656
657
```
657
658
658
659
> [!NOTE]
659
-
> PR creation may fail if "Allow GitHub Actions to create and approve pull requests" is disabled in Organization Settings. Fallback creates issue with branch link.
660
+
> PR creation may fail if "Allow GitHub Actions to create and approve pull requests" is disabled in Organization Settings. By default (`fallback-as-issue: true`), fallback creates an issue with branch link and requires `issues: write` permission. Set `fallback-as-issue: false` to disable fallback and only require `contents: write` + `pull-requests: write`.
660
661
661
662
### Close Pull Request (`close-pull-request:`)
662
663
@@ -1336,6 +1337,20 @@ safe-outputs:
1336
1337
create-issue:
1337
1338
```
1338
1339
1340
+
#### How GitHub App Tokens Work
1341
+
1342
+
When you configure `app:` for safe outputs, tokens are **automatically managed per-job** for enhanced security:
1343
+
1344
+
1. **Per-job token minting**: Each safe output job automatically mints its own token via `actions/create-github-app-token` with permissions explicitly scoped to that job's needs
1345
+
2. **Permission narrowing**: Token permissions are narrowed to match the job's `permissions:` block - only the permissions required for the safe outputs in that job are granted
1346
+
3. **Automatic revocation**: Tokens are explicitly revoked at job end via `DELETE /installation/token`, even if the job fails
1347
+
4. **Safe shared configuration**: A broadly-permissioned GitHub App can be safely shared across workflows because tokens are narrowed per-job
1348
+
1349
+
> [!TIP]
1350
+
> **Why this matters**: You can configure a single GitHub App at the organization level with broad permissions (e.g., `contents: write`, `issues: write`, `pull-requests: write`), and each workflow job will only receive the specific subset of permissions it needs. This provides least-privilege access without requiring per-workflow App configuration.
1351
+
1352
+
**Example**: If your workflow only uses `create-issue:`, the minted token will have `contents: read` + `issues: write`, even if your GitHub App has broader permissions configured.
Copy file name to clipboardExpand all lines: docs/src/content/docs/reference/tokens.mdx
+4-1Lines changed: 4 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -232,7 +232,9 @@ gh aw secrets set APP_PRIVATE_KEY --value "$(cat path/to/private-key.pem)"
232
232
233
233
**How it works**:
234
234
235
-
At workflow start, a token is automatically minted with permissions matching your agent job's `permissions:` field. The token is passed to the GitHub MCP server and automatically revoked at workflow end (even on failure).
235
+
At workflow start, a token is automatically minted with **permissions matching your job's `permissions:` field**. The token is passed to the GitHub MCP server and automatically revoked at workflow end (even on failure).
236
+
237
+
This is the same per-job narrowing behavior used by `safe-outputs.app:` - see the [Safe Outputs documentation](/gh-aw/reference/safe-outputs/#github-app-token-app) for a detailed explanation of how GitHub App tokens are narrowed per-job.
236
238
237
239
**Token precedence and fallback**:
238
240
@@ -243,6 +245,7 @@ At workflow start, a token is automatically minted with permissions matching you
243
245
- The compiler automatically sets `GITHUB_MCP_SERVER_TOKEN` and passes it as `GITHUB_PERSONAL_ACCESS_TOKEN` (local/Docker) or an `Authorization: Bearer` header (remote).
244
246
- In most cases, you do not need to set this token separately. Use `GH_AW_GITHUB_TOKEN` instead.
245
247
- **GitHub App advantages**: Short-lived tokens (auto-revoked at workflow end), no credential rotation needed, automatic permission calculation, better auditability.
248
+
- **Per-job permission narrowing**: When using a GitHub App (via `tools.github.app:` or `safe-outputs.app:`), tokens are automatically narrowed to match the job's `permissions:` block. This means you can safely configure a broadly-permissioned GitHub App at the organization level, and each job will only receive the specific permissions it needs.
246
249
- If using a GitHub App for both safe-outputs and GitHub MCP server, you can configure them independently for different permission levels.
247
250
- Set the resource owner to the organization when the repository is organization-owned.
248
251
- `GITHUB_TOKEN`is not supported in remote mode. Use `GH_AW_GITHUB_TOKEN` or a GitHub App instead.
0 commit comments