|
| 1 | +--- |
| 2 | +author: Melvin Wang @wmmc88 |
| 3 | +created on: 2026-02-09 |
| 4 | +last updated: 2026-02-26 |
| 5 | +issue id: 5949 |
| 6 | +--- |
| 7 | + |
| 8 | +# Authenticated GitHub API Requests for PowerShell Module |
| 9 | + |
| 10 | +For [#5949](https://github.com/microsoft/winget-cli/issues/5949). |
| 11 | + |
| 12 | +## Abstract |
| 13 | + |
| 14 | +This spec describes adding support for authenticated GitHub API requests in the WinGet PowerShell module. The module's `GitHubClient` helper will automatically detect `GH_TOKEN` or `GITHUB_TOKEN` environment variables and use them to authenticate Octokit API calls, significantly increasing the GitHub API rate limit. |
| 15 | + |
| 16 | +## Inspiration |
| 17 | + |
| 18 | +Users running `Repair-WinGetPackageManager` in GitHub Actions pipelines hit unauthenticated rate limits (60 requests/hour). Authenticated requests allow 5,000 requests/hour. The GitHub CLI (`gh`) already uses `GH_TOKEN` and `GITHUB_TOKEN` for the same purpose, and GitHub Actions automatically provides `GITHUB_TOKEN`. |
| 19 | + |
| 20 | +See: https://github.com/microsoft/windows-drivers-rs/actions/runs/20531244312/job/58982795057#step:3:43 |
| 21 | + |
| 22 | +## Solution Design |
| 23 | + |
| 24 | +The `GitHubClient` class in `Microsoft.WinGet.Client.Engine` is updated to: |
| 25 | + |
| 26 | +1. Read all known token environment variables (`GH_TOKEN`, `GITHUB_TOKEN`) on construction. |
| 27 | +2. Log the presence or absence of each token via `StreamType.Verbose`. |
| 28 | +3. Select the token to use based on precedence (`GH_TOKEN` > `GITHUB_TOKEN`), matching GitHub CLI behavior. |
| 29 | +4. Log which token source is being used, or that no token was found. |
| 30 | +5. Set `Octokit.GitHubClient.Credentials` if a token is available. |
| 31 | + |
| 32 | +Token resolution is extracted into a static `ResolveGitHubToken` method for testability. |
| 33 | + |
| 34 | +### Token Precedence |
| 35 | + |
| 36 | +`GH_TOKEN` takes precedence over `GITHUB_TOKEN`, matching the [GitHub CLI convention](https://cli.github.com/manual/gh_help_environment). This is because `GH_TOKEN` is explicitly set by users, while `GITHUB_TOKEN` is automatically provided by GitHub Actions and may have more restricted permissions. |
| 37 | + |
| 38 | +### Logging |
| 39 | + |
| 40 | +All logging uses `StreamType.Verbose` via the existing `PowerShellCmdlet.Write` pattern, visible when users pass `-Verbose` to cmdlets. Example output: |
| 41 | + |
| 42 | +``` |
| 43 | +VERBOSE: GH_TOKEN environment variable: not found |
| 44 | +VERBOSE: GITHUB_TOKEN environment variable: found |
| 45 | +VERBOSE: Using authenticated GitHub API requests via GITHUB_TOKEN environment variable. |
| 46 | +``` |
| 47 | + |
| 48 | +### Files Changed |
| 49 | + |
| 50 | +- `src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/GitHubClient.cs` — Token resolution logic and logging. |
| 51 | +- `src/PowerShell/Microsoft.WinGet.Client.Engine/Properties/AssemblyInfo.cs` — `InternalsVisibleTo` for unit tests. |
| 52 | +- `src/PowerShell/Microsoft.WinGet.Client.Engine/Commands/WinGetPackageManagerCommand.cs` — Pass `PowerShellCmdlet` to `GitHubClient` constructor. |
| 53 | +- `src/PowerShell/Microsoft.WinGet.Client.Engine/Helpers/AppxModuleHelper.cs` — Pass `PowerShellCmdlet` to `GitHubClient` constructor. |
| 54 | +- `src/PowerShell/Microsoft.WinGet.UnitTests/GitHubClientTests.cs` — Unit tests for token resolution. |
| 55 | + |
| 56 | +## UI/UX Design |
| 57 | + |
| 58 | +No new command-line arguments or user-facing changes. The feature is automatic: if `GH_TOKEN` or `GITHUB_TOKEN` is set in the environment, authenticated requests are used. Users can see which token is being used by running any repair/assert cmdlet with `-Verbose`. |
| 59 | + |
| 60 | +### Accessibility |
| 61 | + |
| 62 | +No impact on accessibility. |
| 63 | + |
| 64 | +### Security |
| 65 | + |
| 66 | +- Tokens are never logged or written to output; only the environment variable name is logged. |
| 67 | +- Token values are read from environment variables which are a standard secure mechanism for passing secrets in CI/CD environments. |
| 68 | +- Whitespace-only token values are treated as unset to prevent accidental empty-credential authentication. |
| 69 | + |
| 70 | +### Reliability |
| 71 | + |
| 72 | +Improves reliability by reducing GitHub API rate limit failures in CI/CD pipelines. Unauthenticated requests are still used as a fallback when no tokens are set. |
| 73 | + |
| 74 | +### Compatibility |
| 75 | + |
| 76 | +Fully backward compatible. When no token environment variables are set, behavior is identical to the previous implementation. |
| 77 | + |
| 78 | +### Performance, Power, and Efficiency |
| 79 | + |
| 80 | +No measurable impact. A single environment variable read per `GitHubClient` construction. |
| 81 | + |
| 82 | +## Potential Issues |
| 83 | + |
| 84 | +- If a user has an expired or revoked token in `GH_TOKEN`/`GITHUB_TOKEN`, API calls will fail with a 401 rather than falling back to unauthenticated. This matches GitHub CLI behavior and is the expected outcome. |
| 85 | + |
| 86 | +## Future considerations |
| 87 | + |
| 88 | +- Support for additional token sources (e.g., `gh auth token` integration, Windows Credential Manager). |
| 89 | +- Applying authenticated requests to other parts of the WinGet client beyond the PowerShell module. |
| 90 | + |
| 91 | +## Resources |
| 92 | + |
| 93 | +- [GitHub API rate limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api) |
| 94 | +- [GitHub CLI environment variables](https://cli.github.com/manual/gh_help_environment) |
| 95 | +- [Octokit.NET authenticated access](https://octokitnet.readthedocs.io/en/latest/getting-started/#authenticated-access) |
| 96 | +- [Issue #5949](https://github.com/microsoft/winget-cli/issues/5949) |
0 commit comments