NuGet Trusted Publishingが2025年9月22日に公開され、OpenID Connect (OIDC)を使ってトークンレスでCIからNuGetパッケージを公開できるようになりました。
- New Trusted Publishing enhances security on NuGet.org - .NET Blog
- Trusted Publishing on nuget.org - Microsoft Learn
今回は、NuGet Trusted Publishingを使ってGitHub ActionsからトークンレスでNuGetパッケージを公開するメリットと手順を解説します。NuGet Trusted Publishingは積極的に使っていきましょう。
NuGet Trusted Publishingとは
従来、NuGetパッケージを公開するには、APIキーを発行してdotnet nuget pushコマンドに渡す必要がありました。
このようなAPI認証はシンプルなため長年利用されてきましたが、ここ数年は複数の課題が指摘されています。
- APIキーが長期間有効であるため、漏洩リスクが高い
- APIキーのローテーションが手動であり、運用コストが高い (最長1年)
- CI/CD環境にAPIキーを安全に保存する必要がある
- APIキーが漏れたらだれでもどこからでもパッケージを公開できてしまう
APIキー認証の問題はNuGetに限らず、多くのパッケージシステムで共通した課題といえます。例えば利用者が特に多いnpmは、パッケージ作者から詐取したAPIキーを使ってマルウェア入りパッケージを公開する事件が何度も発生しています。npmにおけるパッケージAPI認証の課題に対するGitHubの対策は「TOTPからPasskeyベースへの移行 (認証のフィッシング対策強化)」と「OIDCを使ったトークンレスパッケージ公開(Trusted Publishing)」です。npmにおいてTrusted Publishingが先行していているので、本記事と合わせて読むと参考になる記事を紹介します
本記事で紹介するNuGet Trusted Publishingは、細かい違いはあるものの、おおむねnpm Trusted Publishingと同様の仕組みをNuGetに導入した考えて差し支えないでしょう。
OIDCを使ったトークンレスパッケージ公開は何を解決するのか
OIDCを使ったトークンレスパッケージ公開は、API管理を不要にすることが最大の利点です。「手元からパッケージ公開せず、基本的にパッケージ公開はCI/CDからのみ行う」、という前提を置く限りかなり有効な手法といえます。
- APIキーが短時間のみ有効な自動発行されたトークンに置き換わるため、漏洩時のリスクが大幅に低減される
- ユーザーによるAPIキーローテーションが不要になる
- CI/CD環境にAPIキーを保存する必要がなくなる
- GitHub ActionsなどのOIDC対応CI/CD環境からのみパッケージを公開できるように制限できる
ただし、OIDCを使ったトークンレスパッケージ公開には以下のような制約もあります。
- CI/CD環境からのみパッケージを公開できる (手元からOIDCでパッケージ公開はできない)
- CI/CD環境とパッケージシステムの両方がOIDCに対応している必要がある
また、OIDCを使ったトークンレスパッケージ公開を導入しても、以下のようなリスクは残ります。
- CI/CD環境へ不正アクセスされた場合、パッケージを公開されるリスクがある
- あくまでもパッケージ公開の認証を強化するものであり、パッケージ内容の改ざんやマルウェア混入を防止するものではない
OIDCを使った基本的な仕組みについては、業界で取り組んでいるOpenSSFイニシアチブ)を参照するとフローや概念がよくわかります。

NuGet Trusted Publishingの概要
Trusted PublishingはOIDCを使ってパッケージ公開時のサービス認証を行う仕組みです。NuGet Trusted Publishingでは、事前に登録されたCI/CD環境からリクエストに限り、短時間のみ有効なトークンを発行してパッケージ公開を許可します。このため、ユーザーが直接APIキーを管理する必要はありませんが、コマンドにはdotnet nuget publish -k "token"のように短命なトークンを渡すことになります。
OIDCを使った認証フローは次の通りです。
- CI/CD環境がOIDCトークンを発行
- CI/CD環境がOIDCトークンを使ってnuget.orgから短時間のみ有効なパッケージ公開トークンを取得
- CI/CD環境がパッケージ公開トークンを使ってNuGetパッケージを公開
OIDCには事前認証が必要なため、Trusted Publishingを利用する = NuGetで信頼設定を行う、GitHub Actionsは指定した設定で実行することを意味します。
- nuget.orgでTrusted Publishingのポリシーを設定
- CI/CDはポリシーに沿った設定でNuGetパッケージ公開
NuGet Trusted Publishingは、CI/CD環境としてGitHubに対応していますが他のCI/CD環境は対応していません。1
設定方法
NuGet Trusted Publishingを設定する手順を見ていきましょう。
nuget.orgでTrusted Publishingのポリシーを設定
Nugetにログインして、アカウントメニュー -> Trusted Publishingを開きます。

