Skip to content
Technology and engineering

Subscription owner, and no permission to read a secret

October 17, 2026

On Azure, owning the subscription gives you the control plane, not the data. The roles I declared for a secret, the Terraform state and the cluster, and why I switched off every back door.

A hand at an access reader on a wall
Photo by HUUM on Unsplash

I came from Google Cloud, where I was used to a project owner being able to do almost anything. On Azure I became Owner of the subscription and found it gave me access to no data at all: not a secret in the vault, not the Terraform state, not the cluster.

Two planes, two permissions

Azure separates the control plane, which creates, changes and deletes resources, from the data plane, which reads and writes what's inside them. Owner holds every control plane action and no data actions, so data needs roles of its own.

In the lab that turned into four concrete decisions:

  • The secret vault runs in RBAC mode, not access policies. Writing a secret takes Key Vault Secrets Officer, and the application's identity only has Key Vault Secrets User, which reads.
  • The Terraform state account has shared keys switched off. With no key, access goes through Entra ID, and reading or writing the state takes Storage Blob Data Contributor on that account.
  • The cluster has local Kubernetes accounts disabled and authorization goes through Azure RBAC. Using kubectl as an administrator takes Azure Kubernetes Service RBAC Cluster Admin on the cluster.
  • On the image registry, the cluster pulls with AcrPull and publishing takes AcrPush, which goes to whoever publishes, not to what runs.
The Owner role on the control plane on the left, with no data actions, and on the right the vault, the Terraform state, the cluster and the registry with the data role each one asks for.
Owner of the subscription is not owner of the data.

It's not a boundary against the owner

An Owner can grant themselves any of those roles, because Owner can write role assignments, so this doesn't protect data from the subscription owner. What it does is force you to declare who touches the data, with an exact scope, and leave it in the activity log. Without that declaration, data access doesn't happen by accident.

That's why every role sits in the code next to the resource it protects, scoped to that resource and not to its resource group: the vault's assignment points at the vault, the cluster's at the cluster.

Why I switched off every back door

None of this works if any of those doors has a spare key. A storage account with shared keys on lets anyone holding the key read everything, with no Entra ID and no role. A cluster with local accounts has an admin certificate that never goes through Azure RBAC. Switching those keys off is what makes the data roles the only way in.

One AKS detail worth knowing: since Kubernetes 1.25, Azure won't let you disable local accounts on a cluster that isn't integrated with Entra ID. The two settings go together.

And one declared exception: the account that receives the virtual network's flow logs keeps shared keys on, because Network Watcher writes with the account key and the Terraform resource offers no managed identity to do it with. Nothing in the repository reads or stores that key.

Give the operator Owner and stop thereCostNothingRiskOwner carries no data actions: the deployment hits an access deniedVerdictDoesn't work on Azure
Leave shared keys and local accounts onCostNothing, everything works on day oneRiskA static credential that bypasses every roleVerdictRejected
Data roles declared per resource, no back doorsCostA few more role assignments in the codeRiskForgetting one breaks a deployment in a clean environmentVerdictChosen

What changes coming from Google Cloud

Google Cloud has the same separation, but the basic owner and editor roles cover so much that habits form differently, and Google's own advice is not to use them. Azure makes the separation mandatory by design.

For a team migrating, that means the permission model doesn't translate one to one. The data plane gets designed separately, and who reads what gets decided before deploying, not when someone hits an access denied. The full decision is in the repository.

On your platform, who can read your secrets today, and how many of them can only because they hold a role nobody designed for that?

Sign in to say it was useful

Notices

I let you know when I publish.

Conversation