Azure RBAC PIM 承認データをapp-onlyトークンで取得できない理由と対策|ARM roleAssignmentApprovalsとMicrosoft Graph

Azure RBAC の PIM 承認データを自動で集めたいのに、ARM の roleAssignmentApprovals が app-only トークンを受け付けずに詰まるケースがあります。本記事では、なぜユーザー トークンが必須なのか、Graph API での代替可否、そして現場で使える回避策と権限設計の注意点を整理します。

目次

起きている問題:ARM の roleAssignmentApprovals を app-only で呼べない

Azure の特権管理(PIM: Privileged Identity Management)を使って Azure RBAC(ロール割り当て)を運用していると、「誰が、いつ、どのロールを要求し、誰が承認したか」という承認データを定期的に取得したくなります。ところが、Azure Resource Manager(ARM)の次のエンドポイントを叩くと、アプリ専用トークン(client credentials / app-only)ではエラーになり、情報を取得できません。

GET https://management.azure.com/providers/Microsoft.Authorization/roleAssignmentApprovals?api-version=...
Authorization: Bearer {app-only access token}

一方で Microsoft Graph には PIM 関連 API があり、アプリケーション権限(app-only)で参照できるものも存在します。そのため「ARM でも同じように user-less(ユーザーなし)で取得できないのか?」という疑問が生まれやすいポイントです。

観点ARM(Azure Resource Manager)Microsoft Graph
主な用途Azure リソースの管理プレーン(リソース作成・設定・RBAC)Entra ID / Microsoft 365 の統合 API(ディレクトリ・監査・一部の PIM)
PIM 承認データの取得roleAssignmentApprovals はユーザー トークン必須エンドポイント次第で app-only 可能なものがある
app-only の適性管理操作は app-only で可能なものも多いが、ユーザー文脈が必要な API もあるアプリケーション権限での参照系が比較的充実(ただし範囲に差がある)

結論:ARM の PIM 承認エンドポイントはユーザー トークン必須

ポイントはシンプルで、ARM の PIM 承認(roleAssignmentApprovals)を参照する API は、委任された権限(delegated)を前提に設計されているという点です。クライアント資格情報フローで取得した app-only トークンでは、呼び出しが成立しません。

ここで重要なのは、これは「アプリ登録の権限が足りない」だけの話ではなく、トークンにユーザー主体(ユーザーのサインイン)が含まれていないこと自体が要因になっている点です。PIM の承認ワークフローは、監査の観点でも「誰の操作か」が前提になりやすく、ユーザー文脈を要求する API が存在します。

なぜ app-only では失敗するのか:トークンと権限モデルの違い

同じ「アクセストークン」でも、委任(ユーザー)とアプリ(app-only)では意味が違います。Azure API を設計・運用するときは、まずこの違いを整理すると迷いが減ります。

項目委任された権限(ユーザー トークン)アプリケーション権限(app-only)
主体ユーザー(+アプリ)アプリ(サービスプリンシパル/マネージドID)
典型フロー認可コード、デバイスコード、対話サインイン(MSAL/ブラウザ)クライアント資格情報(証明書/シークレット)
強みユーザーの文脈・条件付きアクセス・MFA を前提にできるサーバー間通信、バッチ、無人実行に向く
弱み無人実行に工夫が必要(対話要素が残りやすい)「ユーザーとしての操作」や「承認者の文脈」を要求する API では弾かれることがある
PIM 承認(ARM roleAssignmentApprovals)取得できる取得できない

エラーの出方と、ありがちな勘違い

roleAssignmentApprovals を app-only で呼ぶと、環境や API バージョンによって文言は揺れますが、方向性としては「ユーザーがいない」「この呼び出しはユーザーコンテキストが必要」という系統のエラーになります。権限(ロール)を増やしても解決しないのが落とし穴です。

症状よくある原因切り分けのコツ
app-only だと必ず失敗するAPI が委任トークン前提同じ API をユーザー トークン(例:Azure CLI ログイン)で叩くと成功する
管理者ロールを付与しても改善しない権限不足ではなくトークン種別の問題JWT をデコードし、oid/upn 等のユーザー情報が存在するか確認する
Graph では取れるのに ARM では取れないAPI の設計思想・対応範囲の差「同じ PIM」でも Azure リソース RBAC と Entra ロール は API の置き場が違う

実務的な対応:まず要件を分解して「取るべきデータ」を決める

「PIM 承認データ」と一口に言っても、欲しい情報はケースで違います。ARM の roleAssignmentApprovals が取れないと分かった時点で、次のように要件を分解すると代替案が見つかりやすくなります。

  • 未処理の承認待ちを一覧したいのか(運用担当のワークキュー)
  • 承認・却下の履歴を集計したいのか(監査・レポート)
  • 最終的に付与されたロール割り当てを確認できればよいのか(棚卸し)
  • Azure RBAC(Azure リソース)と Entra ロール(ディレクトリ)どちらの PIM なのか

この分解ができると、「承認そのもの」ではなく「結果(ロール割り当て)」や「監査ログ」で要件を満たせるケースが見えてきます。

