💻

マネージド ID に Microsoft Graph API アクセス許可設定を行う

2024/11/03に公開

Configure Microsoft Graph API access permissions for Managed Identity

Microsoft Azure を利用していると、マネージド ID が設定された Azure リソースから、SharePoint や Exchange Online (Outlook)、Microsoft Teams をはじめとする Microsoft 365 環境、あるいは Microsoft Entra ID テナント のユーザー/グループ情報にアクセスしたいことがあると思います。(例えば、App Service や Azure Functions などから対象のリソースにアクセスしたい、など)

Microsoft 365 や Microsoft Entra ID 上のリソース情報にアクセスする際に使用する REST API は基本、Microsoft Graph なので、これを使用するのですが、Microsoft Azure を利用しているのであれば、シークレットレスに、マネージド ID を利用してアクセス権限を定義できます。

https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0

AWS や Google Cloud など、他社クラウドであれば、サービスプリンシパルと呼ばれるアプリ ID のようなものを発行し、証明書やシークレット文字列による認証を介してアクセスを行うことになりますが、正直シークレットや証明書流出による不正アクセスリスクへの対策は面倒です。
実際に私も、Microsoft Graph API に関しては会社では以下のような取り組みを行っています。

https://techblog.recruit.co.jp/article-272/

ですが、Azure OpenAI Service や Azure AI Search をはじめ、せっかく多くのユーザーが Microsoft Azure を使い始めている今、ユーザーにはマネージド ID を使用して、シークレットレスでよりセキュアな形で Microsoft Graph API 活用をし、もっと多くの人に Microsoft Azure & Microsoft Graph の知見を共有したいのが実情です。
そのため、この記事では、マネージド ID に Graph API アクセス許可を付与する手順を紹介したいと思います。

マネージド ID

システム割り当て あるいは ユーザー割り当て にて、Microsoft Azure リソース自体を他のユーザー ID と同様に扱える機能です。
これにより、ユーザー ID に対してアクセス権限を割り当てるのと同様、Microsoft Azure リソース個別に Microsoft 365 環境や Microsoft Entra リソースに対するアクセス権限を付与し、シークレットレスかつセキュアに利用することが可能になります。

https://learn.microsoft.com/ja-jp/entra/identity/managed-identities-azure-resources/overview

マネージド ID はブラウザから Graph API アクセス許可を操作できない

通常、サービスプリンシパルに対して Microsoft Graph API のアクセス許可を付与する場合は、Azure ポータルや Microsoft Entra 管理センターから操作を行い、設定を行うかと思います。

しかしながら、マネージド ID の場合、同じ画面を表示することは不可となっています。そのため、マネージド ID に紐づくサービスプリンシパルをブラウザ上で表示することができなくなっており、API のアクセス許可をブラウザ上から GUI で定義することができません。
そのため、テナント管理者は、Microsoft Graph PowerShell などを用いて、マネージド ID に対し Microsoft Graph API のアクセス許可を付与する必要があります。

Microsoft Graph PowerShell でマネージド ID に Graph API アクセス許可を付与する

Microsoft Graph PowerShell については、以下の公式ドキュメントを参照し、インストールなどを完了してください。

https://learn.microsoft.com/ja-jp/powershell/microsoftgraph/installation?view=graph-powershell-1.0

また、Microsoft Graph PowerShell で作業を行うユーザーは、特権ロール管理者 の Microsoft Entra 管理者ロールを付与しておきます。

Application permission

Application (アプリケーションの許可) 種別の Microsoft Graph アクセス権限を付与する場合は、対象の Application の権限 ID を取得した上で、New-MgServicePrincipalAppRoleAssignment コマンドを使用します。

# Microsoft Graph PowerShell にサインイン
Connect-MgGraph -Scope "Application.ReadWrite.All,AppRoleAssignment.ReadWrite.All" -TenantId "<テナント ID>"
# Graph アクセス許可を付与する対象のマネージド ID 情報を取得
$sp = Get-MgServicePrincipal -ServicePrincipalId "<マネージド ID のオブジェクト ID>"
# Microsoft Graph のサービスプリンシパル情報を取得
$graphResource = Get-MgServicePrincipal -All | Where-Object { $_.ServicePrincipalNames.Contains('https://graph.microsoft.com') }
# 付与したいアクセス許可の権限ロール ID を取得
# ※例として、以下では "User.Read.All" と "GroupMember.Read.All" の権限ロール ID を取得
$permissions = $graphResource.AppRoles | Where-Object { $_.Value -eq 'User.Read.All' -or $_.Value -eq 'GroupMember.Read.All'}

実行後、$permissions を参照すると、以下のように権限 ID 情報が取得できているはずです。
New-MgServicePrincipalAppRoleAssignment コマンドを使用して、1 つずつマネージド ID に Graph API アクセス権限を付与していきます。

# アクセス許可を割り当てる
$permissions | ForEach-Object { New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id -PrincipalId $sp.Id -AppRoleId $_.Id -ResourceId $graphResource.Id }

Delegated permission

