Azure SQLのCREATE USER FROM EXTERNAL PROVIDERで出る「Server identity does not have the required permissions to access the MS graph」エラーの原因と解決策

Azure SQL Databaseでマイクロサービス用のユーザー割り当てマネージドID(UAMI)をEXTERNAL PROVIDERユーザーとして自動作成しようとすると、「Server identity does not have the required permissions to access the MS graph」というエラーで止まるケースがよくあります。本記事では、このエラーの正体と、Azure DevOpsパイプラインから安全かつ再現性高く解消するための考え方・設定手順・実装のポイントを徹底解説します。

目次

どんなときに「Server identity does not have the required permissions…」が出るのか

まずは、この記事で扱う代表的な構成を整理します。

  • Azure SQL Database(論理サーバー)に サーバーIDとして UAMI を割り当て
  • Azure DevOps パイプラインから サービス プリンシパル(SPN) で Azure SQL に接続
  • パイプラインの中で sqlcmd を使い、マイクロサービス用の ユーザー割り当てマネージドID(UAMI) を Azure SQL Database 上の EXTERNAL PROVIDERユーザー として作成
  • 実行する T-SQL は次のようなもの:
-- 対象アプリDB上で実行
CREATE USER [microservice-umi] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [microservice-umi];

このとき、次のエラーメッセージが返ってきます。

Server identity does not have the required permissions to access the MS graph.

Azure DevOps のサービスコネクション(SPN)には Microsoft Graph の権限を付与しているのに、なぜかエラーになる──ここがハマりポイントです。

関係するリソースの整理

役割具体的な主体主な役割
SQLサーバーID(Server identity)論理サーバーに割り当てた UAMI / SMIAzure SQL が Microsoft Entra ID / Microsoft Graph に問い合わせるときに使う ID
接続元SPNAzure DevOps サービスコネクションのアプリ登録パイプラインから Azure SQL へログインするための ID
ターゲットUAMIマイクロサービス用 UAMI(例: microservice-umi)アプリ本体が利用するマネージドID。DB上では EXTERNAL USER として表現
Entra 管理者Privileged Role Administrator / Entra 管理者などDirectory Readers や Graph 権限を割り当てる人

重要なのは、Microsoft Graph にアクセスしているのは「接続元SPN」ではなく「SQLサーバーID」 だという点です。これが分からないと、どこに権限を付ければいいかずっと迷子になります。

エラーメッセージの正体:Graph にアクセスできないのは誰か?

CREATE USER FROM EXTERNAL PROVIDER の裏側

CREATE USER ... FROM EXTERNAL PROVIDER は、Azure SQL が内部的に Microsoft Entra ID(旧 Azure AD)に対して「この名前のプリンシパルは存在するか?」「どの Object ID / App ID か?」を問い合わせる仕組みになっています。この問い合わせは Microsoft Graph 経由で実行されます。

このとき、Graph にアクセスするのは「今 SQL に接続しているユーザー」ではなく、論理サーバーに設定したサーバーID(Managed Identity) です。Microsoft 公式ドキュメントでも、「サーバーIDに Directory Readers か、User.Read.All / GroupMember.Read.All / Application.Read.All の Graph 権限を付与せよ」と明記されています。

Server identity とは何か

Azure SQL Database の「サーバーID」は、論理サーバーに紐づく マネージドID のことです(SMI でも UAMI でも可)。この ID は次の用途で使われます。

  • Entra ユーザー / グループ / サービスプリンシパルの存在確認
  • グループメンバーシップの展開(グループを指定して権限付与したときなど)
  • 一部の Entra 認証機能の内部処理

そのため、CREATE USER FROM EXTERNAL PROVIDER を実行した瞬間、サーバーIDで Microsoft Graph に対してディレクトリ参照が行われるのですが、このとき必要な権限が足りないと、まさに今回のエラー:

Server identity does not have the required permissions to access the MS graph.

が発生します。

「接続に使っているSPN」と「サーバーID」は別物

もう一度整理すると、次のような関係になります。

誰の権限?何に使われる?今回のエラーとの関係
接続SPNAzure SQL へのログイン、T-SQL の実行権限CREATE USER を「実行する権限」には関係するが、Graph エラーの直接の原因ではない
サーバーID(Managed Identity)Entra 参照(Graph 経由)、グループ展開Graph エラーの原因はほぼここ。Directory Readers / Graph 権限が必要
ターゲットUAMIアプリ実行時の認証CREATE USER の対象だが、今回のエラーの 発生原因 ではない

