From d4f142d24c7d566c6c2bea88d73b4b2719704810 Mon Sep 17 00:00:00 2001 From: Tamir Dresher Date: Tue, 9 Jun 2026 13:57:20 +0300 Subject: [PATCH] ci(Squad.Agents.AI): switch NuGet publish to Trusted Publishing (OIDC) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the long-lived NUGET_API_KEY repo secret with NuGet/login@v1 OIDC token exchange (1-hour API key) per the modern Trusted Publishing flow: https://learn.microsoft.com/nuget/nuget-org/trusted-publishing Why --- - No long-lived credentials stored in the repo. - Token is scoped to this workflow + repo + branch via the OIDC subject claim and the Trusted Publishing policy registered on nuget.org. - Eliminates the chicken-and-egg between needing admin to set NUGET_API_KEY and needing the package live to validate the workflow. What changed ------------ - Add `id-token: write` to the publish job (required for OIDC). - Drop the `Verify NuGet API key` step. - Drop the `--api-key ` reference to secrets.NUGET_API_KEY. - Add `NuGet/login@v1` step that exchanges the OIDC token for a short-lived API key, exposed via `steps.nuget-login.outputs.NUGET_API_KEY`. - Add a fail-fast check for the new `vars.NUGET_USER` repository variable (non-sensitive; the nuget.org profile name that performs the exchange). - Update the file header documentation to reflect the new flow and link to the Trusted Publishing setup page. Required configuration before first publish ------------------------------------------- 1. Create the `Squad` organization on nuget.org and add owners. 2. Configure a Trusted Publishing policy at https://www.nuget.org/account/trusted-publishing owned by the Squad org: Repository Owner: bradygaster Repository: squad Workflow File: squad-agents-ai-release.yml Environment: (empty) 3. Set repository variable NUGET_USER (Settings → Secrets and variables → Actions → Variables) to a Squad-org-member's nuget.org profile name (NOT email). Variable, not secret — the username is non-sensitive. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/squad-agents-ai-release.yml | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/.github/workflows/squad-agents-ai-release.yml b/.github/workflows/squad-agents-ai-release.yml index 22c04533c..cf84a2d89 100644 --- a/.github/workflows/squad-agents-ai-release.yml +++ b/.github/workflows/squad-agents-ai-release.yml @@ -1,4 +1,17 @@ -# Requires repo secret NUGET_API_KEY. Generate at nuget.org → API Keys → Create. +# Publishes Squad.Agents.AI to NuGet.org via Trusted Publishing (OIDC). +# +# ## Authentication +# No long-lived API key is stored. The job uses GitHub Actions OIDC to obtain a +# short-lived (1 hour) NuGet API key via the NuGet/login@v1 action. A Trusted +# Publishing policy must be configured at https://www.nuget.org/account/trusted-publishing +# under the package owner (Squad organization) with: +# Repository Owner: bradygaster +# Repository: squad +# Workflow File: squad-agents-ai-release.yml +# Environment: (leave empty) +# Set repository variable NUGET_USER to the nuget.org profile name that should +# perform the token exchange (a member of the Squad org). Use a variable, not a +# secret — the username is non-sensitive. # # ## Failure recovery # Publishing is branch-driven: dev creates prerelease NuGet packages, main creates stable NuGet @@ -38,6 +51,9 @@ jobs: publish: name: Pack and publish NuGet package runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # Required for OIDC token issuance to NuGet/login concurrency: group: squad-agents-ai-release-${{ github.ref }} cancel-in-progress: false @@ -116,14 +132,14 @@ jobs: echo "PACKAGE_VERSION=${package_version}" >> "${GITHUB_OUTPUT}" echo "Resolved PACKAGE_VERSION=${package_version} (${version_source})" - - name: Verify NuGet API key + - name: Verify NUGET_USER variable shell: bash env: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + NUGET_USER: ${{ vars.NUGET_USER }} run: | set -euo pipefail - if [[ -z "${NUGET_API_KEY}" ]]; then - echo "::error::Missing repo secret NUGET_API_KEY. Generate at nuget.org → API Keys → Create, then add it as a repository secret." + if [[ -z "${NUGET_USER}" ]]; then + echo "::error::Missing repository variable NUGET_USER. Set it under Settings → Secrets and variables → Actions → Variables to the nuget.org profile name (NOT email) of a Squad org member that will perform the OIDC token exchange. Configure the matching Trusted Publishing policy at https://www.nuget.org/account/trusted-publishing." exit 1 fi @@ -153,8 +169,14 @@ jobs: path: nupkgs/* if-no-files-found: ignore + - name: NuGet login (OIDC → temp API key) + id: nuget-login + uses: NuGet/login@v1 + with: + user: ${{ vars.NUGET_USER }} + - name: Push to NuGet.org shell: bash env: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} - run: dotnet nuget push nupkgs/*.nupkg --source https://api.nuget.org/v3/index.json --api-key "${NUGET_API_KEY}" --skip-duplicate + NUGET_TEMP_KEY: ${{ steps.nuget-login.outputs.NUGET_API_KEY }} + run: dotnet nuget push nupkgs/*.nupkg --source https://api.nuget.org/v3/index.json --api-key "${NUGET_TEMP_KEY}" --skip-duplicate