Azure PIM の永続アクティブ割り当てを Azure Policy で禁止してみた
こんにちは、クラウド事業本部コンサルティング部のいたくらです。
はじめに
Azure PIM(Privileged Identity Management)では、ロールの割り当てに有効期限を設定し、永続的なアクティブ割り当てを制限できます。
しかし、PIM のロール設定はロールごと・スコープごとに個別設定が必要で、かつ上位スコープの設定が継承されません。管理グループ・サブスクリプション・リソースグループとスコープが増えるほど、設定漏れのリスクが高まります。
本記事では、Azure Policyを使って「永続的なアクティブ割り当て」を一括で禁止する方法を紹介します。
Azure Policyは管理グループやサブスクリプションに割り当てると配下に継承されるため、PIMロール設定の継承問題を解消できます。実際にサブスクリプションスコープで検証した結果もあわせて紹介します。
三行まとめ
- Azure Policy で
roleAssignmentScheduleRequestsのNoExpirationを拒否すれば、永続的なアクティブ割り当てを一括禁止できる - PIM ロール設定はスコープ間で継承されないが、Azure Policy は管理グループから配下に継承されるため設定漏れを防げる
- ServicePrincipal は JIT アクティベーションができないため、
principalTypeエイリアスで除外する
背景:MCSB PA-2 の推奨事項
Microsoft Cloud Security Benchmark(MCSB)の PA-2 では、常設特権(standing privileges)の作成を避け、JIT メカニズムを使用することを推奨しています。
Instead of creating standing privileges, use just-in-time (JIT) mechanism to assign privileged access to the different resource tiers.
引用:MCSB PA-2: Avoid standing access for user accounts and permissions
具体的には、Azure AD PIM(Privileged Identity Management)を使用して、Azure リソースへの JIT 特権アクセスを有効にすることが推奨されています。
制御手段の比較:PIMロール設定とAzure Policy
Azure リソースロールの永続的なアクティブ割り当てを禁止する手段は 2 つあります。
| 観点 | PIM ロール設定 | Azure Policy |
|---|---|---|
| 永続アクティブ禁止 | できる | できる |
| 期間の上限強制 | できる | できない |
| 承認要件・MFA・通知 | できる | できない |
| 適用範囲 | ロールごと・スコープごとに個別設定 | 管理グループに割り当てれば配下に継承 |
| 運用負荷 | ロール数 × スコープ数の設定が必要 | 1 つのポリシーで全ロールをカバー可能 |
| スコープ間の継承 | 継承されない | 継承される |
PIM ロール設定は承認フローや MFA の設定など細かな制御ができますが、スコープごとに個別設定が必要です。一方、Azure Policy は管理グループに 1 つ割り当てるだけで配下すべてに適用されます。
推奨する使い分け
- 永続アクティブ禁止(ガードレール) → Azure Policy で一括制御
- 承認フロー・MFA 等が必要な高権限ロール → PIM ロール設定を個別に追加設定
Azure Policy の実装
ポリシー定義
scheduleInfo.expiration.type エイリアスを使用して、NoExpiration(無期限)のアクティブ割り当てリクエストを拒否するカスタムポリシーを作成します。
{
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Authorization/roleAssignmentScheduleRequests"
},
{
"field": "Microsoft.Authorization/roleAssignmentScheduleRequests/requestType",
"in": [
"AdminAssign",
"AdminExtend",
"AdminRenew"
]
},
{
"field": "Microsoft.Authorization/roleAssignmentScheduleRequests/scheduleInfo.expiration.type",
"equals": "NoExpiration"
},
{
"field": "Microsoft.Authorization/roleAssignmentScheduleRequests/principalType",
"notEquals": "ServicePrincipal"
}
]
},
"then": {
"effect": "deny"
}
}
各条件の意味は以下の通りです。
| 条件 | 説明 |
|---|---|
type = roleAssignmentScheduleRequests |
PIM 経由のロール割り当てリクエストを対象とする |
requestType in AdminAssign, AdminExtend, AdminRenew |
管理者による割り当て・延長・更新を対象とする |
scheduleInfo.expiration.type = NoExpiration |
無期限の割り当てリクエストを検出する |
principalType != ServicePrincipal |
ServicePrincipal は JIT アクティベーションができないため除外する |
NoExpiration を拒否すると、AfterDuration(期間指定)または AfterDateTime(日時指定)のいずれかが必須になります。つまり、このポリシー 1 つで「期限付き必須」を暗黙的に強制できます。
ポリシー定義の作成
Azure CLI で作成する場合、上記の JSON を例えば policy-rule.json として保存し、以下のコマンドを実行します。
az policy definition create \
--name "deny-permanent-active-assignment" \
--display-name "Deny permanent active role assignments" \
--description "Denies role assignment schedule requests with NoExpiration. Service Principals are excluded because they cannot use JIT activation." \
--rules policy-rule.json \
--mode All \
--subscription "<サブスクリプションID>"

