パッケージ ソース マッピング

パッケージ ソース マッピングは、特にパブリックとプライベートの両方のパッケージ ソースを使用する場合に、サプライ チェーンのセキュリティを向上させるために使用できるツールです。

既定では、NuGet はパッケージをダウンロードする必要があるときに、構成されているすべてのパッケージ ソースを検索します。 パッケージが複数のソースに存在する場合、どのソースからパッケージをダウンロードするかは決定論的でない可能性があります。 パッケージ ソース マッピングを使用すると、NuGet が検索するソースをパッケージごとにフィルター処理できます。

また、攻撃に対するサプライ チェーンの強化に役立つその他のベスト プラクティスに関する提案も用意されています。

パッケージ ソース マッピングは NuGet 6.0 で追加されました。 Visual Studio 17.5 以降では、Visual Studio の [オプション] ダイアログでパッケージ ソース マッピングを追加および削除できます。

Visual Studio のサポート

Visual Studio パッケージ ソース マッピング ツールのサポート - > オプション パッケージ マネージャー UI でのサポート
17.0 - 17.4 ✅ 対応可能 ❌ 使用可能 ❌ 使用可能
17.5 ✅ 対応可能 ✅ 対応可能 ❌ 使用可能
17.7 Preview 3 ✅ 対応可能 ✅ 対応可能 ✅ 状態が表示される

この機能は、すべての NuGet 統合ツールで使用できます。

これらより前のツールでは、パッケージ ソース マッピング構成が無視されます。 この機能を使用するには、すべてのビルド環境で、互換性のあるツールのバージョンが使用されていることを確認してください。

パッケージ ソース マッピングは、互換性のあるツールが使用されている限り、すべてのプロジェクトの種類 (.NET Framework を含む) に適用されます。

ビデオ チュートリアル

パッケージ ソース マッピング機能のビデオベースの概要については、YouTube の パッケージ ソース マッピングを使った NuGet パッケージのセキュリティ保護のビデオをご覧ください。

パッケージ ソース マッピングの有効化

この機能を利用するには、nuget.config ファイルを用意する必要があります。 リポジトリのルートに単一の nuget.config を配置することがベスト プラクティスとされています。 詳細については、nuget.config に関するドキュメントを参照してください。

Visual Studio の [オプション] ダイアログを使用して有効にする

  1. Visual Studio でソリューションを開きます。
  2. Package Source Mappings の [オプション] ダイアログに 移動します。

パッケージ マネージャー UI から

  • 一覧からパッケージを選択して、詳細ウィンドウに表示します。
  • Configure ボタンを押して、パッケージ ソース マッピングのオプション ページを開きます。

Visual Studio の [NuGet パッケージ マネージャー] ウィンドウに、選択したパッケージが表示され、[構成] ボタンと [パッケージ ソース マッピングがオフ] の状態が強調表示されます。

Visual Studio の [オプション] ダイアログから

  • メイン Visual Studio ツール バーの Tools メニューに移動し、NuGet Package Manager ->Package Manager Settings を選択します。
  • Package Source Mappings ページに移動します。

Visual Studio の [パッケージ ソース マッピング オプション] ダイアログに、パッケージ ソース マッピングが表示されていない。[追加] ボタンを使用して新しいマッピングを作成します。

  1. Package Source Mappings ページ内の Add ボタンを押して Add Package Source Mappings ダイアログを開きます。

[パッケージ ソース マッピングを追加する] ダイアログ 4. パッケージ ID またはパッケージ パターンを入力し、目的のソースのチェックボックスを切り替えて、1 つ以上のパッケージ ソースを選択します。

塗りつぶされたパッケージ パターンと選択したパッケージ ソースを含む [パッケージ ソース マッピングを追加する] ダイアログ。

  1. Package Source Mapping のオプション ページには、新しく作成されたソース マッピングが表示されます。

