本記事は Microsoft Learn の「マネージド ID を実装する」というモジュールをまとめたものである。
マネージド ID の概要
開発者が直面する「認証情報の管理」という課題を、マネージド ID が解決する。
1. 開発者の課題
- 資格情報の管理:API キー、パスワード、証明書などを安全に保管し、漏洩を防ぐのは困難
- 「鍵の鍵」問題:Key Vault にアクセスするためのパスワードをどこに隠すか、という矛盾が発生する
2. マネージド ID の仕組み
- 身分証の自動付与:Azure がアプリケーション自体に Microsoft Entra ID 上の「身分証(ID)」を直接割り当てる
- トークンの自動取得:アプリはパスワードを提示することなく、自分自身の ID を使ってアクセス許可(トークン)を取得できる
3. 主なメリット
- 資格情報が不要:アプリのコードや設定ファイルにパスワードを一切書かずに済む
- 管理の自動化:認証情報の更新やローテーションは Azure 側で自動処理される
- 高い安全性:開発者が「鍵」に触れる必要がないため、人的ミスによる漏洩リスクが激減する
マネージド ID の 2 つの種類
マネージド ID には、ライフサイクルや管理方法が異なる 2 つのタイプがある。
1. システム割り当てマネージド ID (System-assigned)
Azure リソース(VM や Web アプリなど)と 1 対 1 で結びつく ID。
- 作成:リソースの設定で「オン」にすると、Azure が自動で作成
- ライフサイクル:リソースと運命を共にする。リソースを削除すれば ID も自動消滅
- 用途:特定の 1 つのリソースだけに専用の権限を与えたい場合に最適
2. ユーザー割り当てマネージド ID (User-assigned)
独立した 1 つの Azure リソース として作成する ID。
- 作成: 事前に「マネージド ID」リソースとして作成し、後からアプリ等に紐付ける
- 共有:1 つの ID を複数のリソース(例:10 台の VM)で使い回せる
- ライフサイクル:独立している。アプリを削除しても ID は残り、管理者が手動で消すまで存続
- 用途:複数のリソースに同じ権限をまとめて付与したい場合に効率的
3. 共通の仕組み
- 実体:内部的には「サービスプリンシパル」の特殊形態
- 制限:Azure リソース以外では使用できないようロックされており、安全性が高い
- クリーンアップ:ID が削除されれば、対応する内部の認証情報も自動で削除される
マネージド ID の特性と使い分け
システム割り当てとユーザー割り当ての違いを、特性とユースケースで整理。
1. 特性比較表
| プロパティ | システム割り当て | ユーザー割り当て |
|---|---|---|
| 作成方法 | Azure リソースの一部として作成 | 独立した Azure リソースとして作成 |
| ライフサイクル | 親リソースと連動(親が消えれば ID も消える) | 独立(明示的に削除するまで存続) |
| リソース間の共有 | 不可(1 対 1) | 可能(1 つの ID を複数に関連付け) |
2. 一般的なユースケース
システム割り当てマネージド ID
- 単一のワークロード:1台の仮想マシンや1つの Web アプリだけで完結する場合
- 独立性の重視:他と ID を共有せず、個別にアクセス権を管理したい場合
ユーザー割り当てマネージド ID
- 複数リソースでの共有:複数の仮想マシンが同じデータベースや Key Vault にアクセスする場合
- 事前認可:リソース(VM 等)を作成する前に ID を作成し、権限を与えておきたい場合
- 一貫性の維持:VM の作り直し(リサイクル)が頻繁に発生しても、アクセス許可設定をそのまま使い回したい場合
マネージド ID をサポートする Azure サービス
マネージド ID は、Microsoft Entra 認証に対応しているさまざまな Azure サービスで利用できる。
1. 利用可能な範囲
- 認証先:Microsoft Entra ID を使った認証をサポートするすべてのサービス(Key Vault, Azure SQL, Storage など)に対して使用可能
- 対象サービス:非常に多くの Azure リソースがマネージド ID をサポートしており、一覧は公式ドキュメントで随時更新されている
2. 汎用的なコンセプト
- 共通の仕組み:本モジュールでは「仮想マシン (VM)」を例に説明するが、基本的な考え方や設定手順は他のサービスでも共通
- 適用例:Azure App Service、Azure Functions、Azure Container Instances など、どのリソースであっても「ID を割り当ててトークンを取得する」というフローは変わらない
マネージド ID の認証フロー
システム割り当てマネージド ID の動作フロー
Azure VM でシステム割り当てマネージド ID を有効にした際の、裏側のセットアップと認証の仕組み
1. ID の作成と構成
- リクエスト:管理者が VM で ID を有効にすると、Azure Resource Manager (ARM) がその要求を受ける
- 身分証の発行:ARM が Microsoft Entra ID 上に、その VM 専用のサービスプリンシパル(アプリ用アカウント)を作成
- 情報の埋め込み:作成された ID 情報(クライアント ID や証明書)が、VM 専用の内部窓口(Azure Instance Metadata Service: IMDS)に書き込まれる
2. アクセス許可の設定
-
権限付与:作成されたサービスプリンシパルに対して、RBAC(ロール割り当て)などを用いて「どのリソースに触ってよいか」を設定
- 例:ストレージの読み取り権限、Key Vault のシークレット取得権限など
3. トークン取得と認証の流れ
-
トークン要求:VM 内のアプリが、内部エンドポイント(
http://169.254.169.254/metadata/identity/oauth2/token)にアクセス。このエンドポイントは VM 外部からは絶対に叩けないため安全 - 代理認証:IMDS が保持している ID 情報を使って Entra ID と通信し、アクセストークン(JWT)を取得してアプリに返す
- リソース利用:アプリはそのトークンを HTTP ヘッダーに添えてターゲットのサービス(Storage や Key Vault)へ送信し、認証をパスする
Azure Instance Metadata Service (IMDS) は、Azure上で動いている仮想マシンが、自分自身が何者で、どんな環境にいるのかを自問自答して情報を取得するための特別な窓口。
ユーザー割り当てマネージド ID の動作フロー
ユーザー割り当て ID は、VM とは独立した「リソース」として作成・管理される。その認証プロセスのまとめ。
1. ID の作成と紐付け
- 独立した作成:最初に Azure Resource Manager (ARM) が独立したリソースとして ID を作成。このとき Entra ID 上にサービスプリンシパルが生成される
- VM への構成:作成済みの ID を VM に割り当てる。ARM はその ID 情報(クライアント ID 等)を VM 内部の窓口(IMDS)に登録する
2. アクセス許可の設定
- 権限付与:ID(サービスプリンシパル)に対して、ターゲットとなるリソース(Key Vault や Storage)へのアクセス権(RBAC)を事前に割り当てる
3. トークンの取得と利用
-
トークン要求:VM 内のアプリが内部エンドポイント(
http://169.254.169.254/metadata/identity/oauth2/token)へリクエストを送る - ポイント:ユーザー割り当て ID が複数ある場合は、どの ID のトークンが欲しいか「クライアント ID」を明示して要求する
- Entra ID との通信:IMDS が Entra ID からアクセストークン(JWT)を取得し、アプリに返す
- リソースへのアクセス: アプリは取得したトークンを使って目的のサービスを呼び出す
マネージド ID を構成する
システム割り当てマネージド ID の構成方法
1. 必要な権限
- ロール:「仮想マシン共同作成者」ロールが必要
- 補足:Microsoft Entra ID(旧 Azure AD)側の特別な管理者権限は不要
2. VM 作成時に有効化する
az vm create コマンドに特定のパラメーターを組み合わせて実行する。
-
使用する主なフラグ:
-
--assign-identity:システム割り当て ID を有効にする -
--role:ID 作成と同時に、その ID に与える役割(例:contributor)を指定 -
--scope:そのロールを適用する範囲(サブスクリプション単位など)を指定
-
az vm create --resource-group myResourceGroup \
--name myVM --image win2016datacenter \
--generate-ssh-keys \
--assign-identity \
--role contributor \
--scope mySubscription \
--admin-username azureuser \
--admin-password myPassword12
3. 既存の VM で有効化する
すでに動いている VM に対して ID を追加する場合は az vm identity assign を使う。
az vm identity assign -g myResourceGroup -n myVm
ユーザー割り当てマネージド ID の構成方法
ユーザー割り当て ID は独立したリソースであるため、「作成」と「割り当て」の 2 ステップが必要。
1. 必要な権限
- 仮想マシン共同作成者:VM を操作するために必要
- マネージド ID オペレーター:作成済みの ID をリソースに紐付けるために必要
- 補足:Entra ID(旧 Azure AD)側の特別な管理者権限は不要
2. 手順 1:ユーザー割り当て ID の作成
まず、ID そのものをリソースとして作成する。
az identity create -g myResourceGroup -n myUserAssignedIdentity
3. 手順 2:VM への割り当て
作成した ID を VM に紐付ける。タイミングは「作成時」でも「作成後」でも可能。
-
VM 作成時に割り当てる:
-
--assign-identityに作成した ID 名を指定 -
--roleと--scopeで、その ID が持つ権限も同時に設定可能
-
az vm create \
--resource-group <RESOURCE GROUP> \
--name <VM NAME> \
--image Ubuntu2204 \
--admin-username <USER NAME> \
--admin-password <PASSWORD> \
--assign-identity <USER ASSIGNED IDENTITY NAME> \
--role <ROLE> \
--scope <SUBSCRIPTION>
-
既存の VM に割り当てる:
az vm identity assignを使用して、後から ID を流し込む
az vm identity assign \
-g <RESOURCE GROUP> \
-n <VM NAME> \
--identities <USER ASSIGNED IDENTITY>
アクセストークンを取得する
Azure SDK の中核となる DefaultAzureCredential は、実行環境に合わせて最適な認証方法を自動で選択する非常に便利な仕組み。
1. DefaultAzureCredential のメリット
- コードの共通化:開発環境(自分の PC)と運用環境(Azure 上)で、認証コードを一切書き換える必要がない
- 柔軟性:複数の認証メカニズムを順番に試し、最初に成功したものでログインする
2. 認証を試行する優先順位
以下の順序で認証を試み、成功した時点で停止する。
- 環境変数:アプリの設定に埋め込まれたサービスプリンシパル情報などを確認
- マネージド ID:Azure 上で実行されている場合、そのリソースの ID を使用(運用環境のメイン)
- Visual Studio:開発者が VS 上でサインインしているアカウント
-
Azure CLI:ターミナルで
az login済みのカウント -
Azure PowerShell:
Connect-AzAccount済みのカウント - 対話型ブラウザー:ブラウザーを立ち上げて手動ログイン(※デフォルトでは無効)
Azure Identity SDK を使用した実装例
SDK を活用することで、わずか数行のコードでセキュアな認証を実装できる。以下に主要なパターンをまとめる。
1. 標準的な認証(DefaultAzureCredential)
最も一般的で推奨される方法。環境(ローカル/Azure)に応じて自動で認証。
- 特徴:コード内に認証情報を一切書く必要がない
// Create a secret client using the DefaultAzureCredential
var client = new SecretClient(new Uri("https://myvault.vault.azure.net/"), new DefaultAzureCredential());
2. ユーザー割り当てマネージド ID の明示
1 つのリソースに複数の ID がある場合、特定の「ユーザー割り当て ID」を使うよう指定できる。
-
方法:
DefaultAzureCredentialOptionsに クライアント ID をセットする
// When deployed to an azure host, the default azure credential will authenticate the specified user assigned managed identity.
string userAssignedClientId = "<your managed identity client Id>";
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId });
var blobClient = new BlobClient(new Uri("https://myaccount.blob.core.windows.net/mycontainer/myblob"), credential);
3. カスタム認証フロー(ChainedTokenCredential)
DefaultAzureCredential の試行順序や種類を、自分で自由にカスタマイズしたい場合に使う。
- 特徴:複数の認証方式を組み合わせて「独自のチェーン(優先順位)」を作成できる
- 例:「マネージド ID を最優先し、ダメなら Azure CLI を使う」という 2 段階に限定する設定
// Authenticate using managed identity if it is available; otherwise use the Azure CLI to authenticate.
var credential = new ChainedTokenCredential(new ManagedIdentityCredential(), new AzureCliCredential());
var eventHubProducerClient = new EventHubProducerClient("myeventhub.eventhubs.windows.net", "myhubpath", credential);