ポリシーの割り当て
作成したポリシーをサブスクリプションまたは管理グループに割り当てます。
今回はサブスクリプションに割り当てます。
az policy assignment create \
--name "deny-permanent-active-assignment" \
--display-name "Deny permanent active role assignments" \
--policy "/subscriptions/<サブスクリプションID>/providers/Microsoft.Authorization/policyDefinitions/deny-permanent-active-assignment" \
--scope "/subscriptions/<サブスクリプションID>" \
--enforcement-mode "Default"
実運用では管理グループスコープに割り当てることで、配下のすべてのサブスクリプション・リソースグループに一括適用できます。

動作確認
テスト 1:永続アクティブ割り当て → 拒否されること
PIM 画面から、閲覧者(Reader)ロールを「アクティブ」かつ「永続的にアクティブ」で割り当てを試みます。



Azure Policy によって拒否され、以下のエラーメッセージが表示されました。
'サブスクリプション' でロール '閲覧者' へのメンバー xxxx のロールの割り…
リソース 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' はポリシーによって許可されませんでした。ポリシー識別子: '[{"policyAssignment":{"name":"Deny permanent active role assignments", ...}]'
Azure CLI で直接 PIM API を呼び出した場合も同様に拒否されます。
az rest --method PUT \
--url "https://management.azure.com/subscriptions/<サブスクリプションID>/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/<リクエストID>?api-version=2020-10-01" \
--body '{
"properties": {
"principalId": "<ユーザーオブジェクトID>",
"roleDefinitionId": "/subscriptions/<サブスクリプションID>/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
"requestType": "AdminAssign",
"scheduleInfo": {
"startDateTime": "2026-03-30T14:00:00Z",
"expiration": {
"type": "NoExpiration"
}
}
}
}'
ERROR: Forbidden({"error":{"code":"RequestDisallowedByPolicy", ...}})
エラーレスポンスの evaluatedExpressions を見ると、ポリシー定義の allOf で指定した 4 条件すべてが True と評価されたため、Deny が発動していることがわかります。
エラーレスポンスの詳細(クリックで展開)
{
"error": {
"code": "RequestDisallowedByPolicy",
"target": "<リクエストID>",
"message": "Resource '<リクエストID>' was disallowed by policy.",
"additionalInfo": [
{
"type": "PolicyViolation",
"info": {
"evaluationDetails": {
"evaluatedExpressions": [
{
"result": "True",
"expression": "type",
"expressionValue": "Microsoft.Authorization/roleAssignmentScheduleRequests",
"targetValue": "Microsoft.Authorization/roleAssignmentScheduleRequests",
"operator": "Equals"
},
{
"result": "True",
"expression": "Microsoft.Authorization/roleAssignmentScheduleRequests/requestType",
"expressionValue": "AdminAssign",
"targetValue": ["AdminAssign", "AdminExtend", "AdminRenew"],
"operator": "In"
},
{
"result": "True",
"expression": "Microsoft.Authorization/roleAssignmentScheduleRequests/scheduleInfo.expiration.type",
"expressionValue": "NoExpiration",
"targetValue": "NoExpiration",
"operator": "Equals"
},
{
"result": "True",
"expression": "Microsoft.Authorization/roleAssignmentScheduleRequests/principalType",
"targetValue": "ServicePrincipal",
"operator": "NotEquals"
}
]
},
"policyDefinitionId": "/subscriptions/<サブスクリプションID>/providers/Microsoft.Authorization/policyDefinitions/deny-permanent-active-assignment",
"policyDefinitionName": "deny-permanent-active-assignment",
"policyDefinitionDisplayName": "Deny permanent active role assignments",
"policyDefinitionEffect": "deny"
}
}
]
}
}
テスト 2:期限付きアクティブ割り当て → 成功すること
同じ PIM 画面で、「永続的にアクティブ」のチェックを外し、期限付き(例:1 年間)で割り当てを実行します。


