Expose ValidationLevel so what-if can run under a least-privilege identity
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 78/100
Research direction
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.
Written by the indexing model from the issue text.
Description
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
- Give the Validate pipeline identity a role with
*/read,Microsoft.Resources/deployments/whatIf/actionandMicrosoft.Resources/deployments/validate/action, and no write on any resource type. - Open a pull request that adds a resource — in our case
Microsoft.AlertsManagement/actionRulesandmicrosoft.insights/actionGroups. - 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
mainat time of writing - Azure DevOps pipelines from
AzOps-Accelerator ValidationLevelrequires Az PowerShell 13.4.0+ / Azure CLI 2.76.0+
References
- Dominant language
- PowerShell
- Stars
- 420
- Forks
- 174
- Avg merge
- 16d 18h
- Merged PRs (30d)
- 1
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Azure/AzOps
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 4/5 3-5 days Newbie friendliness 42/100
-
Difficulty 4/5 3-5 days Newbie friendliness 28/100
-
triage
Difficulty 4/5 3-5 days Newbie friendliness 35/100
Similar issues
-
[BUG] ECR GetAuthorizationToken returns a proxyEndpoint for the default region, not the request's Openbug ecr
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
docs-from-code
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
microsoft/aspire.dev#1734 ·
-
[BUG] Openbug needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
openwallet-foundation/eudiplo#1067 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
hashicorp/go-azure-helpers#286 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
akash-network/community#1526 ·