Createをクリックして、Trusted Publishingポリシーを作成します。下は私の管理しているSkiaSharp.QrCodeリポジトリの設定例です。
- ポリシー名は任意の名前でOK。識別しやすいようにリポジトリ名などを入れておくとよさそう
- Package OwnerはNuGetのアカウントを指定。ここでOrgアカウントを選択すれば、NuGet Orgアカウントのパッケージが対象となる
- Repository OwnerはGitHubのリポジトリ所有者名を指定。GitHub Orgのパッケージなら、GitHub Organization名を指定
- Repository Nameはリポジトリ名を指定
- Workflow Fileは、GitHub Actionsワークフローのファイル名を指定。注意書きにあるように、.github/workflows/以下の「ファイル名」のみを指定

CI/CDワークフローの設定
CI/CDワークフローと言ってもGithub Actionsにしか対応していないので、GitHub Actionsワークフローです。
- ワークフローファイル名は、NuGet Trusted Publishingポリシーで指定したWorkflow Fileと一致させる必要がある
- Nuget/loginアクションを実行するジョブのPermissionsに
id-token: writeの権限を付与するのがポイント。AWSやGoogle Cloud、AzureといったほかのOIDCデプロイと同じように、OIDCトークン発行のために必要 - NuGetの短命トークン取得には、NuGet/loginアクションを使うのが推奨。nuget.orgからパッケージ公開トークンを取得し、ステップ変数にセットしてくれる
サンプルのワークフローrelease.yamlは次の通りです。この例では、git tagでバージョンタグをプッシュしたときにパッケージを公開するようにしています。
name: Publish NuGet package on: push: tags: - 'v*.*.*' # バージョンタグをプッシュしたときに実行 jobs: publish: permissions: contents: read id-token: write # OIDCトークン発行のために必要 runs-on: ubuntu-24.04 steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 # ビルド & パック - name: dotnet pack run: dotnet pack -c Release -o ./bin # NuGet/loginアクションでOIDCトークンを使って短命トークンを取得 - name: NuGet Login uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.0.0 id: login with: user: my-nuget-username # NuGetのユーザー名を指定、Orgアカウントでもユーザー名となる # 取得した短命トークンを使ってパッケージを公開 - name: Push package run: dotnet nuget push ./bin/*.nupkg --api-key "${{ steps.login.outputs.NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json
ワークフローを実行
タグをプッシュすれば、GitHub ActionsがトリガーされてOIDCを使ってNuGetパッケージが公開されます。
制約
2025年10月1日時点で、Reusable WorkflowでNuGet/Loginを使った場合に、NuGetで登録したポリシーを見つけられないことを確認しています。Reusable Workflowを使わずに、直接ワークフローに記述する場合は問題ないので、こちらを利用することをお勧めします。
Error: Token exchange failed (401): No matching trust policy owned by user '***' was found.
NuGet/loginのIssueで報告してありますが、これはNuGet側で対応しないといけなさそうな気配があるのでしばらくかかりそうです。
- Organization Packages Policy couldn't found when using Reusable Workflow · Issue #6 · NuGet/login
- Workflow file name matching inconsistent · Issue #9 · NuGet/login
再現ワークフローは次の通り
# `.github/workflows/nuget-push.yaml@main` name: Push NuGet on: workflow_call: jobs: create-release: permissions: contents: write id-token: write # required for NuGet Trusted Publish runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - name: NuGet login (OIDC → temp API key) uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.1.0 id: login with: user: my-nuget-user
# 呼び出し元ワークフロー name: Build-Release on: workflow_dispatch: jobs: dummy: permissions: contents: write id-token: write # required for NuGet Trusted Publish uses: .github/workflows/nuget-push.yaml@main
まとめ
NuGetのAPI Token認証の課題を解決するTrusted Publishingが公開されました。API Tokenではトークンローテーションや対応パッケージの指定といったわずらわしさがありましたが、Trusted Publishingを使えばリポジトリごとにOIDCで認証できるため、認証管理がかなりシンプルになります。
とはいえ、認証の境界ラインがGitHub ActionsなどのCI/CD環境に移動するため、CI/CD環境のセキュリティがザルだと意味がありません。CI/CD環境のセキュリティ対策をしっかり行った上で、Trusted Publishingを導入することをお勧めします。2025年現在ならGitHub 2FAからSMSは削除し、Passkeyベースの認証に移行するのがよいでしょう。
- 2025年10月時点↩