つまり、SPN にいくら Graph 権限を足しても、このエラーは解決しません。見るべきはいつも「サーバーIDの権限」です。

公式な要件:サーバーIDには Directory Readers または特定の Graph 権限が必要

Microsoft の公式ドキュメントでは、Azure SQL Database / Azure SQL Managed Instance で Microsoft Entra 認証と管理操作を行うために、サーバーIDに次のいずれかを付与するよう説明されています。

  • Directory Readers ロール(推奨されるシンプルな方法)
  • または、次の Microsoft Graph アプリケーション権限 のセット
    • User.Read.All
    • GroupMember.Read.All
    • Application.Read.All

このロール/権限は、サブスクリプションやリソースグループではなく、Microsoft Entra テナントに対して割り当てる必要がある点に注意してください。

多くの環境では、Graph の細かい権限セットよりも、Directory Readers ロールをサーバーIDに付与する方が簡単でトラブルも少ないため、本記事でもこの方法を中心に解説します。

正しい対処:サーバーIDに Directory Readers を割り当てる

全体の流れ

エラー解消までの大まかな流れは次の通りです。

  1. Azure SQL サーバーにマネージドID(UAMI / SMI)が割り当てられていることを確認
  2. そのマネージドID(サーバーID)の サービスプリンシパル を Entra 上で特定
  3. サーバーIDに対して Directory Readers ロールをテナントスコープで割り当て
  4. 反映後、再度 CREATE USER FROM EXTERNAL PROVIDER を実行

以下、ポータル操作ベースで具体的に見ていきます。

1. サーバーIDを確認する(Azure ポータル)

  1. Azure ポータルで対象の SQL サーバー(論理サーバー) を開きます(例: umi-weu-srv)。
  2. 左メニューの [セキュリティ] > [ID] を開きます。
  3. 「システム割り当て済み」または「ユーザー割り当て」で、サーバーに紐づいているマネージドIDを確認します。
  4. ここに表示される プリンシパルID / クライアントID を控えておきます。

論理サーバー名を使って Entra 側のエンタープライズ アプリケーションを検索することもできます。

2. Directory Readers ロールをサーバーIDに割り当てる

次に、Entra 管理センターで、サーバーIDに Directory Readers ロールを割り当てます。この操作は Privileged Role Administrator 以上 のロールを持つユーザーのみ実行できます。

  1. Microsoft Entra 管理センターを開きます。
  2. 左メニューから [ロールと管理者](Roles and administrators)を選択します。
  3. ロール一覧から Directory Readers を探してクリックします。
  4. [割り当ての追加] をクリックします。
  5. 「メンバーの選択」で、先ほど控えたサーバーID(論理サーバー名や Client ID で検索)を選択します。
  6. 追加を完了します。

これで、SQL サーバーのマネージドIDが Microsoft Graph を通してディレクトリ情報を読み取れるようになり、CREATE USER FROM EXTERNAL PROVIDER 実行時の Graph エラーは解消されるはずです。

3. 反映後に T-SQL を再実行

ロール割り当ての反映には数分かかる場合があります。時間をおいてから、再度 Azure DevOps のパイプラインを実行し、CREATE USER を含むステップを試します。

-- 必ずターゲットのアプリDB側で実行
CREATE USER [microservice-umi] FROM EXTERNAL PROVIDER;

-- 必要最小限のロールだけ付与する例
ALTER ROLE db_datareader ADD MEMBER [microservice-umi];

これで、サーバーIDが Graph を使って microservice-umi(UAMI)の情報を解決できるようになり、ユーザー作成が成功します。

PowerShell / Microsoft Graph で Directory Readers を自動付与する例

本番運用では、Entra ロール付与も Infrastructure as Code 化したいケースがあります。その場合は、Microsoft Graph PowerShell を用いて Directory Readers をサーバーIDに割り当てることができます。

概要イメージは次の通りです。

# 前提:
# - 実行ユーザーは Privileged Role Administrator 以上
# - Microsoft.Graph モジュールがインストール済み