Delegated (委任されたアクセス許可) 種別の Microsoft Graph アクセス権限のを付与する場合は、対象の Delegated の権限内容を定義した上で、New-MgOauth2PermissionGrant コマンドを使用します。
Application アクセス許可の付与と違い、Graph API アクセス許可の付与のための AppRoleId 取得は不要になりますが、その分コマンド実行にはクセがあるので注意が必要です。

# Microsoft Graph PowerShell にサインイン
Connect-MgGraph -Scope "Application.ReadWrite.All,DelegatedPermissionGrant.ReadWrite.All" -TenantId "<テナント ID>"
# Graph アクセス許可を付与する対象のマネージド ID 情報を取得
$sp = Get-MgServicePrincipal -ServicePrincipalId "<マネージド ID のオブジェクト ID>"
# Microsoft Graph のサービスプリンシパル情報を取得
$graphResource = Get-MgServicePrincipal -All | Where-Object { $_.ServicePrincipalNames.Contains('https://graph.microsoft.com') }
# 付与したい Delegated アクセス許可の一覧を指定 (複数ある場合は space で繋ぐ)
# 例として、以下では User.Read と offline_access、openid、email のアクセス許可を指定
$scopes = "User.Read offline_access openid email"

New-MgOauth2PermissionGrant コマンドを使用して、マネージド ID に Graph API アクセス権限を付与していきます。
Application の権限付与と異なり、Delegated の権限の場合は、組織の代理として承認 の扱いがあります。テナント内の全メンバーの Delegated アクセス許可を管理者として付与するか、テナント内のメンバー (ユーザー) を対象に Delegated アクセス許可を付与するかによって、パラメータが一部異なります。

### アクセス許可を割り当てる
# 特定のプリンシパル (単一のテナントメンバー) の承認をする場合
New-MgOauth2PermissionGrant -ClientId $sp.Id -ResourceId $graphResource.Id -Scope $scopes -ConsentType "Principal" -PrincipalId "{対象ユーザーのオブジェクト ID}"
# 組織の代理として承認 (テナント内の全メンバー分の承認をする場合)
New-MgOauth2PermissionGrant -ClientId $sp.Id -ResourceId $graphResource.Id -Scope $scopes -ConsentType "AllPrincipals"

コマンド実行時の注意

New-MgOauth2PermissionGrant コマンドは、すでに管理者として同意 (組織の代理として承認) された Delegated アクセス許可が存在している場合や、特定のプリンシパル (メンバー) にすでに Delegated アクセス許可が付与されている場合は使用ができません。
その場合は Get-MgOauth2PermissionGrant コマンドを使用し、クライアント ID でフィルターして対象の権限付与の ID を取得した後、Update-MgOauth2PermissionGrant コマンドを使用して Delegated アクセス許可を書き換えてください。

Microsoft Graph アクセス許可一覧を取得したい場合

$graphResource で取得した Microsoft Graph サービスプリンシパルオブジェクト以下に対象のクラスがあるので、確認することも可能です。

# Microsoft Graph のサービスプリンシパル情報を取得
$graphResource = Get-MgServicePrincipal -All | Where-Object { $_.ServicePrincipalNames.Contains('https://graph.microsoft.com') }
# Delegated アクセス許可一覧
$graphResource.Oauth2PermissionScopes
$graphResource.Oauth2PermissionScopes.Value # アクセス許可の名称一覧
$graphResource.Oauth2PermissionScopes.Id # アクセス許可の権限ロール ID
$graphResource.Oauth2PermissionScopes.AdminConsentDescription # アクセス許可の説明
# Application アクセス許可一覧
$graphResource.AppRoles
$graphResource.AppRoles.Value # アクセス許可の名称一覧
$graphResource.AppRoles.Id # アクセス許可の権限ロール ID
$graphResource.AppRoles.Description # アクセス許可の説明

Microsoft Graph App マニフェスト

サービスプリンシパルにおける Microsoft Graph App マニフェストの JSON を利用している方は認識があるかもですが、各 Microsoft Graph アクセス許可権限には、一意の権限 ID が割り当てられています。
コマンドでマネージド ID を含むサービスプリンシパルに対して権限付与を行う際も、基本はマニフェスト内容に準じた内容になっている (はず) ので、コマンド実行時の権限ロール ID などの内容をより深く理解したい方は、個別にサービスプリンシパルを作成し、マニフェスト一式を参照してみると良いと思います。

https://learn.microsoft.com/ja-jp/entra/identity-platform/reference-microsoft-graph-app-manifest

参考情報

https://learn.microsoft.com/ja-jp/azure/app-service/scenario-secure-app-access-microsoft-graph-as-app?tabs=azure-powershell#grant-access-to-microsoft-graph

https://learn.microsoft.com/ja-jp/graph/permissions-grant-via-msgraph?pivots=grant-delegated-permissions&tabs=http

https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.applications/new-mgserviceprincipalapproleassignment?view=graph-powershell-1.0

https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/new-mgoauth2permissiongrant?view=graph-powershell-1.0

https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/get-mgoauth2permissiongrant?view=graph-powershell-1.0

https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/update-mgoauth2permissiongrant?view=graph-powershell-1.0

Discussion