[パッケージ ソース マッピング] のオプション ページに、新しく作成されたソース マッピングが表示されています

  1. [オプション] ダイアログボックスの OK を押して、該当する nuget.config の変更を保存します。
  2. NuGet パッケージ マネージャー ウィンドウが更新され、選択したパッケージのソース マッピングの新しい状態が反映されます。 Visual Studio の [NuGet パッケージ マネージャー] ウィンドウに、[パッケージ ソース マッピングが見つかりました] 状態の選択したパッケージと[構成] ボタンが表示されます。

nuget.config を手動で編集して有効にする

  • nuget.config ファイルで、対象のパッケージ ソースを宣言します。
  • ソース宣言の次に、<packageSourceMapping> 要素を追加します。これにより、各ソースに必要なマッピングを指定します。
  • 使用中のソースごとに厳密に 1 つの packageSource 要素を宣言します。
    • 必要な数のパターンを追加します。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- Define the package sources, nuget.org and contoso.com. -->
  <!-- `clear` ensures no additional sources are inherited from another config file. -->
  <packageSources>
    <clear />
    <!-- `key` can be any identifier for your source. -->
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="contoso.com" value="https://contoso.com/packages/" />
  </packageSources>
  
  <!-- Define mappings by adding package patterns beneath the target source. -->
  <!-- Contoso.* packages and NuGet.Common will be restored from contoso.com,
       everything else from nuget.org. -->
  <packageSourceMapping>
    <!-- key value for <packageSource> should match key values from <packageSources> element -->
    <packageSource key="nuget.org">
      <package pattern="*" />
    </packageSource>
    <packageSource key="contoso.com">
      <package pattern="Contoso.*" />
      <package pattern="NuGet.Common" />
    </packageSource>
  </packageSourceMapping>
</configuration>

さまざまなレベル (マシン レベル、ユーザー レベル、リポジトリ レベル) で複数の nuget.config ファイルが存在する場合、パッケージ ソース マッピング設定は、nuget.config の優先順位規則に従って適用されます。

パッケージ ソース マッピング規則

NuGet で、最適な柔軟性と制御性を得るために、すべてのパッケージを、適切に定義された優先順位に従ってパッケージ パターンと一致させる必要があります。

パッケージ パターンの要件

要求されたすべてのパッケージを、定義済みのパッケージ パターンと一致させて 1 つ以上のソースにマップする必要があります。 つまり、packageSourceMapping 要素を定義したら、すべてのパッケージ (推移的なパッケージを含む) の復元元となるソースを明示的に定義する必要があります。

  • 最上位および推移的なパッケージの両方を、定義済みのパターンと一致させる必要があります。 最上位パッケージとその依存関係は同じソースからのものでなければならない、という要件はありません。
  • 同じ ID パターンを複数のソースに対して定義することで、そのパターンが定義されているいずれのフィードからも、一致したパッケージ ID を復元できます。 ただし、復元の予測可能性に影響があるため、この方法はお勧めしません (指定のパッケージが複数のソースから取得される可能性があります)。 各ソースをすべて信頼できる場合には、この方法が有効な構成である可能性があります。

パッケージ パターンの構文

パターン 構文例 説明
パッケージ プレフィックス パターン *NuGet.* 末尾を * にする必要があります。* は 0 個以上の文字と一致します。 * は、指定可能な最短のプレフィックス パターンで、すべてのパッケージ ID と一致します。
パッケージ ID パターン NuGet.CommonContoso.Contracts 完全一致のパッケージ ID。

パッケージ パターンの優先順位

パッケージ ID と一致する一意のパターンが複数ある場合は、最も具体的なパターンが優先されます。 パッケージ ID パターンは常に優先順位が最も高く、汎用的な * は優先順位が最も低くなります。 パッケージ プレフィックス パターンの場合、最長のものが優先されます。

パッケージ パターンの優先順位の例

既定のソースの設定