代替案の全体像:ARM に固執しない設計が鍵

ここからは「ARM roleAssignmentApprovals を app-only で取得する方法がない」という前提で、現場で採用されやすい代替パターンを整理します。

パターン狙いメリット注意点
Microsoft Graph の PIM API を使うapp-only で取れる範囲を最大化無人実行と相性が良い/Entra 系データは集めやすいAzure リソース RBAC の承認データが完全に同等とは限らない
ユーザー トークンで ARM を呼ぶ(サービスアカウント)roleAssignmentApprovals を確実に取得ARM の情報をそのまま取れる対話サインイン要素/トークン保護/運用負荷が増える
ログ(監査・アクティビティ)で代替する承認・付与の事実を追跡参照系 API だけで集計できることが多い「承認待ち一覧」のようなリアルタイム運用には不向き
結果(ロール割り当て)を棚卸し対象にする最終状態を可視化RBAC の棚卸し・最小権限に直結「誰が承認したか」まで必要なら追加情報が要る

Microsoft Graph 側でどこまで代替できるか

Microsoft Graph には PIM に関連するエンドポイントがあり、アプリケーション権限(app-only)で参照できるものもあります。設計の第一候補は「Graph で取れるデータは Graph に寄せる」です。

Graph へ寄せやすいケース

  • Entra ID(ディレクトリ)側のロール管理、監査、ユーザー/グループ情報と合わせてレポートしたい
  • 複数テナント・複数サブスクリプションにまたがるデータを、同一の認可モデルで集約したい
  • バッチ処理で定期取得し、データレイク/Log Analytics/BI に連携したい

Graph だけでは不足しやすいケース

  • 「Azure RBAC の PIM 承認待ち」を運用キューとして扱い、即時に一覧化したい
  • ARM の特定エンドポイントでしか得られないフィールド(承認ステージや内部 ID など)が必須
  • 既存運用が ARM のデータ構造前提で作り込まれている(データモデル移行コストが高い)

つまり、Graph は強力な選択肢ですが、「Azure リソース PIM を完全に app-only で置き換える」という観点では、要件次第で不足が残る可能性があります。

Graph を app-only で呼ぶ最小例(参考)

Graph 側で代替できる範囲があるなら、app-only のままデータ収集パイプラインに載せられます。以下は「クライアント資格情報フローで Graph トークンを取得し、PIM 関連の参照 API を呼ぶ」最小例です(実際のエンドポイントや必要権限は、対象が ディレクトリ ロールか グループか Azure リソースかで変わります)。

# 1) トークン取得(アプリ専用)
curl -sS -X POST "https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id={client-id}" \
  -d "client_secret={client-secret}" \
  -d "scope=https://graph.microsoft.com/.default" \
  -d "grant_type=client_credentials"

# 2) 取得した access_token を使って Graph を呼ぶ
curl -sS -H "Authorization: Bearer {access_token}" \
  "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignmentScheduleRequests"

Graph の PIM 系エンドポイントは v1.0 と beta で機能差が出ることがあります。運用で使う場合は、できるだけ v1.0 に寄せつつ、beta を使うときは「仕様変更・フィールド変更」が起き得る前提でデータモデルを疎結合にしておくと安全です。

対象Graph エンドポイント例用途のイメージ補足
Entra ロール(ディレクトリ)/roleManagement/directory/roleAssignmentScheduleRequests割り当て要求(スケジュール要求)の参照承認プロセスを含む運用は要件により追加 API が必要
PIM for Groups/identityGovernance/privilegedAccess/group/assignmentScheduleRequestsグループの特権割り当て要求の参照グループ管理と合わせて扱いやすい
PIM for Azure Resources/identityGovernance/privilegedAccess/azureResources/roleAssignmentRequests(beta の例)Azure リソース側の要求情報を参照対応状況や取得できるフィールドは変わり得る

どうしても ARM の承認データが必要な場合の現実解

要件として「ARM の roleAssignmentApprovals でしか満たせない」場合、現時点での現実解はユーザー トークンで ARM を呼ぶことです。ここでは、実装・運用で事故りやすいポイントを先回りして整理します。

最小構成の考え方

  • アプリ登録は「委任された権限」を前提にする(ユーザーサインインを伴う)
  • 実行主体は専用の運用ユーザー(サービスアカウント)に寄せる
  • 強固なサインイン制御(MFA/条件付きアクセス/サインイン場所)を必ず組み合わせる
  • 取得処理の実行ログ(いつ誰が実行したか)と、取得したデータの保管先(改ざん耐性)を設計に含める

Azure CLI を使った確認(切り分けに便利)

まず「ユーザー トークンなら取れる」ことを確認すると、問題がトークン種別にあると確証が得られます。運用端末で Azure CLI を使う例です。

# ユーザーとしてサインイン(対話)
az login

