# Microsoft Azure IAM permissions

> ZopNight reads an Azure subscription through 3 built-in roles: Reader for inventory, Monitoring Reader for the utilisation metrics that idle findings need, and Cost Management Reader for spend. That is 120 read permissions. Acting on findings adds the custom Zopnight Write Access role, granted separately.

Source: https://zop.dev/integrations/azure/permissions
Updated: 2026-08-20

---

## Common questions

### Which Azure roles does ZopNight need?

Three built-in ones for reading: Reader at subscription scope for inventory, Monitoring Reader for the utilisation metrics that idle and rightsizing findings depend on, and Cost Management Reader for spend. That is 120 read permissions, none of which can change anything.

### Is Contributor or Owner ever required?

No. Writes come from the custom Zopnight Write Access role, plus Zopnight AKS Access for cluster and node-pool operations and Zopnight Databricks Access if you run Databricks on Azure. That is 125 write permissions across the three.

### Why does the write role need deallocate rather than powerOff?

Because a VM that is stopped but still allocated keeps billing for compute. ZopNight issues Microsoft.Compute/virtualMachines/deallocate/action, which releases the capacity. Granting powerOff/action instead produces schedules that appear to work and save nothing.

## Reader roles now, Zopnight Write Access later

Azure is role-based rather than action-based, so the honest answer is a list of roles, not a
list of strings. Read-only discovery needs **Reader** at subscription scope, **Monitoring
Reader** for the utilisation metrics that idle and rightsizing findings depend on, and **Cost
Management Reader** for spend.

That is the whole read grant: 120 permissions, none of which can change anything.

Acting on findings needs the custom **Zopnight Write Access** role, plus **Zopnight AKS
Access** for cluster and node-pool operations and **Zopnight Databricks Access** if you run
Databricks on Azure. 125 write permissions across those three.

## Service principal or workload identity federation?

Both are supported and the choice is a real one.

- **Workload identity federation** stores **no secret**. Azure trusts a ZopNight OIDC token
  directly, so there is nothing to rotate and nothing to leak. Prefer it.
- **Service principal** uses a client ID, secret and tenant ID. Universally supported, but the
  secret is stored and you own its rotation.

## Why deallocate, not power off

Stopping an Azure VM through the guest OS leaves it **allocated**, and an allocated VM keeps
billing for compute. ZopNight always issues `deallocate`, which releases the capacity and stops
the compute charge. The disks keep billing either way, which is a separate finding.

This is why the write role needs `virtualMachines/deallocate/action` specifically, and why
granting only `powerOff/action` produces schedules that appear to work and save nothing.

## Namespace scheduling

AKS carries an extra purpose, `namespace_scheduling`: scaling every Deployment and StatefulSet
in a namespace to zero and suspending its CronJobs, then restoring the prior replica counts.
It needs cluster access rather than subscription-level rights, which is why it sits in its own
role instead of the general write grant.
