Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022
Azure Pipelines をセキュリティで保護する場合は、共有インフラストラクチャ、リポジトリ、プロジェクトなどを保護することを検討してください。
この記事は、Azure Pipelines のセキュリティ対策を実装するのに役立つシリーズの一部です。 詳細については、「 Azure Pipelines のセキュリティ保護」を参照してください。
[前提条件]
| カテゴリ | 必要条件 |
|---|---|
| Azure DevOps | - Azure DevOps をセキュリティで保護し、Azure Pipelines を セキュリティで保護する方法に関するページの推奨事項を実装します。 - YAML と Azure Pipelines に関する基本的な知識。 詳細については、「最初のパイプラインの作成」を参照してください。 |
| アクセス許可 | - パイプラインのアクセス許可を変更するには: プロジェクト管理者グループのメンバー。 - 組織のアクセス許可を変更するには: プロジェクト コレクション管理者グループのメンバー。 |
共有インフラストラクチャを保護する
Azure Pipelines の保護されたリソースは、実際のインフラストラクチャを抽象化したものです。 基になるインフラストラクチャを保護するには、次の推奨事項に従ってください。
Microsoft によってホストされているプールを使用する
Microsoft がホストするプールは、パイプラインの実行ごとに分離とクリーンな仮想マシンを提供します。 可能であれば、セルフホステッド プールの代わりに Microsoft がホストするプールを使用します。
プロジェクトごとにエージェントを分離する
エージェントは、1 つのプールにのみ関連付けることができます。 プールを複数のプロジェクトに関連付けることで、複数のプロジェクト間でエージェントを共有できます。 実際には、複数のプロジェクトで同じエージェントが連続して使用される場合があります。 コスト効率に優れていますが、このアプローチでは横移動リスクが発生する可能性があります。
横方向の移動を減らし、プロジェクト間のクロスコンタミネーションを防ぐには、それぞれ特定のプロジェクト専用の個別のエージェント プールを維持します。
低い権限のアカウントを使用してエージェントを実行する
Azure DevOps リソースに直接アクセスできる ID でエージェントを実行すると、危険な場合があります。 このリスクは、Microsoft Entra ID を使用する組織で一般的です。
このリスクが重要な理由:
- Entra ID によってサポートされる ID でエージェントを実行すると、ジョブのアクセス トークンに依存することなく、Azure DevOps API に直接アクセスできます。
- これらのビルド エージェントで侵害されたパイプラインを実行する敵対者は、Azure DevOps 組織全体を制御できる可能性があります。
推薦: 特権のないローカル アカウントを使用してエージェントを実行します。
-
Windows エージェント: ネットワーク サービス (
NT AUTHORITY\NETWORK SERVICE)、ローカル サービス、または グループ管理サービス アカウント (gMSA) を使用します。 -
Linux エージェントと macOS エージェント: 専用の非ルート ユーザー アカウント (たとえば、
svc_azuredevops) を作成します。 このアカウントには、セキュリティを最大限に高める sudo または sudoers アクセス権を持つべきではありません。
重要
Azure DevOps では、 Project Collection Service Accounts グループが誤解を 招く可能性があります。 継承により、Project Collection Service アカウントのメンバーも Project Collection Administrators のメンバーになります。 一部のお客様は、Entra ID によってサポートされる ID を使用してビルド エージェントを実行します。これらの ID は Project Collection Service アカウントに含めることができます。
高い特権を持つエージェントのリスク:
セルフホステッド エージェントは、シークレットや運用環境にアクセスするために、高い特権を持つアカウントで動作することがあります。 敵対者がこれらのビルド エージェントのいずれかで侵害されたパイプラインを実行すると、次のことができます。
- これらのシークレットにアクセスする
- これらのアカウントを介してアクセスできる他のシステムを横方向に移動する
エージェント セキュリティのベスト プラクティス:
- セルフホステッド エージェントを実行するために、可能な限り低い特権アカウントを使用します。
- マシン アカウントまたはマネージド サービス ID の使用を検討してください。
- Azure Pipelines でシークレットと環境へのアクセスを管理できるようにします。
サービス接続のスコープを最小限に抑える
サービス接続は、必要なリソースにのみアクセスする必要があります。
認証に関する推奨事項:
- 可能な場合は常に、Azure サービス接続のサービス プリンシパルの代わりにワークロード ID フェデレーションを使用します。
- ワークロード ID フェデレーションでは、業界標準テクノロジである Open ID Connect (OIDC) を使用して、シークレットに依存せずに Azure と Azure DevOps の間の認証を容易にします。
スコープの推奨事項:
- 必要なリソースのみにアクセスするように Azure サービス接続 のスコープを設定します。
- Azure サブスクリプション全体に対して広範な共同作成者権限を付与することは避けてください。
- 新しい Azure Resource Manager サービス接続を作成するときは、常に特定のリソース グループを選択します。
- リソース グループに、ビルドに必要な VM またはリソースのみが含まれていることを確認します。
- GitHub アプリを構成する場合は、ビルドするリポジトリにのみアクセス権を付与します。
プロジェクトを保護する
個々のリソースだけでなく、Azure DevOps のリソース グループを検討することが重要です。 リソースはチーム プロジェクトごとに編成されるため、プロジェクトの設定と包含に基づいてパイプラインがアクセスできる内容を理解する必要があります。
パイプライン内の各ジョブは、開いているリソースを読み取るアクセス許可を持つアクセス トークンを受け取ります。 場合によっては、パイプラインによってこれらのリソースが更新される場合もあります。 このアクセス許可モデルは、ユーザー アカウントが特定のリソースに直接アクセスできない可能性がある一方で、パイプラインで実行されているスクリプトとタスクは引き続きアクセスできることを意味します。 さらに、Azure DevOps のセキュリティ モデルを使用すると、組織内の他のプロジェクトからこれらのリソースにアクセスできます。 特定のリソースへのパイプライン アクセスを制限する場合、この決定はプロジェクト内のすべてのパイプラインに適用されます。特定のパイプラインに、開いているリソースへのアクセス権を選択的に付与することはできません。
個別のプロジェクト
オープン リソースの性質上、各製品とチームを個別のプロジェクトで管理することを検討してください。 これにより、ある製品からパイプラインが誤って別の製品から開いているリソースにアクセスするのを防ぎ、横方向の露出を最小限に抑えることができます。 しかし、複数のチームまたは製品がプロジェクトを共有する場合、リソースの細かい分離が困難になります。
Azure DevOps 組織が 2019 年 8 月より前に作成された場合でも、すべての組織のプロジェクトで開いているリソースに対して実行がアクセスできる可能性があります。 組織の管理者は、パイプラインのプロジェクト分離を有効にする Azure Pipelines の重要なセキュリティ設定を確認する必要があります。
この設定は、 Organization 設定>Pipelines>Settings、または直接: https://dev.azure.com/Organization_Name/_settings/pipelinessettingsにあります。
リポジトリを保護する
バージョン管理リポジトリには、ソース コード、パイプラインの YAML ファイル、および必要なスクリプトとツールを格納できます。 コードとパイプラインに安全に変更を加えるためには、アクセス許可とブランチ ポリシーを適用することが重要です。 さらに、パイプラインのアクセス許可 追加し、リポジトリに確認することを検討してください。
さらに、リポジトリの 既定のアクセス制御設定 を確認します。
Git の設計は、ブランチ レベルの保護に制限があることを意味します。 リポジトリへのプッシュ アクセスを持つユーザーは、通常、新しいブランチを作成できます。 GitHub オープンソース プロジェクトを使用している場合は、GitHub アカウントを持つすべてのユーザーがリポジトリをフォークし、投稿を提案できます。 パイプラインは (特定のブランチではなく) リポジトリに関連付けられているため、コードファイルと YAML ファイルを信頼できない可能性があるものとして扱う必要があります。
フォーク
GitHub のパブリック リポジトリを使用する場合は、ビルドをフォークする方法を慎重に検討してください。 組織外からのフォークは、特定のリスクを引き起こします。 信頼されていない可能性のあるコードから製品を保護するには、次の推奨事項に従います。
注
これらの推奨事項は、主に GitHub からパブリック リポジトリを構築する場合に適用されます。
フォーク ビルドにシークレットを提供しない
既定では、パイプラインはフォークを構築しますが、それらのパイプライン内のジョブに対して、シークレットや保護されたリソースを自動的に公開しません。 セキュリティを維持するために、この保護を無効にしないでください。
注
フォーク ビルドを有効にしてシークレットにアクセスすると、Azure Pipelines によって既定で使用されるアクセス トークンが制限されます。 このトークンは、通常のアクセス トークンと比較して、開いているリソースへのアクセスが制限されています。 フォーク ビルドに通常のビルドと同じアクセス許可を付与するには、 Make フォーク ビルドに通常のビルドと同じアクセス許可 設定を有効にします。
フォーク ビルドを手動でトリガーすることを検討する
自動フォーク ビルドをオフに し、代わりに pull request コメントを使用して、これらのコントリビューションを手動でビルドします。 この設定により、ビルドをトリガーする前にコードを確認できます。
フォーク ビルドには Microsoft ホステッド エージェントを使用する
セルフホステッド エージェントでフォークからビルドを実行しないようにします。 セルフホステッド エージェントを使用する場合、外部組織は企業ネットワーク内のコンピューターで外部コードを実行できます。 可能な限り、Microsoft でホストされるエージェントを使用します。 セルフホステッド エージェントの場合は、ネットワーク分離を実装し、エージェントがジョブ間で状態を保持しないようにします。
コードの変更を確認する
フォークしたプルリクエストでパイプラインを実行する前に、提案された変更を慎重に確認し、実行しても問題がないことを確認してください。
実行する YAML パイプラインのバージョンは、プル要求のバージョンです。 コマンド ライン スクリプトや単体テストなど、YAML コードとパイプラインの実行時に実行されるコードに対する変更には特に注意してください。
GitHub のトークン スコープの制限
GitHub でフォークされた pull request をビルドすると、Azure Pipelines は、パイプラインで GitHub リポジトリの内容を変更できないようにします。 この制限は、GitHub との統合に Azure Pipelines GitHub アプリを使用する場合に "のみ" 適用されます。 OAuth アプリなど、他の形式の GitHub 統合を使用する場合、制限は適用されません。
ユーザー ブランチ
適切なアクセス許可を持っている組織のユーザーは、新しいコードまたは更新されたコードを含む新しいブランチを作成できます。 このコードは、保護されたブランチと同じパイプラインを介して実行できます。 新しいブランチの YAML ファイルが変更されると、更新された YAML によってパイプラインが実行されます。 この設計は優れた柔軟性とセルフサービスを提供しますが、(悪意を持って行われたかどうかにかかわらず) すべての変更が安全であるわけではありません。
パイプラインが、ソース コードを使用する場合や、Azure Repos で定義されている場合は、Azure Repos のアクセス許可モデルを完全に理解している必要があります。 特に、リポジトリ レベルでブランチの作成アクセス許可を持つユーザーは、コントリビューション アクセス許可がなくても、リポジトリにコードを取り込むことができます。
その他のセキュリティの考慮事項
パイプラインをセキュリティで保護する場合は、次のセキュリティの側面を考慮してください。
PATH に依存する
エージェントの PATH 設定に依存することは危険です。 以前のスクリプトやツールによって変更されている可能性があるため、思っている方向を指していないかもしれません。 セキュリティ クリティカルなスクリプトやバイナリの場合は、常にプログラムへの完全修飾パスを使用します。
シークレットをログに記録する
Azure Pipelines は、可能な限りログからシークレットを削除しようとします。 このフィルター処理はベストエフォート ベースであり、シークレットが漏洩するおそれがあるすべての方法をキャッチすることはできません。 シークレットをコンソールにエコーしたり、コマンド ライン パラメーターで使用したり、ファイルにログしたりしないでください。
コンテナーのロックダウン
コンテナーには、ホスト エージェントとの通信に必要な、システムによって提供されるボリューム マウント マッピングが、タスク、ワークスペース、および外部コンポーネントにいくつか用意されています。 これらのボリュームの一部またはすべてを読み取り専用としてマークできます。
resources:
containers:
- container: example
image: ubuntu:22.04
mountReadOnly:
externals: true
tasks: true
tools: true
work: false # the default; shown here for completeness
通常、ほとんどのユーザーは最初の 3 つのディレクトリを読み取り専用に設定し、 work を読み取り/書き込みのままにします。
特定のジョブまたはステップで work ディレクトリに書き込まない場合は、 work 読み取り専用にすることもできます。 ただし、パイプライン タスクに自己修正が含まれる場合は、 tasks を読み取り/書き込みとして保持する必要があります。
使用可能なタスクを制御する
Marketplace からタスクをインストールして実行する機能を無効にすることができます。 この方法では、パイプラインで実行されるコードをより詳細に制御できます。 また、エージェントに対する特別なアクションである チェックアウト タスクを除き、すべてのインザボックス タスクを無効にすることもできます。 ほとんどの状況では、インザボックス タスクを無効にしないでください。
tfxを使用して直接インストールするタスクは、常に使用できます。
これらの両方の機能を有効にすると、それらのタスク のみが 使用できます。
監査サービスを使用する
監査サービスは、多数のパイプライン イベントを記録します。
監査ログを定期的に確認して、悪意のある変更が過去に滑り落ちないようにします。
開始するには、 https://dev.azure.com/ORG-NAME/_settings/auditにアクセスしてください。