AWS vs GCP vs Azure: org hierarchy, IAM, and key management, side by side
The same three problems β organize accounts, control identity, manage keys β solved three ways. A practical mapping of AWS, Google Cloud, and Azure governance, plus the certs that drill each one.
If you already know one cloud's governance model, you know 80% of the other two β the concepts are identical and only the vocabulary changes. Every cloud makes you answer the same three questions before you ship anything real: how do I organize my accounts, who is allowed to do what, and how are my encryption keys created and controlled? This post maps AWS, Google Cloud, and Azure onto each other, one layer at a time, and calls out the four places the analogy quietly breaks.
Those four layers β hierarchy, guardrails, identity, and key management β are also the backbone of every cloud architecture and security exam. So the same reading that saves you a week of cross-cloud confusion is most of the syllabus for a certification. Certs to drill each layer are linked at the end.
The three problems every cloud solves
Take away the marketing and every governance discussion is three layers stacked on top of each other:
- Structure β a nested set of containers (organization β grouping β workload boundary) so you can isolate environments, apply guardrails, and split the bill.
- Identity and permissions β which principals can perform which actions on which resources, plus the ceiling that caps what any grant can ever hand out.
- Key management β where cryptographic keys live, who may use them, and who may administer them β two different questions that people constantly conflate.
Most engineers can list the pieces in the cloud they know best. The hard part is the full picture: the layers that are easy to forget, and how each piece translates to the other two clouds.
Layer 1 β the resource hierarchy
Each cloud has a top-level organization node, an optional middle grouping layer you nest for departments or environments, and a workload boundary that also serves as the unit of billing and blast radius. Policies set high up flow downward in all three.
- Org root β AWS: an Organization with a management account. GCP: the organization node. Azure: the tenant root management group, backed by a Microsoft Entra tenant.
- Grouping container (nestable) β AWS: Organizational Unit (OU). GCP: folder. Azure: management group.
- Workload and billing boundary β AWS: account. GCP: project. Azure: subscription.
- Resource grouping inside the boundary β AWS: none (tags, or per-account). GCP: none β the project is the container. Azure: the resource group, which is mandatory; every resource lives in exactly one.
The first real divergence hides here. In AWS the account is a hard wall β the default unit of blast radius β which is why grown-up AWS estates run dozens or hundreds of accounts. In GCP the project does two jobs at once: it's both the grouping unit and the billing/isolation unit, so there's no separate "resource group" concept. Azure adds a fourth level the others lack β the resource group β sitting under the subscription as a lifecycle container you deploy and tear down as a unit.
Layer 2 β preventive guardrails (the permission ceiling)
Before you grant anyone anything, each cloud lets you set an upper bound on what permissions can ever exist below a node β a ceiling no individual grant can punch through. This is not the same as handing out access; it's the "you may never, org-wide" layer.
- Cap on what principals can do β AWS: Service Control Policy (SCP). GCP: Organization Policy constraints plus IAM deny policies. Azure: Azure Policy.
- Cap on who can touch a resource β AWS: Resource Control Policy (RCP). GCP: IAM allow/deny policies on the resource. Azure: Azure Policy plus deny assignments.
- Enforce service configuration β AWS: declarative policies. GCP: Organization Policy constraints. Azure: Azure Policy (deny / audit / deployIfNotExists).
AWS split this job in two. SCPs are principal-centric ("our people can't do X") and the newer RCPs are resource-centric ("nobody β not even an outside account β can touch this S3 bucket, KMS key, or role unless they're in our org"). Used together they close gaps neither covers alone. The trap: in AWS and GCP an SCP or Org Policy never grants anything β it only subtracts. Azure is wired differently, cleanly separating RBAC (permissions) from Azure Policy (compliance and configuration), so the guardrail job belongs mostly to Azure Policy while "who can do what" belongs entirely to RBAC.
Layer 3 β identity and permissions
Every cloud expresses a grant as the same triple β a principal, a role (a bundle of permissions), and a scope β but assembles the pieces differently.
- Identity directory β AWS: IAM plus IAM Identity Center (SSO). GCP: Cloud Identity / Google Workspace plus IAM. Azure: Microsoft Entra ID.
- Permission bundle (the "role") β AWS: an IAM policy, managed or inline. GCP: an IAM role β basic, predefined, or custom. Azure: an RBAC role definition, built-in or custom.
- The grant itself β AWS: a policy attached to a user, group, or role. GCP: an IAM binding (member + role, optionally a condition) on a resource. Azure: a role assignment (principal + role + scope).
- Conditions and explicit deny β AWS: IAM condition keys and explicit
Deny. GCP: IAM Conditions and deny policies. Azure: RBAC conditions and deny assignments.
The deepest difference is where the grant lives. In AWS you mostly attach the policy to the identity β a role or user β and the permission travels with them. In GCP the allow policy attaches to the resource: you grant principal P the role R on resource X, and it inherits down the hierarchy. Azure's role assignment resembles GCP's binding but anchors to a scope in the management-group β subscription β resource-group β resource chain. Internalize "AWS = identity-attached, GCP and Azure = resource/scope-attached" and a lot of cross-cloud confusion disappears.
Layer 3b β workload identity (the part people forget)
Humans aren't the only principals. Your code needs an identity too, and getting it right is the single biggest lever on least privilege. The golden rule everywhere: never ship long-lived static keys β attach a managed identity to the workload instead.
- Identity for a running workload β AWS: an IAM role, assumed via instance profile, task role, or OIDC. GCP: a service account attached to the resource. Azure: a managed identity, system- or user-assigned.
- App / non-human principal β AWS: IAM role. GCP: service account. Azure: service principal.
- Keyless trust from outside the cloud β AWS: IAM roles with OIDC/SAML federation. GCP: Workload Identity Federation. Azure: workload identity federation.
Watch the naming overlap that trips everyone up: an "IAM role" in AWS is a workload identity you assume, whereas a "role" in GCP and Azure is only a permission bundle β the identity is a service account or managed identity. Same word, two different jobs. GCP service-account keys and Azure service-principal secrets still exist, but both clouds now push hard toward keyless federation for anything running outside their perimeter.
Layer 4 β key management
Finally, encryption. Each cloud has a managed key service, organizes keys in a small hierarchy, and β crucially β separates using a key (encrypt/decrypt) from administering a key (rotate, disable, set policy).
- Service β AWS: KMS, plus CloudHSM for dedicated hardware. GCP: Cloud KMS, plus Cloud HSM / external. Azure: Key Vault, plus Managed HSM for dedicated hardware.
- Key organization β AWS: KMS keys (CMKs), aliases, multi-Region keys. GCP: key ring β key β key version. Azure: vault β key / secret / certificate.
- Access control β AWS: key policy + grants + IAM (all three combine). GCP: Cloud KMS IAM bindings at project, key-ring, or key level. Azure: RBAC by default, or legacy per-vault access policies; Managed HSM uses its own local RBAC.
- Use vs. administer split β AWS: encrypt/decrypt actions vs. key-admin actions. GCP:
cryptoKeyEncrypterDecryptervs.adminroles. Azure: "Crypto User" vs. "Crypto Officer"-style roles.
A current wrinkle worth knowing: for new Key Vaults on recent API versions, Azure RBAC is now the default access model, and the older per-vault access policies are the legacy path β which finally aligns Key Vault with how the rest of Azure does permissions. AWS stays the odd one out: a KMS key's key policy is authoritative and can grant access independently of IAM, so a classic AWS foot-gun is locking yourself out of a key by editing IAM while forgetting the key policy. In GCP, KMS access is plain IAM like everything else.
Where the mental model breaks
A clean mapping is dangerous if you trust it too literally. The four places the analogy leaks:
- "IAM role" means two different things. In AWS it's an assumable identity; in GCP and Azure a "role" is only a permission set, with the identity kept separate. Never translate it word for word.
- AWS attaches permissions to identities; GCP and Azure attach them to resources and scopes. Your "where do I look to audit access?" instinct has to flip when you switch clouds.
- Account, project, and subscription are not the same blast radius. An AWS account is a strong wall; a GCP project is wall, bill, and grouping in one; an Azure subscription is mostly a billing and scale boundary, with the resource group handling day-to-day lifecycle.
- Guardrails subtract, grants add β except Azure splits the jobs. SCPs and Org Policies only ever cap permissions; Azure caps via Policy and grants via RBAC as two separate systems.
The principle underneath all three is the same: least privilege, enforced by structure. Put guardrails high (org, OU, folder, management group), grant narrowly and prefer roles over static keys, and keep "can use a key" separate from "can administer a key." The names change across clouds; the discipline doesn't.
Practical takeaways
- Design the hierarchy before the first workload. Retrofitting accounts, projects, or subscriptions later hurts in every cloud.
- Set ceilings high, grant low. SCP/RCP, Org Policy, or Azure Policy at the top; specific roles at the narrowest scope that works.
- Default to managed identities. IAM roles on AWS, service accounts on GCP, managed identities on Azure β and keyless federation for anything crossing a cloud boundary.
- Treat key admin as privileged. Separate encrypt/decrypt from rotate/disable/set-policy, and on AWS always check the key policy, not just IAM.
- If you use Terraform or OpenTofu, these primitives are exactly what you'll codify β
aws_organizations_*,google_folder,azurerm_management_group, and the IAM/RBAC and KMS resources beneath them.
Drill each layer, per cloud
Every cloud's architecture and security certifications are built squarely on the resource hierarchy, IAM/RBAC, and key management. If you want to practice them with real exam questions, CertLabPro has a track for each:
- AWS β Solutions Architect Associate (SAA-C03) for the hierarchy and IAM, and Security Specialty (SCS-C03) for SCPs, RCPs, and KMS. New to AWS? Start with Cloud Practitioner (CLF-C02).
- Google Cloud β Professional Cloud Architect for organization, folders, projects, and IAM, and Professional Cloud Security Engineer for IAM deny policies, Org Policy, and Cloud KMS.
- Azure β Solutions Architect Expert (AZ-305) for management groups and governance, and Security Engineer (AZ-500) for RBAC, Azure Policy, and Key Vault. New to Azure? Start with Azure Fundamentals (AZ-900).
The bottom line
AWS, Google Cloud, and Azure are not as different as their docs make them feel. Each gives you a hierarchy to organize accounts, an identity model built on principal-role-scope, a guardrail layer that caps what permissions can exist, and a key service that separates using keys from administering them. Learn the four layers once and the cross-cloud translation is mostly vocabulary β and learn the four places the analogy leaks, and you'll dodge the mistakes that vocabulary hides. Those fundamentals are exactly what CertLabPro's question banks are built to drill, across all three clouds.