# ARM 向けユーザー トークンを取得
ARM_TOKEN=$(az account get-access-token --resource https://management.azure.com/ --query accessToken -o tsv)

# roleAssignmentApprovals を呼び出し(例)
curl -sS -H "Authorization: Bearer ${ARM_TOKEN}" \
  "https://management.azure.com/providers/Microsoft.Authorization/roleAssignmentApprovals?api-version=YYYY-MM-DD"

この呼び出しが成功する一方で、同じリクエストに app-only トークンを入れると失敗するなら、原因は「権限不足」ではなくユーザー文脈が必須であることが濃厚です。

無人化を狙う場合にありがちな落とし穴

  • 長期保存したリフレッシュトークンに依存すると、運用・セキュリティのリスクが跳ね上がる
  • 条件付きアクセスやサインインリスクのポリシーにより、突然トークン更新が止まることがある
  • 特権ユーザーでの運用は監査負荷が増えるため、必要最小限のロールとスコープで設計する

「完全無人」にこだわるほど、PIM の思想(人の承認・監査)と衝突しやすくなります。取得タイミングを「日次の監査レポート」へ寄せるなど、業務設計側を調整できると一気に楽になります。

ログ・監査で代替する発想:承認“待ち”ではなく承認“結果”を集める

承認待ちをリアルタイムで拾う必要がない場合、監査ログやアクティビティログ(Azure Monitor / Log Analytics)に寄せると、app-only でも扱いやすいことがあります。たとえば次のような設計です。

  • ロール割り当ての作成/削除イベントを収集して「いつ誰に何が付与されたか」を追跡する
  • PIM 操作に関連する監査イベントを収集して「要求・承認・却下の痕跡」を集計する
  • 収集先を Log Analytics や SIEM に統一し、検索・アラート・保管を一括で扱う

この方法は、roleAssignmentApprovals のような「ワークキュー」そのものではなく、監査・可視化に強いアプローチです。「承認待ち一覧」ではなく「承認の履歴と結果」がゴールなら、検討価値が高いです。

要件別のおすすめルート(判断表)

あなたの要件優先候補補足
無人バッチで PIM 関連情報を集めたいMicrosoft Graph(app-only 対応範囲を活用)Azure RBAC 承認“待ち”が必須かどうかで分岐
Azure RBAC の承認待ちを一覧して運用したいARM(ユーザー トークンで呼ぶ)サービスアカウント+強いサインイン制御が現実的
監査・レポートが目的で、承認結果が分かればよいログ/監査(Activity Log / Audit Logs / Log Analytics)データモデルを「イベント駆動」に寄せると強い
最終的な RBAC 割り当ての棚卸しが目的ロール割り当ての一覧取得(ARM/Graph の参照系)承認者情報が要件ならログと組み合わせる

セキュリティと権限設計のチェックリスト

PIM を扱う自動化は、便利さと引き換えに特権の集中が起きやすい領域です。実装前に次の観点を必ず確認してください。

チェック項目推奨理由
最小権限取得対象スコープ(管理グループ/サブスク/リソースグループ)を絞る万一の漏えい時の影響範囲を限定
実行主体専用アカウント/専用アプリに分離する権限の横展開を防ぎ、監査もしやすい
認証強度MFA と条件付きアクセスを強制し、実行元を制限「特権の自動化」を狙った攻撃への耐性を上げる
秘密情報の管理証明書/シークレット/トークンは Key Vault 等に保管し、ローテーションを前提にする長期固定は漏えいリスクが高い
監査取得処理の実行ログ、API 呼び出しログ、保存データの改ざん検知を用意「誰がいつ何を見たか」も監査対象になりやすい

よくある質問

サービスプリンシパルに Owner を付ければ app-only で取れますか?

いいえ。roleAssignmentApprovals の問題は「権限の強さ」ではなく、トークンがユーザーを含まない(委任されていない)ことに起因します。ロールを強くしても、API が要求する前提が変わらない限り解決しません。

マネージド ID なら取れますか?

マネージド ID も本質的には app-only(アプリ主体)です。したがって roleAssignmentApprovals のようにユーザー トークンを要求する API では、同じ壁にぶつかります。

Graph を使えば Azure RBAC の承認情報も完全に取れますか?

Graph には PIM 関連 API があり app-only で扱えるものもありますが、Azure リソース RBAC の承認ワークフローを ARM と同等に扱えるかは要件次第です。まず「承認待ち一覧が必須か」「履歴と結果で足りるか」を分解し、Graph+ログの組み合わせで満たせないかを検討するのが現実的です。

まとめ:PIM 承認データ取得は「ARM にこだわるほど難易度が上がる」

  • ARM の roleAssignmentApprovals はユーザー トークン必須で、app-only では取得できません。
  • 自動化したいなら、Microsoft Graph の PIM API で代替できる範囲を最大化するのが第一候補です。
  • 要件が「承認待ち」ではなく「監査・棚卸し」なら、ログ/結果データに寄せることで無人化しやすくなります。
  • どうしても ARM が必要な場合は、サービスアカウント+委任トークンを前提に、最小権限と監査を含めた設計にしましょう。

この記事を書いた人

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

コメント

コメントする

目次