ci: publish to NuGet.org via Trusted Publishing instead of an API key - #54
Merged
Conversation
The 2.0.1 publish failed with 403 "The specified API key is invalid, has expired, or does not have permission" - NUGET_API_KEY aged out. Last successful publish was 2025-07-25 and nuget.org caps API keys at 365 days, so it expired almost to the day. nuget.org now also marks API keys "Not recommended" and steers key creation towards Trusted Publishing, so rotating was not the obvious path anyway. Trusted Publishing exchanges a GitHub OIDC token for a short-lived nuget.org key, which removes the whole class of failure: nothing to rotate, store or leak. This is the second credential of that vintage to die silently in this repo - GIST_SECRET has been returning 401 for the badge pipeline since the same week. The job gains id-token: write, a NuGet/login@v1 step runs immediately before the push (the temporary key is valid for one hour), and its output replaces the secret in the existing --package-secret argument. The Cake task is unchanged, and it already pushes to https://api.nuget.org/v3/index.json. The GitHub Packages path still uses GITHUB_TOKEN and is untouched. Requires the trusted publishing policy on nuget.org: package owner LocalStack.NET, repository localstack-dotnet/localstack-dotnet-client, workflow publish-nuget.yml, no environment. That policy is active.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 Description
Replaces the long-lived
NUGET_API_KEYwith Trusted Publishing (GitHub OIDC → short-lived nuget.org key) for the NuGet.org publish path.Why now. The v2.0.1 publish failed with:
NUGET_API_KEYhad aged out. The last successful publish was 2025-07-25 and nuget.org caps API keys at 365 days, so it expired almost to the day. nuget.org now also marks API keys "Not recommended" and routes key creation towards Trusted Publishing, so rotating was not the straightforward path anyway.This is the second credential of that vintage to die silently in this repo —
GIST_SECREThas been returning401for the badge pipeline since the same week, which is why the README test badges have served July 2025 numbers ever since. Trusted Publishing removes the whole class: nothing to rotate, store, or leak.🔄 Type of Change
What changed
id-token: writeadded to thepublish-manualjob permissions.NuGet/login@v1step runs immediately before the push — the temporary key is valid for one hour, so requesting it early would risk expiry.--package-secretargument.The Cake
nuget-pushtask is unchanged — it already pushes tohttps://api.nuget.org/v3/index.json. The GitHub Packages path still usesGITHUB_TOKENand is untouched.Required nuget.org policy
Already created and active:
LocalStack.NETlocalstack-dotnet(#50793344)localstack-dotnet-client(#187457001)publish-nuget.ymlNote the two distinct owners: the package owner on nuget.org is
LocalStack.NET, while the repository owner islocalstack-dotnet. Using the latter for both would produce a policy that does not cover these packages.🧪 Verification
Proven end-to-end before merge, not after:
LocalStack.Client.Extensions2.0.1 was published to nuget.org by this exact workflow, run from this branch.Two things the docs left ambiguous, now settled by that run:
user:for an organization-owned policy — neither the Microsoft docs nor theNuGet/loginREADME says whether this is the individual account or the org. The individual account name (localstack-dotnet) is correct.🔍 Notes
NUGET_API_KEYis left in repo secrets deliberately — it is expired and unused, but removing it is a separate cleanup once this has a few releases behind it.