Identity parity — Google Cloud IAM against AWS IAM and Microsoft Entra / Azure RBAC, and the five differences that change an estimate
Counterpart names for IAM, Workload Identity Federation, Secret Manager and Cloud KMS, then the five differences that cost or save migration work: the grant model, the fixed ceilings and which cloud raises them, where a workload identity lives, keyless federation object counts, and the pricing dimension.
markdownguidev158DQ-2GBPstage: designtrust: officialfamily: identityservice: iaminterface: anyidentity parityiam migrationroles/AWS IAMAWS STSMicrosoft Entra IDAzure RBACworkload identity federationAssumeRoleWithWebIdentityfederated identity credentialRoleAssignmentLimitExceededsecret managerkey vaultcloud kmsaws kms
Identity parity
1. The names
| Google Cloud | AWS | Azure / Microsoft |
|---|---|---|
| IAM (role-based access control) | AWS IAM | Azure RBAC |
| Cloud Identity | IAM Identity Center | Microsoft Entra ID |
| service account | IAM role (workloads) / IAM user | managed identity, or app registration + service principal |
| Workload Identity Federation | OIDC federation + AssumeRoleWithWebIdentity | workload identity federation (a federated identity credential) |
| Secret Manager | Secrets Manager | Azure Key Vault (secrets) |
| Cloud KMS | AWS KMS | Azure Key Vault (keys) |
Both tables agree on these rows. The one-to-two row matters: Microsoft maps both Cloud KMS and Secret Manager to Azure Key Vault. Google Cloud splits the two jobs into two services with separate IAM surfaces and separate quota models. Either way, that is a service boundary appearing or disappearing, not a rename.
2. The grant model — the difference that rewrites the policy code, not just the names
| Google Cloud | AWS | Azure | |
|---|---|---|---|
| what you write | a role binding in a resource's allow policy: principal + role + optional condition | a JSON policy document, attached to an identity or to a resource | a role assignment: principal + role definition + scope |
| who holds it | the resource (and anything above it in the hierarchy) | identity-attached, resource-attached, or both | the scope |
| how a grant is narrowed | a deny policy or a Principal Access Boundary, both separate objects | an explicit Deny statement inside the same policy language | a deny assignment (created by Azure, not generally by you) |
| what inherits | policy inherits down org → folder → project → resource | an SCP constrains down an OU tree; identity policies do not inherit | an assignment applies down management group → subscription → resource group |
Estimate consequence. Google Cloud and Azure are both "bind a named role at a scope", so role mapping between them is mechanical — the work is in the role catalogue, not the model. AWS is a different language: one policy document expresses conditions, wildcards and explicit denials that Google Cloud needs three object types for (a condition on a binding, a deny policy, a PAB policy). Translating AWS policy JSON into bindings is a decomposition: budget it per policy document, not per role. It is the most under-estimated task in an AWS-to-Google-Cloud move.
3. The ceilings, and which cloud lets you raise them
| Thing | Google Cloud | AWS | Azure |
|---|---|---|---|
| grants at one scope | 1,500 principals per allow policy, "Limits cannot be changed" | managed policies per role 20, raisable to 25 | 5,000 role assignments per subscription, "fixed and cannot be increased"; 500 per management group, also fixed |
| custom roles | 300 per project and 300 per organization, not changeable | customer managed policies 1,500 per account, raisable to 10,000 | 5,000 custom roles per directory (2,000 for Azure operated by 21Vianet) |
| workload identity objects | no quota on pools stated on the IAM quotas page | OIDC providers 100 per account, raisable to 700 | federated identity credentials per object (see Microsoft's limits page) |
| credential lifetime | access token 3,600 s, extendable to 12 h by organization policy | role session 1 h default, up to 12 h, not raisable past 12 | access token lifetime governed by Entra policy |
| long-lived keys | 10 service account keys per account | access keys per user (2) | app registration secrets/certificates |
Three readings an estimate depends on:
- AWS publishes an "automatically approved" increase table; the other two publish fixed limits. A design
that leans on raising an identity ceiling works on AWS and must be redesigned on Google Cloud and Azure.
- The ceilings are not comparable units. 1,500 principals in one policy, 5,000 *role assignments in a
subscription and 20 managed policies on one role* count three different things. Express the estimate as
principals × scopes to convert; the arithmetic is in guides/parity-and-migration-method.md.
- All three answer the same way: group-based grants. Azure's own first remedy is "Replace principal-based
role assignments with group-based role assignments", and Google Cloud's 1,500-principal ceiling forces the same conclusion. A migration that lands principal-by-principal lands at the ceiling.
The two Azure strings a lift-and-shift actually hits:
No more role assignments can be created (code: RoleAssignmentLimitExceeded)
Role definition limit exceeded. No more role definitions can be created (code: RoleDefinitionLimitExceeded)
4. Where a workload's identity lives — the regional and attachment model
| Google Cloud | AWS | Azure | |
|---|---|---|---|
| identity object scope | a service account is a project-level, global object | an IAM role is account-level and global | a managed identity is a regional resource in a resource group; an app registration is tenant-level |
| how a workload gets it | attach the service account to the VM / Cloud Run service / job | attach an instance profile or execution role | assign a system- or user-assigned managed identity |
Estimate consequence. A user-assigned managed identity is regional, so it is part of a region's blast radius and of its resource count; Google Cloud and AWS identities are not. A Google-Cloud-to-Azure move therefore multiplies identity objects by the number of regions — the kind of row that silently triples a "like-for-like" count.
5. Keyless federation — same idea, three different things validated
| Google Cloud | AWS | Azure | |
|---|---|---|---|
| objects to create | 2: a workload identity pool and a pool provider | 1: an IAM OIDC identity provider (plus a trust policy on each role) | 1 per trust: a federated identity credential on a managed identity or app registration |
| where the trust condition lives | --attribute-condition on the provider | the role's trust policy (condition keys on sub, aud) | the credential's issuer / subject / audience fields |
| matching rule | attribute mapping expressions, then the condition | policy conditions | exact, case-sensitive on issuer, subject, audience |
| can the workload skip a service account? | yes — direct resource access is the recommended path | no: the token always maps to an IAM role | no: the token always maps to a managed identity or app |
| documented gotcha | "some APIs have limitations" with federation | a five-minute clock-skew window past the JWT exp claim | only the first 100 signing keys from the external IdP are stored; Entra-issued tokens may not be used in this flow |
Estimate consequence — the biggest saving in this guide. Google Cloud is the only one of the three where a federated workload can be bound straight onto the resource; AWS and Azure always interpose an identity object. So moving to Google Cloud can delete one object per workload, if every API that workload calls supports federation (check first — the vendor says some do not); moving from Google Cloud where direct resource access was used, you must create one identity object per workload on the far side.
Azure's exact, case-sensitive matching on three fields is the usual first-attempt failure when a workflow that worked against Google Cloud's expression-based mapping is pointed at Azure.
6. Pricing dimension (never a price)
The control plane is free on all three. What is metered differs, and the dimension is what an estimate needs:
| Google Cloud | AWS | Azure | |
|---|---|---|---|
| secrets | per secret version per location, plus access operations | per secret per month, plus API calls | per secret operation |
| keys | per key version per month, plus cryptographic operations, priced by protection level | per key per month plus requests | per key plus operations, priced by tier |
Read every figure live. Google Cloud's per version per location metering is the row that matters: the
replication policy chosen in reference/identity/secret-manager-and-kms.md is a cost decision as well as a
residency one.
7. What this guide cannot tell you
Whether a predefined role on one cloud grants the same set of operations as its counterpart. It does not,
and no published table claims it does. Closing that gap means enumerating the permissions the workload
actually used, then mapping permission-to-role on the target: guides/parity-and-migration-method.md.