feat: add GitHub App-only permissions support#21511
Conversation
- Add 35 GitHub App-only PermissionScope constants (administration, members, organization-administration, secrets, environments, workflows, git-signing, vulnerability-alerts, repository-hooks, single-file, codespaces, dependabot-secrets, organization-hooks, organization-members, organization-packages, organization-secrets, organization-custom-org-roles, organization-custom-properties, organization-custom-repository-roles, organization-announcement-banners, organization-events, organization-plan, organization-user-blocking, organization-personal-access-token-requests, organization-personal-access-tokens, organization-copilot, organization-codespaces, email-addresses, codespaces-lifecycle-admin, codespaces-metadata, codespaces-secrets, repository-custom-properties, organization-administration, team-discussions, organization-self-hosted-runners) - Move organization-projects from GitHub Actions scopes to GitHub App-only scopes - Add GetAllGitHubAppOnlyScopes() and IsGitHubAppOnlyScope() functions - Update RenderToYAML() to skip GitHub App-only scopes using IsGitHubAppOnlyScope() - Update convertPermissionsToAppTokenFields() to map all new App-only permissions - Update PermissionsConfig struct and parser/serializer with all new fields - Add validateGitHubAppOnlyPermissions() validation requiring github-app config - Register new validation in compiler pipeline - Add comprehensive tests for all new functionality - Fix test counts for write-all shorthand expansion Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…oryCustomProperties Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
pkg/workflow/frontmatter_types.go
Outdated
| // Supports both shorthand (read-all, write-all) and detailed scope-based permissions. | ||
| // In addition to standard GitHub Actions scopes, this also supports GitHub App-only scopes | ||
| // (e.g., members, administration) for use when a GitHub App is configured. | ||
| type PermissionsConfig struct { |
There was a problem hiding this comment.
@create two types with inheritance to maintain them separate
There was a problem hiding this comment.
Done in 7fc28c6. PermissionsConfig now embeds two separate types:
GitHubActionsPermissionsConfig— standard GITHUB_TOKEN scopesGitHubAppPermissionsConfig— GitHub App-only scopes
Field access is unchanged via Go embedding promotion.
|
@copilot Review comments |
There was a problem hiding this comment.
Pull request overview
Adds support for declaring GitHub App-only permission scopes in the workflow permissions: configuration, ensuring those scopes are omitted from the rendered GitHub Actions YAML but are forwarded to actions/create-github-app-token, and enforcing validation that a GitHub App is configured when such scopes are used.
Changes:
- Expanded
PermissionScopeto include many GitHub App-only scopes and added helpers to classify them. - Updated YAML rendering and GitHub App token minting to handle GitHub App-only scopes appropriately.
- Added compiler-time validation (with tests) requiring a GitHub App configuration when GitHub App-only scopes are declared.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/safe_outputs_app_config.go | Maps permissions (including App-only scopes) into permission-* inputs for actions/create-github-app-token. |
| pkg/workflow/permissions_operations.go | Skips GitHub App-only scopes during permissions: YAML rendering via IsGitHubAppOnlyScope. |
| pkg/workflow/permissions.go | Adds GitHub App-only scopes, lists, and IsGitHubAppOnlyScope() helper. |
| pkg/workflow/github_app_permissions_validation.go | New validation requiring GitHub App configuration when App-only scopes are used. |
| pkg/workflow/github_app_permissions_validation_test.go | New tests for App-only scope classification, rendering, conversion, and validation behavior. |
| pkg/workflow/frontmatter_types.go | Extends typed permissions config parsing/serialization to include App-only scopes. |
| pkg/workflow/compiler.go | Wires the new App-only permissions validation into compilation. |
| pkg/workflow/permissions_operations_test.go | Updates merge tests to reflect organization-projects reclassification and scope lists. |
| pkg/workflow/dangerous_permissions_validation_test.go | Adjusts expected write-scope count after scope list changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| // Find any GitHub App-only permission scopes that are set | ||
| var appOnlyScopes []PermissionScope | ||
| for _, scope := range GetAllGitHubAppOnlyScopes() { | ||
| if _, exists := permissions.Get(scope); exists { |
| @@ -245,11 +245,120 @@ func convertPermissionsToAppTokenFields(permissions *Permissions) map[string]str | |||
| fields["permission-discussions"] = string(level) | |||
| // GitHub Actions permission scopes (supported by GITHUB_TOKEN) | ||
| case "actions": | ||
| return PermissionActions |
| // Skip GitHub App-only permissions - they are not valid GitHub Actions workflow permissions | ||
| // and cannot be set on the GITHUB_TOKEN. They are handled separately when minting | ||
| // GitHub App installation access tokens. | ||
| if IsGitHubAppOnlyScope(scope) { | ||
| continue | ||
| } |
… and GitHubAppPermissionsConfig Respond to code review feedback: use two separate embedded types to clearly separate GitHub Actions GITHUB_TOKEN scopes from GitHub App-only scopes. PermissionsConfig now embeds both, preserving all existing field access patterns. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot keep working |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot Keep working |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot keep working |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
All four review issues are now addressed in commit
|
|
@copilot remove secrets related permissions, like organization secrets, dependabot secrets, ... Show full list of permissions. |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in Full remaining GitHub App-only permission scopes: Repository-level: Organization-level: User-level: |
|
@copilot ensure that write permissions are properly flagged and refused. |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in
Attempting to set any of these to All other GitHub App-only scopes (e.g., |
|
@copilot refuse all write permissions always. Writes are done through safe outputs. |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in Removed the intermediate |
|
@copilot use the technical-doc-writer agent to update the docs |
Add a new '### GitHub App-Only Permissions' section to the permissions reference documenting scopes that cannot be set on GITHUB_TOKEN. These scopes are omitted from the compiled permissions block and forwarded to actions/create-github-app-token when a GitHub App is configured. Cover: full scope list by level, read-only constraint, github-app configuration requirement, and shorthand exemption. Also update the Write Permission Policy exceptions list to mention that GitHub App-only scopes always refuse write at compile time. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Done in
Also updated the Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
* docs: add GH_HOST and RUNNER_TEMP to glossary (daily scan 2026-03-18) (#21553) * docs: update GHES CLI docs and add Copilot GHES troubleshooting guide (#21528) * Fix list height not updating on terminal resize (#21555) * fix(daily-workflow-updater): unblock PR creation by setting protected-files: allowed (#21554) * chore: bump MCP Gateway v0.1.15→v0.1.17 (#21552) * feat: custom Huh theme mapped from pkg/styles Dracula palette (#21557) * Add top-level `github-app` frontmatter as universal fallback for token minting (#21510) * feat: add GitHub App-only permissions support (#21511) * fix: fall back to existing remote tracking ref when incremental patch fetch fails (#21568) * Add weekly blog post writer agentic workflow (#21575) * ci: add timeout-minutes to all 25 jobs lacking explicit limits (#21601) * fix: add setupGlobals in generate_aw_info step to fix staged mode ReferenceError (#21602) * Disable lockdown mode for weekly blog post generator (#21598) * fix: replace git push with GraphQL signed commits to satisfy required_signatures rulesets (#21576) * docs: add weekly update blog post for 2026-03-18 (#21608) Covers v0.58.0 through v0.61.0 (7 releases this week), notable PRs, and auto-triage-issues as Agent of the Week. Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix failing CI: merge main to include setupGlobals in generate_aw_info step and update golden files Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
…ains on data residency (#21527) * Initial plan * Fix threat detection AWF run missing --copilot-api-target and GHE domains on data residency When engine.api-target is configured for GHE Cloud with data residency, propagate the APITarget from the main engine config to the detection engine config so the threat detection AWF invocation receives the same --copilot-api-target flag and GHE-specific domains in --allow-domains. Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Add GITHUB_COPILOT_BASE_URL env var support and fix integration test api-target - Fix TestAPITargetDomainsInThreatDetectionStep to use api.contoso-aw.ghe.com (copilot-api. prefix does not trigger base-domain derivation in GetAPITargetDomains) - Add GetCopilotAPITarget() helper: resolves --copilot-api-target from engine.api-target (explicit) or GITHUB_COPILOT_BASE_URL in engine.env (fallback), mirroring the OPENAI_BASE_URL/ANTHROPIC_BASE_URL pattern for Codex/Claude - Update awf_helpers.go, copilot_engine_execution.go, and domains.go to use the helper - Add unit tests for GetCopilotAPITarget and engine execution step - Add integration test TestGitHubCopilotBaseURLInCompiledWorkflow - Update engines.md docs to document GITHUB_COPILOT_BASE_URL Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * Update DefaultMCPGatewayVersion to v0.1.17 and regenerate golden/lock files (#21609) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: merge main to resolve failing build-wasm and test CI jobs (#21612) * docs: add GH_HOST and RUNNER_TEMP to glossary (daily scan 2026-03-18) (#21553) * docs: update GHES CLI docs and add Copilot GHES troubleshooting guide (#21528) * Fix list height not updating on terminal resize (#21555) * fix(daily-workflow-updater): unblock PR creation by setting protected-files: allowed (#21554) * chore: bump MCP Gateway v0.1.15→v0.1.17 (#21552) * feat: custom Huh theme mapped from pkg/styles Dracula palette (#21557) * Add top-level `github-app` frontmatter as universal fallback for token minting (#21510) * feat: add GitHub App-only permissions support (#21511) * fix: fall back to existing remote tracking ref when incremental patch fetch fails (#21568) * Add weekly blog post writer agentic workflow (#21575) * ci: add timeout-minutes to all 25 jobs lacking explicit limits (#21601) * fix: add setupGlobals in generate_aw_info step to fix staged mode ReferenceError (#21602) * Disable lockdown mode for weekly blog post generator (#21598) * fix: replace git push with GraphQL signed commits to satisfy required_signatures rulesets (#21576) * docs: add weekly update blog post for 2026-03-18 (#21608) Covers v0.58.0 through v0.61.0 (7 releases this week), notable PRs, and auto-triage-issues as Agent of the Week. Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix failing CI: merge main to include setupGlobals in generate_aw_info step and update golden files Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> Co-authored-by: Landon Cox <landon.cox@microsoft.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The
permissions:block only supported GitHub Actions GITHUB_TOKEN scopes. There was no way to declare permissions likemembers,administration, orenvironmentsthat are exclusive to GitHub App installation tokens — and no validation requiring a GitHub App when such scopes are used.Changes
New GitHub App-only permission scopes
PermissionScopeconstants covering repository, organization, and user-level GitHub App permissions (e.g.,administration,members,environments,workflows,vulnerability-alerts,organization-members,team-discussions,codespaces, etc.)organization-projectsfrom the GitHub Actions scope list to GitHub App-only (it was already being silently dropped from YAML rendering; now correctly classified)secrets,dependabot-secrets,organization-secrets,codespaces-secrets) are intentionally excludedFull GitHub App-only scope list
Repository-level:
administration,environments,git-signing,vulnerability-alerts,workflows,repository-hooks,single-file,codespaces,repository-custom-propertiesOrganization-level:
organization-projects,members,organization-administration,team-discussions,organization-hooks,organization-members,organization-packages,organization-self-hosted-runners,organization-custom-org-roles,organization-custom-properties,organization-custom-repository-roles,organization-announcement-banners,organization-events,organization-plan,organization-user-blocking,organization-personal-access-token-requests,organization-personal-access-tokens,organization-copilot,organization-codespacesUser-level:
email-addresses,codespaces-lifecycle-admin,codespaces-metadataConfig types
PermissionsConfigembeds two separate types:GitHubActionsPermissionsConfig(standard GITHUB_TOKEN scopes) andGitHubAppPermissionsConfig(GitHub App-only scopes)Rendering
RenderToYAML()skips all GitHub App-only scopes (they can't be set onGITHUB_TOKEN) via the newIsGitHubAppOnlyScope()helper; returns""instead of a barepermissions:header when all scopes are skippedconvertPermissionsToAppTokenFields()maps all new scopes topermission-*inputs foractions/create-github-app-token, checking only explicitly-declared scopes (never shorthand-derived)Validation
github-appconfigured anywhere in the workflow (tools.github.github-app,safe-outputs.github-app, orgithub-app:)read-all,write-all,all: read) do NOT trigger this validationwriteis requested for any GitHub App-only scope — all GitHub App-only permissions must be declared asread; write operations are performed via safe-outputs, not through declared permissionsDocumentation
docs/src/content/docs/reference/permissions.mdwith a new### GitHub App-Only Permissionssection listing all scopes by level, explaining that they are omitted from the compiledpermissions:YAML and forwarded toactions/create-github-app-token, and documenting the compile-time validation rulesExample usage:
The
membersscope is omitted from the workflow'spermissions:YAML but passed aspermission-members: readwhen minting the App token.Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.