Migrate To NuGet Trusted Publishing (OIDC)

by Alex Johnson 43 views

Securing your NuGet package publishing process is crucial in today's development landscape. This article guides you through migrating from the traditional API key method to NuGet.org's trusted publishing feature, leveraging OpenID Connect (OIDC) for enhanced security and streamlined workflows. The main goal is to remove the reliance on static NUGET_API_KEY stored as repository secrets, replacing it with a more secure approach where authentication is directly linked to the repository and workflow file. This transition not only reduces the risk of compromised API keys but also simplifies the management of your NuGet package publishing.

Official Documentation: https://learn.microsoft.com/en-us/nuget/nuget-org/trusted-publishing

Acceptance Criteria (To-Do)

Let's break down the migration process into manageable steps.

1. Configure nuget.org

Configuring NuGet.org is the first critical step in transitioning to trusted publishing. This involves setting up your account to recognize and trust your GitHub repository and workflow. First, you'll need to log in to your NuGet.org account, ensuring you have ownership of the packages you intend to publish. Navigate to the Manage Account section and find the Trusted Publishers option. Here, you'll add a new trusted publisher, which essentially creates a link between your NuGet account and your GitHub repository. The details you'll need to provide include the GitHub Owner (your GitHub username or organization name), the GitHub Repository name, and the path to your GitHub workflow file responsible for publishing the NuGet packages. An important note: the GitHub environment field should be left blank. Finally, you'll associate the specific packages from your repository, such as ByteAether.Ulid, with this new trusted publisher. This configuration ensures that only your specified GitHub workflow can publish these packages, thereby preventing unauthorized uploads and enhancing the security of your NuGet packages. Make sure every step is performed to avoid errors during the publishing process.

  • [ ] Go to nuget.org and log in to the account that owns the package(s).
  • [ ] Navigate to Manage Account e Trusted Publishers.
  • [ ] Add a new trusted publisher with the following details:
    • GitHub Owner: ByteAether
    • GitHub Repository: Ulid
    • GitHub workflow: .github/workflows/publish-nuget.yml
    • GitHub environment: Leave this field blank.
  • [ ] Add the package(s) from this repository (e.g., ByteAether.Ulid) to the new trusted publisher.

2. Update GitHub Actions Workflow

Updating your GitHub Actions workflow is a pivotal step in transitioning to NuGet.org trusted publishing. This involves modifying your workflow file to utilize OIDC for authentication, eliminating the need for the conventional API key. Begin by locating the publish job within your .github/workflows/publish-nuget.yml file. Introduce a permissions block to this job, specifying the necessary permissions for the workflow. Specifically, you'll grant id-token: write to enable the workflow to request an OIDC token, and contents: read to allow the workflow to read the repository's contents. Next, find the "Publish to NuGet" step in your workflow. This is where you'll make a critical change: remove the --api-key ${{ secrets.NUGET_API_KEY }} argument from the dotnet nuget push command. This removal is essential because you're now relying on OIDC for authentication instead of the API key. By removing the API key argument, you're instructing the dotnet nuget push command to use the OIDC token for authentication, which is automatically provided by GitHub Actions. This ensures that your NuGet packages are published securely and without the need to manage sensitive API keys directly.

  • [ ] In .github/workflows/publish-nuget.yml, find the publish job.
  • [ ] Add the permissions block to this job. The workflow should look like this:
```yaml
jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:                 # Add this block
      id-token: write
      contents: read

    steps:
    - name: Checkout code
      # ... rest of the steps ...
```
  • [ ] Find the "Publish to NuGet" step.
  • [ ] Remove the --api-key ${{ secrets.NUGET_API_KEY }} argument from the dotnet nuget push command.
**Before:**

```yaml
- name: Publish to NuGet
  run: dotnet nuget push ./output/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json
```

**After:**

```yaml
- name: Publish to NuGet
  run: dotnet nuget push ./output/*.nupkg --source https://api.nuget.org/v3/index.json
```

3. Verification

Verification is a crucial step to ensure that the migration to NuGet.org trusted publishing has been successful. This process involves confirming that your GitHub Actions workflow is correctly configured to publish NuGet packages using OIDC. Begin by merging the changes you've made to your workflow file into your main branch. This will trigger the release workflow, which you can also manually initiate using the workflow_dispatch trigger. Next, navigate to the "Actions" tab in your GitHub repository to monitor the workflow's execution. Ensure that the workflow runs successfully, paying close attention to the "Publish to NuGet" step. Examine the workflow logs for this step to confirm that it completed without any errors. Successful completion of this step indicates that the OIDC authentication is working as expected. Finally, verify that the new package version is visible on NuGet.org. This confirms that your package has been successfully published using the new trusted publishing method. If you encounter any issues during this verification process, double-check your configuration settings and workflow file to ensure everything is correctly set up.

  • [ ] Merge the workflow changes.
  • [ ] Trigger the release workflow (either by publishing a new release or using workflow_dispatch).
  • [ ] Go to the "Actions" tab and confirm the workflow runs successfully.
  • [ ] Check the workflow logs for the "Publish to NuGet" step to ensure it completed without errors.
  • [ ] Verify the new package version is visible on nuget.org.

4. Cleanup

Cleaning up old secrets after successfully migrating to NuGet.org Trusted Publishing is an essential security practice. With the new OIDC-based publishing method in place, the NUGET_API_KEY is no longer needed and should be removed to prevent any potential misuse. To do this, navigate to the Settings > Secrets and variables > Actions section of your GitHub repository. Here, you'll find a list of all the secrets stored for your repository. Locate the NUGET_API_KEY secret and delete it. This ensures that the API key cannot be accidentally used or compromised, further enhancing the security of your NuGet package publishing process. Regularly reviewing and cleaning up unused secrets is a good practice to maintain a secure development environment.

  • [ ] After verifying the new publishing method works, go to Settings Secrets and variables Actions.
  • [ ] Delete the old NUGET_API_KEY repository secret.

By following these steps, you'll successfully migrate to NuGet.org's trusted publishing feature, enhancing the security and efficiency of your NuGet package publishing process.

For more in-depth information, see the official Microsoft documentation on NuGet Trusted Publishing.