Contributor is the role people reach for when something needs to work now. It usually works, but it gives the identity far more power than an application normally needs. Most workloads do not need to manage Azure resources. They need to read a secret, write a blob, send a message, or query data.

The useful split is control plane vs. data plane. Control-plane permissions manage resources: create, update, delete, configure, list keys, or change infrastructure. Data-plane permissions use the data inside those resources. For application identities, this distinction keeps the runtime from becoming a resource admin.

Give the identity the role for the operation. A managed identity that reads secrets from Key Vault usually needs Key Vault Secrets User. A worker that writes blobs usually needs Storage Blob Data Contributor on the storage account or container it uses. The running app and the deployment pipeline should not share the same permission shape.

This matters when something goes wrong. A bug, leaked token, compromised workload, or bad configuration can only do what the identity is allowed to do. If every identity is Contributor, a small application failure can become an Azure failure.

Scope the assignment tightly. Prefer a specific resource or resource group when subscription scope is not needed. Keep production identities separate from local development and test identities, even if the same application code uses all of them.

In .NET, this can still keep the application code simple. Use DefaultAzureCredential or a managed identity credential in Azure SDK clients, then let Azure RBAC decide what that identity can actually do.

Least privilege is not ceremony. It keeps access reviews readable and makes mistakes smaller.