期限付きの割り当ては Azure Policy に拒否されず、正常に作成されました。
注意点
IAM ブレードからの割り当てはブロックされない
Azure Portal の IAM ブレード(サブスクリプション → アクセス制御 (IAM) → ロールの割り当ての追加)から作成した割り当ては、Azure Policy でブロックされませんでした。

| 操作経路 | 使用される API | Azure Policy による制御 |
|---|---|---|
| PIM 画面からの割り当て | roleAssignmentScheduleRequests |
ブロックされる |
| IAM ブレードからの割り当て | roleAssignments(クラシック) |
ブロックされない |
| Azure CLI で PIM API を呼び出し | roleAssignmentScheduleRequests |
ブロックされる |
IAM ブレードはクラシックな roleAssignments API を使用しており、今回の Azure Policy が対象とする roleAssignmentScheduleRequests とは異なるリソースタイプです。そのため、Azure Policy だけでは完全な制御にはなりません。
PIM ロール設定の「永続するアクティブな割り当てを許可する」のチェックを外す設定と併用することで、両方の経路をカバーできます。
| 制御対象 | PIM ロール設定 | Azure Policy |
|---|---|---|
PIM 経由の割り当て(roleAssignmentScheduleRequests) |
制御可能 | 制御可能 |
クラシック API の割り当て(roleAssignments) |
制御可能 | 制御不可 |
| スコープ間の継承 | 継承されない | 継承される |
つまり、Azure Policy をガードレールとして導入しつつ、PIM ロール設定も併用するのが最も堅牢な構成です。
ServicePrincipal の除外
ServicePrincipal は対話的なログインができないため、PIM の JIT アクティベーションを利用できません。そのため、ポリシー定義で principalType エイリアスを使って除外しています。
Azure Policy で使用できるエイリアスは az provider show コマンドで調べられます。例えば principalType が使えるかどうかは以下で確認できます。
az provider show --namespace Microsoft.Authorization \
--resource-type roleAssignmentScheduleRequests \
--query "resourceTypes[0].aliases[?contains(name, 'principalType')]"
緊急時のアクセス経路
Azure リソースロールには専用の緊急アクセスアカウントの概念はありません。緊急時のアクセスは Entra ID 側の仕組みで確保されます。
- Entra ID の Global Administrator(緊急アクセスアカウント、永続アクティブ)でサインイン
- Entra 管理センターで「Access management for Azure resources」を有効化
- ルートスコープ(
/)で User Access Administrator に自動昇格
このため、Azure リソースロールについては全ロールで永続アクティブを禁止しても、緊急時のアクセス経路には影響しません。
ライセンス要件
PIM の利用には以下のいずれかのライセンスが必要です。
- Microsoft Entra ID P2
- Microsoft Entra ID Governance
まとめ
- Azure Policy で
roleAssignmentScheduleRequestsのNoExpirationを拒否することで、PIM 経由の永続的なアクティブ割り当てを一括禁止できる - PIM ロール設定はスコープごとに個別設定が必要で継承されないが、Azure Policy は管理グループから配下に継承されるため設定漏れのリスクを低減できる
- ただし、IAM ブレード(クラシック API)からの割り当てはブロックされないため、PIM ロール設定との併用が推奨される
- ServicePrincipal は
principalTypeエイリアスで除外する
Azure Policy だけでは IAM ブレードからのクラシック API 経由の割り当てをブロックできないことには少し驚きました。
Azure Policy と PIM ロール設定はそれぞれカバー範囲が異なるため、どちらか一方ではなく併用することが重要だと感じました。
この記事がどなたかのお役に立てれば幸いです。
以上、クラウド事業本部コンサルティング部のいたくら(@itkr2305)でした!