* パターンを使用すると、宣言を事実上の既定のソースとすることができます。これにより、指定されている他のパターンと一致しないパッケージは、エラーのスローなしでそのソースから復元されます。 この構成は、たとえば nuget.org からのパッケージを主に使用し、内部パッケージは少ししかないか、すべての内部パッケージに対して標準プレフィックス (Contoso.* など) を使用するような場合に便利です。

チームが、内部パッケージ ID に対して標準プレフィックスを使用しない場合、またはインストール前に nuget.org パッケージを詳しく調査する場合は、プライベート ソースを既定にする方がニーズに合うでしょう。

Note

要求されたパッケージがグローバル パッケージ フォルダーに既に存在する場合、ソースの参照は行われず、マッピングは無視されます。 リポジトリのグローバル パッケージ フォルダーを宣言して、この機能のセキュリティ上のメリットを生かすことを検討してください。 次のイテレーションで、既定のグローバル パッケージ フォルダーを使用するエクスペリエンスを向上させる取り組みが予定されています。 パッケージのインストールが機能する仕組みの詳細については、概念ドキュメントを参照してください。

作業の開始

リポジトリを完全にオンボードするには、手動または NuGet.PackageSourceMapper ツールを使用する方法の 2 つあります。

手動オンボード

手動オンボードの場合は、次の手順を実行できます。

  1. 新しいリポジトリのグローバル パッケージ フォルダーを宣言します。
  2. dotnet restore を実行して依存関係を復元します。
  3. dotnet list package --include-transitive を実行して、ソリューション内のすべての最上位および推移的なパッケージを表示します。
    • packages.config を使用した .NET フレームワーク プロジェクトの場合、packages.config ファイルに、すべての直接的および推移的なパッケージの単純なリストが含まれます。
  4. ソリューション内のすべてのパッケージ ID (推移的なパッケージを含む) がターゲット ソースのパターンと一致するように、マッピングを定義します。
  5. dotnet nuget locals global-packages -c を実行して、global-packages ディレクトリをクリアします。
  6. マッピングが正しく構成されていることを確認するために、復元を実行します。 マッピングによってソリューション内のすべてのパッケージ ID が完全に網羅されない場合は、問題を特定するのにエラー メッセージが役立ちます。
  7. 復元が成功したら、完了です。 必要に応じて次のことを検討します。

ツールを使用した自動オンボード

多くのリポジトリには多数のパッケージがあり、手動で作業を行うと時間がかかる場合があります。 NuGet.PackageSourceMapper ツールは、プロジェクトの既知のパッケージとソースに基づいて、自動的に NuGet.config を生成できます。

パッケージ ソース マッパー ツールでは、パッケージの復元が正常に完了している必要があります。ここでそれぞれのパッケージとソースをマップする方法を最もよく理解するために、ビルドの一部として生成された各 .nupkg.metadata ファイルが読み取られます。 ツールでは、上位の依存関係だけでなく、マッピングの生成時にすべての推移的な依存関係も考慮されます。

ツールには、ニーズに応じてマッピング パターンを生成する方法がいくつか用意されています。詳細については、ブログの投稿とツールの readme の手順を確認してください。

ソース マッピングがどのように記述されるかについては、サンプルのリポジトリを参照してください。

Note

  • パッケージ ソース マッピング構成を管理するための nuget.exe または dotnet.exe コマンドはありません。NuGet/Home#10735 を参照してください。
  • パッケージのインストール時にパッケージをマッピングする手段はありません。NuGet/Home#10730 を参照してください。
  • DotNetCoreCLI@2 Azure Pipelines タスクを使う場合は制限があります。これは、ソース マッピング構成で feed- プレフィックスを使うことで回避できます。 ただし、認証が必要な場合は NuGetAuthenticate を使い、スクリプト タスクから直接 dotnet cli を呼び出すことをお勧めします。 microsoft/azure-pipelines-tasks#15542 を参照してください。