Harden workflow credential selection#7249
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d9fa4e9c-c32d-42fb-8ee4-4772473e6479
There was a problem hiding this comment.
Pull request overview
This PR hardens repository automation by introducing a reusable composite action that selects a GitHub automation credential (GitHub App installation token preferred, with a PAT fallback) and updating multiple workflows to use the selected token while logging only the chosen source.
Changes:
- Added a new composite action (
.github/actions/github-app-token) to mint a GitHub App installation token via Azure Key Vault signing, with rollout modes and PAT fallback. - Updated issue/PR automation workflows to use the action output token and added OIDC permissions/environment binding.
- Added a Node test covering token/JWT construction and the GitHub installation token request payload.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/stale-issue-pr-ping.yml | Switch stale ping automation to consume the selected token via the new action. |
| .github/workflows/limit-community-prs.yml | Use selected token for team membership and PR limit enforcement (pull_request_target). |
| .github/workflows/label-pr.yml | Use selected token for label automation and breaking-change sync (pull_request_target). |
| .github/workflows/label-issues.yml | Use selected token for issue labeling automation. |
| .github/workflows/issue-triage.yml | Use selected token for triage/team membership checks. |
| .github/workflows/devflow-pr-review.yml | Use selected token for DevFlow PR review’s team membership gate. |
| .github/tests/test_create_github_app_token.js | Adds tests for JWT/signature conversion and installation token request construction. |
| .github/actions/github-app-token/create-token.js | Implements JWT construction, Key Vault signing, and installation token request. |
| .github/actions/github-app-token/action.yml | Defines the composite action flow (mode validation, Azure login, token creation, selection + logging). |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d9fa4e9c-c32d-42fb-8ee4-4772473e6479
There was a problem hiding this comment.
Automated Code Review
Reviewers: 5 | Confidence: 89%
✓ Correctness
The PR introduces a well-designed reusable credential-selection action with proper fallback logic, input validation, and security measures. The token creation logic correctly handles JWT construction, Azure Key Vault signing, and installation token requests. All workflows that run on pull_request_target correctly pin their checkout to the base SHA. The test coverage validates the key code paths. No correctness issues found.
✓ Security Reliability
The PR is well-designed from a security and reliability standpoint. Credential material is properly masked before output, the composite action's fallback state machine fails closed (hard failure when no token is available and mode is not fallback-capable), pull_request_target workflows correctly pin checkouts to the base SHA, and the token creation script uses execFileSync with argument arrays to prevent shell injection. All previously identified issues in the review thread have been addressed. No new security or reliability concerns found.
✓ Test Coverage
The test file covers the happy path and input validation well, and the new CI workflow ensures tests run on PR/push. However, several error-handling branches in create-token.js lack test coverage: the Key Vault empty-signature guard, the GitHub API HTTP failure path, and the empty-token validation. These are security-relevant error paths that could silently regress without dedicated assertions.
✓ Failure Modes
The credential selection mechanism is well-structured with proper fallback logic, safe checkout pining, and input validation. The one operational concern is that the bare catch in create-token.js discards all diagnostic context from failures, making it very difficult to determine root cause when the app credential path breaks. Since execFileSync pipes (rather than inherits) child stderr, Azure CLI error messages are also invisible.
✗ Design Approach
The rollout wiring is mostly solid, but two workflows now feed the new app token into team-membership checks that still treat any GitHub API failure as "not a team member." That undermines the stated fail-safe rollout goal: a permission gap or transient org/team lookup failure would silently misclassify internal contributors instead of surfacing the rollout problem or falling back.
Flagged Issues
- In
.github/workflows/devflow-pr-review.yml:99-121, the new token path can silently convert team-membership lookup failures intois_team_member=false, which skips review for internal PRs instead of failing safely during rollout. - In
.github/workflows/label-issues.yml:43plus.github/workflows/label-issues.yml:52-70, the new token path can silently convert team-membership lookup failures into "external author," causing internal issues to be mislabeled as community triage.
Automated review by moonbox3's agents
|
Flagged issue In Source: automated DevFlow PR review |
|
Flagged issue In Source: automated DevFlow PR review |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d9fa4e9c-c32d-42fb-8ee4-4772473e6479
|
Addressed both DevFlow flagged issues in ea5066c by routing the affected workflows through the existing fail-safe membership helper. Only a membership 404 is treated as “not a member”; authorization, team lookup, and transient API failures now fail the job. Added the remaining token error-path tests as well. |
Motivation & Context
Several repository automation workflows depend on a single credential acquisition path. This adds a staged selection mechanism with compatibility fallback so the updated path can be verified without interrupting issue and pull-request automation.
Description & Review Guide
Related Issue
Fixes #7248
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and the title prefix in sync automatically.