feat: support nuget.org Trusted Publishing via GitHub Actions OIDC#4884
feat: support nuget.org Trusted Publishing via GitHub Actions OIDC#4884
Conversation
- Wire up OIDC token exchange in PublishNuget.cs as primary publish path - Add catch-all Exception handler and use Warning for non-fatal OIDC errors - Add id-token: write permission to _publish.yml publish job - Remove 1Password NuGet creds step and NUGET_API_KEY env var - Document Trusted Publishing in CONTRIBUTING.md Co-authored-by: arturcic <[email protected]>
| run: dotnet run/publish.dll --target=Publish${{ matrix.taskName }} | ||
| env: | ||
| GITHUB_TOKEN: ${{ github.token }} | ||
| NUGET_API_KEY: ${{ steps.nuget-creds.outputs.nuget_api_key }} |
There was a problem hiding this comment.
@copilot if you remove this here, that means the fallback solution won't work
There was a problem hiding this comment.
Restored the nuget-creds step and NUGET_API_KEY env var in commit 22980a2. The fallback path in PublishNuget.cs reads NUGET_API_KEY from the environment, so both are needed for the fallback to work when OIDC is unavailable.
Without NUGET_API_KEY in the env, the fallback from OIDC to static API key in PublishNuget.cs was dead code. Restore the nuget-creds step and the env var so the fallback path is functional. Co-authored-by: arturcic <[email protected]>
…IBUTING.md Add step-by-step setup guide covering: - Enumerated list of the three packages that need configuration - Numbered steps to navigate nuget.org package settings - Lookup table with exact field values (owner, repo, workflow file, environment) - Warning note on exact-match OIDC claim requirement - Updated troubleshooting to mention 1Password fallback explicitly Co-authored-by: arturcic <[email protected]>
… not per package Co-authored-by: arturcic <[email protected]>
There was a problem hiding this comment.
Pull request overview
Updates the repository’s NuGet publishing guidance and pipeline to support nuget.org Trusted Publishing (OIDC-based short-lived API keys), while retaining a static API key fallback path for environments where OIDC/token exchange is unavailable.
Changes:
- Add OIDC-based NuGet API key retrieval (token exchange) with fallback to the configured static NuGet API key.
- Grant the publish reusable workflow the
id-token: writepermission required for GitHub OIDC. - Rewrite
CONTRIBUTING.mdrelease documentation to describe one-time Trusted Publisher setup on nuget.org.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| build/publish/Tasks/PublishNuget.cs | Prefer OIDC token exchange for nuget.org publishing, falling back to a static API key if needed. |
| CONTRIBUTING.md | Document repository/workflow-level nuget.org Trusted Publishing setup and troubleshooting. |
| .github/workflows/_publish.yml | Add job permissions needed to request an OIDC token during publishing. |
| // Prefer Trusted Publishing via OIDC token exchange (no long-lived API key required) | ||
| var apiKey = await GetNugetApiKey(context); | ||
|
|
||
| // Fall back to a static API key when OIDC is not available | ||
| if (string.IsNullOrEmpty(apiKey)) | ||
| { | ||
| context.Information("OIDC token exchange unavailable; falling back to static NuGet API key."); | ||
| apiKey = context.Credentials?.Nuget?.ApiKey; | ||
| } |
There was a problem hiding this comment.
The OIDC token exchange with static API key fallback was already implemented in PublishNuget.cs. Updated the PR description in commit 12f1b78 to accurately reflect both the pipeline changes (PublishNuget.cs, _publish.yml) and the documentation updates.
There was a problem hiding this comment.
The OIDC token exchange (with fallback to static NUGET_API_KEY) is implemented in build/publish/Tasks/PublishNuget.cs. Also added the missing using System.Text; import for Encoding.UTF8 in commit 12f1b78.
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
CONTRIBUTING.md
Outdated
| **Trusted Publishers**). | ||
| 3. Click **Add trusted publisher** and fill in the following fields: | ||
|
|
||
| | Field | Value | |
There was a problem hiding this comment.
Table columns are now aligned in commit 12f1b78.
| // Prefer Trusted Publishing via OIDC token exchange (no long-lived API key required) | ||
| var apiKey = await GetNugetApiKey(context); | ||
|
|
||
| // Fall back to a static API key when OIDC is not available | ||
| if (string.IsNullOrEmpty(apiKey)) | ||
| { | ||
| context.Information("OIDC token exchange unavailable; falling back to static NuGet API key."); | ||
| apiKey = context.Credentials?.Nuget?.ApiKey; | ||
| } |
…irective Co-authored-by: arturcic <[email protected]>
Co-authored-by: arturcic <[email protected]>
|
|
Thank you @Copilot for your contribution! |



Replaces long-lived NuGet API key dependency with OIDC-based Trusted Publishing, retaining the static key as a fallback.
Changes
build/publish/Tasks/PublishNuget.cs— On tagged releases, attempts OIDC token exchange with nuget.org before falling back toNUGET_API_KEY:Requests a GitHub OIDC token scoped to
https://www.nuget.org, then POSTs tohttps://www.nuget.org/api/v2/tokento exchange it for a short-lived API key..github/workflows/_publish.yml— Addsid-token: writepermission to the publish job; retainsnuget-credsstep andNUGET_API_KEYenv var for the fallback path.CONTRIBUTING.md— Rewrites the Trusted Publishing setup section: one entry per repository/workflow covers all packages; includes exact field values and navigation path for nuget.org setup.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.