Expose ValidationLevel so what-if can run under a least-privilege identity

オープン
#954 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
78/100
issue の種類
機能追加
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
azure, powershell
領域
cloud, devops, security

調査の方向性

Start in src/internal/functions/New-AzOpsDeployment.ps1 and trace how $parameters is assembled before the what-if command call. Add the documented Core.WhatIfValidationLevel setting while preserving the Provider default, then verify that what-if receives the setting and that ProviderNoRbac supports least-privilege validation without changing existing behavior.

索引モデルが issue の本文から書いたものです。

説明

Summary

New-AzOpsDeployment never passes -ValidationLevel to the what-if cmdlets, so ARM always applies the default Provider. Provider runs preflight as a real deployment and checks write permission on every resource in the template. The practical result is that Invoke-AzOpsPush -WhatIf cannot run under a least-privilege identity — the Validate pipeline must use the same principal as Push.

ARM already supports the fix. ValidationLevel: ProviderNoRbac performs full template and provider validation but checks only read permission per resource. AzOps just has no way to ask for it.

Current behaviour

In src/internal/functions/New-AzOpsDeployment.ps1 the what-if call is:

$results = & $whatIfCommand @parameters -ErrorAction Continue -ErrorVariable resultsError

$parameters is built up through the function and never contains a ValidationLevel entry. There is no PSFConfig setting for it either — the only what-if related key is Core.WhatifExcludedChangeTypes.

Repro
  1. Give the Validate pipeline identity a role with */read, Microsoft.Resources/deployments/whatIf/action and Microsoft.Resources/deployments/validate/action, and no write on any resource type.
  2. Open a pull request that adds a resource — in our case Microsoft.AlertsManagement/actionRules and microsoft.insights/actionGroups.
  3. Validate fails:
Get-AzResourceGroupDeploymentWhatIfResult: InvalidTemplateDeployment - Long running operation
failed with status 'Failed'. Additional Info:'The template deployment failed with error:
'Authorization failed for template resource '<name>' of type
'Microsoft.AlertsManagement/actionRules'. The client '***' with object id '<redacted>' does not
have permission to perform action 'Microsoft.AlertsManagement/actionRules/write' at scope
'/subscriptions/<redacted>/resourceGroups/<redacted>/providers/Microsoft.AlertsManagement/actionRules/<name>'.'.'

Granting Microsoft.Resources/deployments/whatIf/action alone is not enough — that clears the first error, and then preflight fails on the per-resource write check.

Why this matters

The usual CI pattern is a low-privilege identity for PR preview and a separate writer for deploy, so that a pull request from anyone cannot run under a principal able to change production. With AzOps, Validate has to hold deploy rights, because what-if demands them.

AzOps-Accelerator ships a single credentials variable group shared by pull.yml, validate.yml and push.yml, so this is consistent with the reference design today — but it means the split isn't available to anyone who wants it.

Proposal

Expose the ARM parameter as a setting, defaulting to Provider so existing behaviour is unchanged:

"Core.WhatIfValidationLevel": "Provider"

and add it to the splat in New-AzOpsDeployment when a what-if is being performed, e.g.

$validationLevel = Get-PSFConfigValue -FullName 'AzOps.Core.WhatIfValidationLevel'
if ($validationLevel) {
    $parameters.ValidationLevel = $validationLevel
}

Operators who want a read-only preview identity could then set ProviderNoRbac and pair it with a custom role of */read plus the two preview actions. AzOps-Accelerator could subsequently offer a separate validate identity, which is not possible while the module cannot pass the parameter.

Workaround considered and rejected

Injecting the parameter from the pipeline:

$global:PSDefaultParameterValues['Get-AzResourceGroupDeploymentWhatIfResult:ValidationLevel'] = 'ProviderNoRbac'

This is unsupported, relies on the global scope reaching into module scope, does not reach the ForEach-Object -Parallel runspaces used when AllowMultipleTemplateParameterFiles and ParallelDeployMultipleTemplateParameterFiles are enabled, and fails silently by reverting to Provider rather than reporting that the setting was ignored.

Versions
  • AzOps 2.8.5, and confirmed unchanged on main at time of writing
  • Azure DevOps pipelines from AzOps-Accelerator
  • ValidationLevel requires Az PowerShell 13.4.0+ / Azure CLI 2.76.0+
References
主要言語
PowerShell
スター
420
フォーク
174
平均マージ
16日 18時間
マージ済み PR(30日)
1

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Azure/AzOps のほかの issue

Azure/AzOps の issue をすべて見る

似ている issue

Cloud の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。