$tenantId   = "<TenantId>"
$serverName = "<LogicalServerName>"   # 例: umi-weu-srv

Connect-MgGraph -TenantId $tenantId `
  -Scopes "RoleManagement.ReadWrite.Directory,Application.Read.All"

# Directory Readers ロールを取得
$dirReadersRole = Get-MgDirectoryRole -Filter "displayName eq 'Directory Readers'"

# 論理サーバーに紐づくサービス プリンシパルを取得
$serverSp = Get-MgServicePrincipal -Filter "displayName eq '$serverName'"

# まだメンバーでなければ Directory Readers に追加
$body = @{
  '@odata.id' = "https://graph.microsoft.com/v1.0/directoryObjects/$($serverSp.Id)"
}

New-MgDirectoryRoleMemberByRef `
  -DirectoryRoleId $dirReadersRole.Id `
  -BodyParameter $body

このように、ロール付与まで含めて自動化しておけば、新しい環境を展開したときにも Graph 権限抜けによるエラーを防止 できます。

Graph アプリケーション権限で解決する場合の注意点

Directory Readers を使わず、Graph のアプリケーション権限だけで解決する方法もあります。その場合は、サーバーID(Managed Identity)のエンタープライズ アプリに対して、次の 3 つセットを付与する必要があります。

  • User.Read.All
  • GroupMember.Read.All
  • Application.Read.All

よくあるミスは、Application.Read.All だけを付けてしまうケースです。これではユーザーやグループ情報を読めないため、結局 CREATE USER FROM EXTERNAL PROVIDER は失敗します。

また、Managed Identity に Graph 権限を付与するには、Microsoft Graph PowerShell などを利用して アプリロール割り当て を行う必要があり、Directory Readers ロール付与よりも作業が複雑になります。

そのため、多くの組織では次のような方針が現実的です。

  • 基本方針:Directory Readers ロールをサーバーIDに付与する
  • 特別なセキュリティ要件があり、Directory Readers を避けたい場合のみ Graph 権限セットで調整する

どうして SPN に Graph 権限を足しても直らないのか

ここまで読むと分かる通り、今回のエラーは サーバーIDが Graph へアクセスできない ことが原因です。

つまり、次のような対処では解決しません。

  • Azure DevOps の SPN(サービスコネクション)に User.Read.All などの Graph 権限を追加する
  • SPN をテナントの Directory Readers にする

これらは SPN が自分で Graph にアクセスするときには効きますが、Azure SQL から Graph にアクセスするときには使われません。Azure SQL にとっては「接続元ユーザー」と「サーバーID」は別の主体だからです。

パイプライン側の実装ポイント

エラー解消の本丸は Directory Readers ですが、パイプライン側にもいくつか押さえておきたいポイントがあります。

1. 接続 SPN は「Entra 管理者」としてサーバーに接続できるか

Azure SQL で Microsoft Entra ユーザー/サービスプリンシパルを作成するには、Entra ユーザーとして十分な権限が必要です。特に最初のユーザー作成は「Microsoft Entra 管理者」として接続する必要があるとドキュメントで説明されています。

  • Azure SQL 論理サーバーの「Microsoft Entra 管理者」に、管理用 SPN(または管理用ユーザー)を設定
  • Azure DevOps のサービスコネクションは、その SPN で Azure SQL に接続する

これができていないと、Graph 周りの権限を正しても、そもそも CREATE USER を実行する SQL 権限が足りずに別のエラーで止まります。

2. OIDC(ワークロードIDフェデレーション)でシークレットレスにする

接続に使う SPN のシークレットを YAML に直書きするのは避け、Azure DevOps の Workload Identity Federation(OIDC) や Key Vault 連携を利用してトークンを取得する構成がおすすめです。

  • Azure DevOps 側で Entra アプリに対する フェデレーション資格情報 を設定
  • パイプラインからはシークレットを持たずに az login --federated-token で認証
  • そのトークンを使って sqlcmd で Azure SQL に接続

これにより、権限管理の軸を「Entra ロールとアプリ割り当て」に統一でき、運用負荷とリスクを下げられます。

3. CREATE USER は必ずアプリDBで実行する

CREATE USER は、そのユーザーを作りたい 個々のデータベースのコンテキスト で実行する必要があります。誤って master データベースで実行すると、「ユーザーは作れたがアプリDBには存在しない」という状態になり、権限トラブルの原因になります。

-- NG: master で実行してしまう
USE master;
CREATE USER [microservice-umi] FROM EXTERNAL PROVIDER;

-- OK: アプリケーションDBで実行
USE appdb;
CREATE USER [microservice-umi] FROM EXTERNAL PROVIDER;

4. 付与するロールは最小限にする

マイクロサービス用 UAMI には、原則として 読み取り専用 など、必要最低限のロールのみを付与します。

パターン付与するロール用途
読み取り専用 APIdb_datareader参照系クエリのみ発行する Web API
CRUD API個別の GRANT(INSERT/UPDATE/DELETE など)最低限のテーブル/操作だけ許可したい場合
管理系ツールdb_owner(慎重に)管理用ツールなど広い権限が必要な場合

「とりあえず db_owner を付けておく」は後から必ず後悔するので、ロール設計も自動化スクリプト内で明示しておきましょう。

Graph を使わずに CREATE USER する裏ワザ(SID 指定)

UMI を使う場合、Azure SQL Database では Microsoft Graph を経由せずに Entra ユーザーを作成する特殊な構文も用意されています。

CREATE USER [microservice-umi] WITH
    SID  = 0x&lthash化された ObjectId>,
    TYPE = E;

このパターンでは、Entra の Object ID を SID として直接指定することで、Azure SQL が Graph に問い合わせる必要をなくします。ただし、

  • Object ID を間違えても Azure SQL 側では検証されない
  • Object ID の取得・管理を自分で正しく行う必要がある

といった注意点があり、ディレクトリ情報の正しさを自分で担保できる場面向けの上級テクニックです。一般的なパイプライン構成では、やはり Directory Readers をサーバーIDに付与して FROM EXTERNAL PROVIDER を使う方が安全です。

よくある誤解とアンチパターン

最後に、このエラー周りでよく見かける誤設定をまとめておきます。

誤解 / アンチパターンなぜダメか正しい考え方
SPN に Graph 権限を付ければ良いと思っているGraph にアクセスするのはサーバーIDであり、SPN ではないDirectory Readers / Graph 権限は サーバーID に付与する
サーバーIDのエンタープライズアプリに Application.Read.All だけ付けるユーザー/グループ情報を読めず、必要な情報が揃わないGraph 権限で解決するなら 3 つセット(User.Read.All / GroupMember.Read.All / Application.Read.All)
Entra ロールをサブスクリプション・リソースグループに付けようとするDirectory Readers は Entra の「ディレクトリ ロール」であり、ARM RBAC とは別物Microsoft Entra 管理センターの「ロールと管理者」からロールを割り当てる
master データベースで CREATE USER してしまうアプリDBにユーザーが現れず、接続エラーになる必ずターゲットDBに USE してから CREATE USER する

最終チェックリスト

本番前に次のチェックリストを確認しておくと安心です。

  • [ ] SQL サーバー(論理サーバー)に マネージドID(UAMI または SMI) が割り当てられている
  • [ ] その サーバーID に Directory Readers が テナントスコープ で付与されている(または Graph 権限 3 点セット)
  • [ ] サーバーの Microsoft Entra 管理者として、接続 SPN(またはユーザー)が DB にサインインできる
  • [ ] CREATE USER は必ずアプリDBで実行している(master ではない)
  • [ ] 付与している DB ロールは 必要最小限 に絞っている
  • [ ] パイプライン内で SPN のシークレットを直書きしておらず、OIDC や Key Vault を使っている

まとめ:見るべき権限は「接続元」ではなく「サーバーID」

「Server identity does not have the required permissions to access the MS graph」というメッセージは直訳すると「SQL サーバーの ID が、MS Graph へアクセスするための権限を持っていません」という意味に他なりません。

ポイントを一文にまとめると、

「接続に使う SPN ではなく、Azure SQL サーバーのマネージドID(サーバーID)に Directory Readers(または所定の Graph 権限)を割り当てる」

これさえ押さえておけば、Azure DevOps パイプラインからの EXTERNAL PROVIDER ユーザー自動作成は、安定して再現可能な仕組みにできます。構成管理・権限管理まで含めて IaC 化し、安心してマネージドIDベースのマイクロサービス認証を活用していきましょう。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次