We’re excited to announce Trusted Publishing on nuget.org — a simpler, safer way to publish NuGet packages from GitHub Actions. Rather than relying on long‑lived API keys, your workflow can use a short‑lived GitHub OIDC token to request a temporary, single‑use NuGet API key. These keys expire quickly (≈ 1 hour), eliminating long‑lived secrets that need to be stored, rotated, or protected from leaks.
👉 Read the docs at aka.ms/nuget/trusted-publishing
Why Trusted Publishing? 🔒
- No long‑lived secrets — nothing sensitive stored in your repository or CI.
- Short‑lived credentials — temporary API keys are issued just‑in‑time and typically last about 1 hour.
- One token → one key — each job’s OIDC token maps to a single temporary API key used for that publish.
Getting started 🚀
- Open the Trusted Publishing page Sign in to nuget.org → open your user menu (top right) → Trusted Publishing (next to API Keys).
- Create a policy
- Package owner: you or your organization
- Repository owner / repository: your GitHub org/user and repository name (for example
contoso-sdk
) - Workflow file: the YAML file in
.github/workflows/
(for examplerelease.yml
) - (Optional) Environment: if your workflow uses GitHub Actions environments
- Wire up your GitHub Actions workflow using the minimal example below.
Minimal GitHub Actions example ⚙️
This example includes only the steps that interact with nuget.org: enabling OIDC, exchanging the token for a temporary API key, and pushing the package.
permissions:
id-token: write # required for GitHub OIDC
jobs:
build-and-publish:
permissions:
id-token: write # enable GitHub OIDC token issuance for this job
steps:
# Build your artifacts/my-sdk.nupkg package here
# Get a short-lived NuGet API key
- name: NuGet login (OIDC → temp API key)
uses: NuGet/login@v1
id: login
with:
# Recommended: use a secret like ${{ secrets.NUGET_USER }} for your nuget.org username (profile name), NOT your email address
user: contoso-bot
# Push the package
run: dotnet nuget push artifacts/my-sdk.nupkg --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json
How it works 🔁
- GitHub issues an OIDC token to the job.
- The NuGet login step sends that token to nuget.org.
- nuget.org validates the token against your Trusted Publishing policy and returns a temporary API key.
- Your workflow uses that key to publish. Request the key immediately before running
dotnet nuget push
— it expires quickly (≈ 1 hour).
Policy ownership & lifecycle 📜
- Private repo bootstrap (7 days, re-activate anytime). New policies for private repositories start out as active for 7 days by default. After the first successful NuGet login (the exchange of a job’s OIDC token for a temporary API key), the policy becomes permanently active and is bound to immutable GitHub IDs. If you miss the initial 7‑day window, you can manually re‑activate the policy for another 7 days from the Trusted Publishing page. A successful NuGet login is sufficient — you don’t need to publish a package.
- Owner matters. A policy is owned by a user or organization and applies only to packages owned by that owner.
- Org changes are respected. If the policy creator loses org membership, or the org is locked or deleted, the policy is disabled and displays a clear warning. When membership or org access is restored, the policy re‑activates automatically.
Migrating from long‑lived API keys 🔄
Already publishing from GitHub Actions? Switching is easy:
- Create a Trusted Publishing policy on nuget.org.
- Remove stored NuGet API keys from your repo or CI secrets.
- Add
NuGet/login@v1
to your workflow and use its output key withdotnet nuget push
. - Done — enjoy, no more key management!
Try it today 🚀
- Read the docs at aka.ms/nuget/trusted-publishing
- Sign in to nuget.org → Trusted Publishing (next to API Keys) and create your first policy.
Huge thanks to OpenSSF and the Securing Software Repos working group for defining the Trusted Publishing guidelines and encouraging their adoption throughout the broader ecosystem.
Publish more securely and with less friction — thank you for contributing to the NuGet community. ✨
Great to see this! Any word on support for other repository hosting sites and CI runners, such as GitLab or Azure DevOps?
Glad you’re excited! Expanding to other CI runners like GitLab is definitely on our radar. If this is something you’d like to see, please open an issue here: https://github.com/NuGet/NuGetGallery/issues. Upvotes help us figure out what to prioritize next!
For everyone else using GitLab -> https://github.com/NuGet/NuGetGallery/issues/10583