From f914ffdfd749f2b40d69d9ea6bf76a17b425f4f4 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 19 Aug 2026 16:48:08 +0700 Subject: [PATCH 1/3] Migrate NuGet publishing to trusted publishing (OIDC) Replace the long-lived NuGet API key secret with short-lived, OIDC-issued credentials via NuGet trusted publishing: - Add id-token: write permission for GitHub OIDC token issuance - Add a NuGet/login@v1 step that exchanges the OIDC token for a short-lived API key (username from the NUGET_USER secret) - Push using the short-lived key instead of secrets.SILLSDEV_PUBLISH_NUGET_ORG The login step currently runs on every build (no gating condition) to validate the trusted publishing policy end-to-end; it will be restored to run only on publish once confirmed working. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/nuget-ci-cd.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nuget-ci-cd.yml b/.github/workflows/nuget-ci-cd.yml index ee26299..e6333b7 100644 --- a/.github/workflows/nuget-ci-cd.yml +++ b/.github/workflows/nuget-ci-cd.yml @@ -12,6 +12,7 @@ jobs: build: permissions: packages: write + id-token: write # enable GitHub OIDC token issuance for NuGet trusted publishing runs-on: ubuntu-latest steps: @@ -48,6 +49,12 @@ jobs: name: nuget-packages path: src/artifacts/package/release/*nupkg + - name: NuGet login + id: nuget-login + uses: NuGet/login@v1 + with: + user: ${{ secrets.NUGET_USER }} + - name: Publish package to NuGet.org if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) shell: bash @@ -83,4 +90,4 @@ jobs: --source https://api.nuget.org/v3/index.json done env: - NUGET_API_KEY: ${{ secrets.SILLSDEV_PUBLISH_NUGET_ORG }} + NUGET_API_KEY: ${{ steps.nuget-login.outputs.NUGET_API_KEY }} From 4de18277ef3dfe95d0475faa6d7e6461e1cb9d5e Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 19 Aug 2026 17:21:19 +0700 Subject: [PATCH 2/3] Gate NuGet login step to publish conditions Trusted publishing was verified, so restore the if-condition on the NuGet login step to match the publish step (push to main or a v* tag). The short-lived key is now only requested when a publish will actually occur. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/nuget-ci-cd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nuget-ci-cd.yml b/.github/workflows/nuget-ci-cd.yml index e6333b7..46800aa 100644 --- a/.github/workflows/nuget-ci-cd.yml +++ b/.github/workflows/nuget-ci-cd.yml @@ -51,6 +51,7 @@ jobs: - name: NuGet login id: nuget-login + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) uses: NuGet/login@v1 with: user: ${{ secrets.NUGET_USER }} From adcff715b6fd6ffe780294853c5825ee642a98c9 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 19 Aug 2026 17:22:49 +0700 Subject: [PATCH 3/3] Pin NuGet/login action to commit SHA Address CodeRabbit feedback: pin NuGet/login to the immutable commit SHA for v1.2.0 instead of the mutable @v1 tag, so a compromised or retagged action can't silently change what runs. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/nuget-ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nuget-ci-cd.yml b/.github/workflows/nuget-ci-cd.yml index 46800aa..f713577 100644 --- a/.github/workflows/nuget-ci-cd.yml +++ b/.github/workflows/nuget-ci-cd.yml @@ -52,7 +52,7 @@ jobs: - name: NuGet login id: nuget-login if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) - uses: NuGet/login@v1 + uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0 with: user: ${{ secrets.NUGET_USER }}