For my work I went from AWS to mostly Azure. Most concepts adapt easily. IAM did not. Not until I stopped fighting it and found the right mental model.

AWS IAM and Azure IAM are not the same thing even though the name is equal. They think in opposite directions, and I was running my AWS reflexes on a system built the other way around.

Lets call it a mirror

That one flip decides more than you would think. Mostly what you can automate, but also how the teams around each cloud end up working. My take: AWS lands on automation first, Azure on human oriented.

The inverted model

Same name, opposite direction. On AWS you reason from the identity out to the resources. On Azure you start at the resource and look back at the identities.

AWS puts one identity in the middle and fans its permissions out to many resources. Azure puts one resource in the middle and many identities point at it. The two are mirror images of each other.

Same result either way, access is controlled. But the reasoning runs backwards between them. Easiest way to feel it is to grant access on both and watch where the permission ends up.

The AWS side

You write a policy. A bit of JSON, the actions and the ARNs they hit, attached to an identity. The permission now lives on the identity and travels with it. You can make it as tight as you like, down to read on one single object. Some resources carry their own policy too, a bucket or a KMS key, but that is the exception.

Want to know what something can do? Open the role and read it. The question is always the same: what can this identity do.

The Azure side

Here you do not touch the identity. You go to the resource, add a role assignment, and bind three things: a principal, a role definition, a scope. The assignment sits on the resource, not on the principal. The principal stays empty.

And the scope only goes so fine. A container, not a single blob. You want one specific blob? Now you need an ABAC condition or a SAS token. The thing that was one line of policy on AWS.

To find out who can reach something, you open the thing itself and read the assignments. The question flips: who can do what on this resource.

An identity is not a grant

This is the one that got me. People kept comparing a managed identity to an IAM role and I never understood the comparison. They are not the same shape.

An IAM role is two things in one: an identity, and a grant stuck to it. A managed identity is only the first part. The credential side matches fine, your compute gets an identity, nothing to rotate, close to what a Lambda gets for free. But that is where it stops. A managed identity is not the role, it is the identity half of the role. The grant half did not disappear. It moved onto the resource.

An identity is not a grant. On AWS the grant sticks to the identity. On Azure the identity is empty and the grant sits on the target.

Granting is a privileged act

This is the part that made my daily work harder.

On AWS, giving something access is a local move. You edit an identity you already own, inside your own stack, and your pipeline does it. Nothing reaches outside. grantRead, done.

Not on Azure. Writing a role assignment is a privileged action on the target. It wants Owner or User Access Administrator on whatever holds that resource. So to glue together two things you built yourself, your pipeline suddenly needs rights over the target. And rights over the target are the one thing nobody hands to an automated identity.

to hand out small access you first need big access

This is not a thought experiment for me. I build a template gallery, and some templates need to hand a workload a role. Nothing wild, let a function read the blobs in its own container. But the deploy identity can’t write that assignment, so we asked for the rights. A minimal set, scoped to the resource, nothing at subscription level. That was nine months ago. Every few weeks we think the identity team finally gets it, and every time it blows up and nothing moves. Nine months, to let a function read its own container.

The same two-resource stack on both clouds, each inside its own IaC deployment boundary. On AWS the grant is an edit on the Lambda role and stays inside the boundary. On Azure the role assignment write needs Owner rights on the storage account, an arrow that reaches in from outside the stack.

Nobody sat down and designed it to be annoying. On AWS the grant stays inside your own stack, so a team can just do it. That is what I mean with automation first. On Azure the grant reaches out to something you might not own, so it lands with whoever governs that something, and that is almost never you. The platform never says who is allowed to grant. It just makes one road smooth and the other a fight, and people take the smooth road.

Why each cloud chose its side

So why are they opposite? Not by accident. Each cloud fit the people it was built for.

AWS was built for people building new things. The identity is first class there, it moves with your code, it should carry its own powers. Starting from the identity is that idea turned into a product. Automation comes almost for free. What you pay for it is auditing, expensive enough that AWS had to build Access Analyzer just to answer the question who can actually reach this bucket.

Azure came from somewhere else. It was built to carry the on-prem world into the cloud, and on-prem access control always sat on the resource. NTFS, Active Directory, SharePoint. An admin walks up to the thing and hands out rights, the thing keeps the list. Azure kept that shape. For the admin coming off on-prem it feels like home, and the auditor gets the easy question. Automation is the part you give up this time.

It is also why PIM feels so natural on Azure and AWS has nothing like it. Privileged Identity Management makes an assignment eligible instead of active. You request it, someone approves, it switches on for a couple of hours, then it expires by itself. It works because the assignment already lives on the resource, so putting a timer and an approval on it is the obvious next step. Same just-in-time admin access people ran on-prem, rebuilt in the cloud, for the same crowd Azure was after all along. Shame it sits behind the Entra ID P2 license.

Where this leaves me

The two models are not right and wrong. They are aimed. Azure at the organisation walking out of the datacenter, AWS at the team building something new.

I am automation-first, so the identity side fits my hand and I am happiest on AWS. On Azure the job is always the same, how do I automate this without losing the least-privilege grip AWS gives me for free. But I stopped being annoyed the day I saw it straight. Azure is not badly designed. It is designed for someone else.

Next in this world-vision series I follow the same split into deployment, where the two clouds part ways all over again.

~ Joost van der Waal

End note

Thanks for reading, I hope it was useful. Please drop me a note on linked in when you have additional questions or remarks.

Oh, and I'm putting all of this into practice. A fully serverless email server that deploys on your own AWS in minutes and runs for about a dollar a month. More on that soon.

~ Joost van der Waal (Cloud guru)