AzureのマネージドIDについて改めて整理してみた

# はじめに
業務の都合上、ここ半年ほどAzureを触る機会があったのですが、個人的に一番理解に苦しんだのがManaged IDについてでした。
そこで、自分が理解するのに時間がかかったポイントをおさらいしながら、改めてマネージドIDについてまとめてみたいと思います。

# マネージドIDとは
はじめに、マネージドIDの基本情報についておさらいをしていきます。
マネージドIDとはAzureリソースへアクセスする際に利用する認証方式の一つです。
Microsoft Entra 認証をサポートしているサービスにアクセスするためのトークンを取得する際に利用するもので、マネージドIDはAzure側で管理されます。
また、特徴として「構成ファイルにアクセス情報（トークン、秘密鍵等）を含めなくて良いため、セキュアなキー管理が実現できる」とも紹介されています。

# マネージドIDの種類
利用できるマネージドIDには「システム割り当てマネージドID」「ユーザ割り当てマネージドID」の２種類があり、それぞれ以下のような特徴があります。
||システム割り当てマネージドID|ユーザ割り当てマネージドID|
|-|-|-|
|作成方法|Azureリソースに紐づいて作成される|単独のAzureリソースとして作成する|
|ライフサイクル|作成したリソースに紐付けら、リソースが削除されるとマネージドIDも削除される|独立したライフサイクルを持つ（特定のリソースに紐付けられない）|
|Azureリソースとの関連付け|1つのAzureリソースにのみ紐付けることができる|1つのユーザ割り当てマネージドIDを複数のAzureリソースに紐付けることができる|

# サービスプリンシパルとの違い
ここまでの文章内であえて言及していませんでしたが、マネージドIDについて調べていると「サービスプリンシパル」という単語を目にします。どちらもAzureリソースへアクセスする際に利用するものとして同じ文脈で登場するので、「マネージドIDとの違いは何なんだ」という疑問を持っていました。
そこで、サービスプリンシパルについて調べていく中でこれらの違いが徐々にわかってきたので、以下に記載していきます。

### サービスプリンシパルとは
違いの説明に入る前に、サービスプリンシパルについて軽く説明したいと思います。
[Azure Virtual Trainingのサイト内](https://learn.microsoft.com/ja-jp/training/modules/authenticate-apps-with-managed-identities/2-service-principals)で「Azure サービス プリンシパルは、アプリまたはサービスを表すプロキシ アカウント (ID) と考えることができます。」「必要な Azure リソースへのアクセス権をサービス プリンシパルに付与します。 資格情報を埋め込んだり、アプリのダミー アカウントを作成したりする代わりに、サービス プリンシパルを使用します。」と記載されています。
つまり、我々が普段Azure上で実行しているRole付与はサービスプリンシパルに権限を付与する行為であり、このサービスプリンシパルを経由して各種リソースにアクセスしていることになります。
（詳しくはリンク先の記事に記載されている画像を見てもらうのがわかりやすいかと思います。）

### マネージドIDはサービスプリンシパルのラッパー
色々調べてみた結果、[Azureが公開しているリファレンス](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-managed-identities-work-vm)の記事の中に以下のような記述を見つけました。

>「Internally, managed identities are service principals of a special type, which can only be used with Azure resources.」

つまり、これらの2つの差分点は
・マネージドID：認証元がAzureリソースの場合のみ利用できる
・サービスプリンシパル：認証元がAzureリソース外でも利用できる
ということのようです。
個人的には「Azure上でRBACを実現するために利用される仕組みがサービスプリンシパル。Azureリソース間でのみ場合できて色々便利となる仕組みがマネージドID」というような解釈をしています。

# なぜマネージドIDがセキュアなのか？
ここまででマネージドIDの概要をある程度理解することができたましたが、「どこかに認証情報が置かれているのであれば、構成ファイル内に認証情報が記載されているのと同じセキュリティレベルなのでは？」という疑問が残っていました。
そのため、どのようにマネージドIDが認証トークンを取得するのかを調べてみました。

### トークンの取得フロー
マネージドIDがEntra IDからアクセストークンを取得するフローは[こちらのリファレンス](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-managed-identities-work-vm)内に記載さています。
結果としては「Azure上から特殊なIPアドレス(リンクローカルアドレス)が割り当てられているAzure Instance Metadata Serviceを経由してEntra IDにトークンを要求する」という処理が行われているようです。
リンク先ではVM上からマネージドIDを利用してアクセストークンを取得する際のフローが説明されているのですが、ざっくりまとめると
1. VM 内からのみアクセスできる Azure Instance Metadata サービス エンドポイントにトークン (http://169.254.169.254/metadata/identity/oauth2/token) を要求
2. クライアント ID と証明書を使用してAzure Instance Metadata ServiceがMicrosoft Entra IDにトークンを要求し、Entra IDがトークンを返却する
3. 取得したトークンを利用して認証を行う

という流れが記載されています。
これであれば「うっかりミスで認証情報が漏れてしまう可能性はまずないだろうな」と納得することができました。

# おわりに
本記事ではマネージドIDの簡単な概要をおさらいしてきました。
マネージドIDを利用することで
- アプリケーションにアクセスするための資格情報をハードコーディングの必要がなくなるためセキュアになる
- Azureリソース削除に合わせてシステム割り当てマネージドIDも削除されるため、認証情報の管理が楽になる

等々のメリットがあるので、Azureを利用する際は利用を検討することをお勧めします。


# 参考資料
- マネージドIDについての概要
https://learn.microsoft.com/ja-jp/entra/identity/managed-identities-azure-resources/overview
- サービスプリンシパルについての説明
https://learn.microsoft.com/ja-jp/training/modules/authenticate-apps-with-managed-identities/2-service-principals
- マネージドIDがトークンを取得するまでのフロー
https://learn.microsoft.com/ja-jp/entra/identity/managed-identities-azure-resources/how-managed-identities-work-vm