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 が必要な場合は、サービスアカウント+委任トークンを前提に、最小権限と監査を含めた設計にしましょう。

コメント