IAM Across Clouds
Comprehensive comparison of IAM across AWS, Azure, GCP, and OCI covering policy models, roles, identity federation, MFA, service identities, and multi-cloud IAM best practices.
Prerequisites
- Understanding of IAM concepts (users, roles, policies)
- Experience with at least one cloud provider's IAM system
IAM Across Clouds: A Comprehensive Comparison
Identity and Access Management (IAM) is the security foundation of every cloud platform. While AWS, Azure, GCP, and OCI all solve the same fundamental problem (who can do what on which resources), they each take significantly different approaches to policy models, role definitions, identity federation, and privilege escalation prevention. Understanding these differences is critical for organizations operating in multi-cloud environments or migrating between providers.
This guide provides a deep comparison of IAM implementations across all four major cloud providers. We cover the core policy model of each provider, how roles and permissions work, identity federation and single sign-on, multi-factor authentication options, service identities for workloads, privilege escalation boundaries, and practical recommendations for multi-cloud IAM architecture.
Each section includes real CLI commands and policy examples so you can see the concrete differences rather than just conceptual comparisons. By the end of this guide, you will understand the fundamental IAM philosophy of each cloud and how to design a coherent identity strategy that spans providers.
IAM Philosophy Comparison
| Aspect | AWS | Azure | GCP | OCI |
|---|---|---|---|---|
| Policy Model | Identity-based + Resource-based JSON policies | RBAC with built-in and custom roles at scopes | Allow-only policies bound to resource hierarchy | Policy language with verbs, resources, and conditions |
| Default Stance | Implicit deny (explicit deny overrides) | Implicit deny | Implicit deny (no deny policies until recently) | Implicit deny |
| Resource Hierarchy | Organizations → OUs → Accounts | Management Groups → Subscriptions → Resource Groups | Organization → Folders → Projects | Tenancy → Compartments (6 levels deep) |
| Service Identity | IAM Roles (assumed by services) | Managed Identities (system or user assigned) | Service Accounts (act as both identity and resource) | Instance Principals / Resource Principals |
| Federation Standard | SAML 2.0, OIDC | SAML 2.0, OIDC, WS-Federation | SAML 2.0, OIDC | SAML 2.0, OIDC |
Policy Models in Depth
AWS IAM Policies
AWS uses JSON-based policies that can be attached to users, groups, roles, or resources. Identity-based policies define what an identity can do. Resource-based policies define who can access a specific resource. When both exist, they are evaluated together. AWS also supports Service Control Policies (SCPs) at the organization level and permission boundaries for delegation.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "us-east-1"
},
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}# Create a custom IAM policy
aws iam create-policy \
--policy-name S3ReadOnlyMFA \
--policy-document file://policy.json
# Attach policy to a role
aws iam attach-role-policy \
--role-name MyAppRole \
--policy-arn arn:aws:iam::123456789012:policy/S3ReadOnlyMFA
# Create an SCP (Organization-level guardrail)
aws organizations create-policy \
--name DenyRegionsOutsideUS \
--type SERVICE_CONTROL_POLICY \
--content '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Action":"*","Resource":"*","Condition":{"StringNotEquals":{"aws:RequestedRegion":["us-east-1","us-west-2"]}}}]}'Azure RBAC
Azure uses Role-Based Access Control (RBAC) where you assign built-in or custom roles to security principals (users, groups, service principals, managed identities) at a specific scope (management group, subscription, resource group, or individual resource). Azure has over 300 built-in roles and supports custom roles with fine-grained action definitions.
# List built-in roles
az role definition list --output table --query "[?roleType=='BuiltInRole'].{Name:roleName, Description:description}" | head -20
# Assign a role at subscription scope
az role assignment create \
--assignee "user@example.com" \
--role "Reader" \
--scope "/subscriptions/SUBSCRIPTION_ID"
# Assign a role at resource group scope
az role assignment create \
--assignee "user@example.com" \
--role "Contributor" \
--scope "/subscriptions/SUBSCRIPTION_ID/resourceGroups/my-rg"
# Create a custom role
az role definition create --role-definition '{
"Name": "Storage Blob Data Reader Custom",
"Description": "Read blob data with IP restriction",
"Actions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/read",
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
],
"NotActions": [],
"DataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
],
"AssignableScopes": ["/subscriptions/SUBSCRIPTION_ID"]
}'GCP IAM
GCP IAM uses a resource hierarchy model where policies are bound at the organization, folder, project, or individual resource level. Policies are inherited downward: a role granted at the organization level applies to all folders, projects, and resources. GCP recently introduced IAM deny policies for explicit deny rules, but the primary model remains allow-based with inheritance.
# Grant a role at project level
gcloud projects add-iam-policy-binding MY_PROJECT \
--member="user:developer@example.com" \
--role="roles/storage.objectViewer"
# Grant a role at folder level (inherited by all projects in folder)
gcloud resource-manager folders add-iam-policy-binding FOLDER_ID \
--member="group:developers@example.com" \
--role="roles/viewer"
# Create a custom role
gcloud iam roles create storageReaderCustom \
--project=MY_PROJECT \
--title="Storage Reader Custom" \
--description="Read objects from Cloud Storage" \
--permissions="storage.objects.get,storage.objects.list,storage.buckets.get" \
--stage=GA
# Add an IAM condition (restrict access by resource attribute)
gcloud projects add-iam-policy-binding MY_PROJECT \
--member="user:developer@example.com" \
--role="roles/storage.objectViewer" \
--condition='expression=resource.name.startsWith("projects/_/buckets/staging-"),title=staging-only,description=Only access staging buckets'
# Create an IAM deny policy (prevents even if allowed elsewhere)
gcloud iam policies create deny-external-sharing \
--attachment-point="cloudresourcemanager.googleapis.com/projects/MY_PROJECT" \
--kind=denypolicies \
--policy-id=deny-external-sharingOCI IAM Policies
# OCI policy syntax: Allow <subject> to <verb> <resource-type> in <location> where <conditions>
# Create a policy allowing a group to manage instances in a compartment
oci iam policy create \
--compartment-id TENANCY_OCID \
--name "compute-admins-policy" \
--description "Allow compute admins to manage instances" \
--statements '[
"Allow group ComputeAdmins to manage instance-family in compartment Production",
"Allow group ComputeAdmins to use virtual-network-family in compartment Production",
"Allow group ComputeAdmins to read app-catalog-listing in tenancy"
]'
# OCI uses four permission verbs: inspect, read, use, manage
# manage > use > read > inspect (each includes the lesser verbs)Identity Federation Comparison
Identity federation lets you use your existing identity provider (Okta, Azure AD, Google Workspace, Ping Identity) to authenticate users to cloud platforms without creating cloud-native user accounts. All four providers support SAML 2.0 and OIDC, but the implementation details differ significantly.
| Feature | AWS | Azure | GCP | OCI |
|---|---|---|---|---|
| SSO Service | IAM Identity Center | Entra ID (native) | Cloud Identity / Workspace | Identity Domains |
| Workload Identity | IAM Roles Anywhere + OIDC | Workload Identity Federation | Workload Identity Federation | Instance/Resource Principals |
| Temporary Credentials | STS AssumeRole (max 12 hrs) | Token lifetime (configurable) | Access tokens (1 hr default) | Security tokens (session-based) |
| Cross-Account/Project | Cross-account role assumption | Lighthouse / B2B collaboration | Cross-project IAM bindings | Cross-tenancy policies |
| MFA Options | TOTP, FIDO2, SMS (deprecated for root) | Authenticator, FIDO2, SMS, phone call | TOTP, FIDO2, phone prompt | TOTP, FIDO2, SMS, email |
Workload Identity Federation
For multi-cloud environments, workload identity federation is critical. It allows services running on one cloud to authenticate to another cloud without managing long-lived credentials. For example, a GitHub Actions workflow can assume an AWS role using OIDC, or a GKE pod can access Azure resources using workload identity federation. All four providers now support this pattern, making credential-free cross-cloud authentication possible.
Service Identities for Workloads
# AWS: Create an IAM role for an EC2 instance
aws iam create-role \
--role-name MyAppRole \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
aws iam create-instance-profile --instance-profile-name MyAppProfile
aws iam add-role-to-instance-profile \
--instance-profile-name MyAppProfile --role-name MyAppRole
# Azure: Create a user-assigned managed identity
az identity create \
--name my-app-identity \
--resource-group my-rg
az vm identity assign \
--name my-vm \
--resource-group my-rg \
--identities my-app-identity
# GCP: Create a service account and assign to VM
gcloud iam service-accounts create my-app-sa \
--display-name="My Application Service Account"
gcloud projects add-iam-policy-binding MY_PROJECT \
--member="serviceAccount:my-app-sa@MY_PROJECT.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
gcloud compute instances set-service-account my-vm \
--service-account=my-app-sa@MY_PROJECT.iam.gserviceaccount.com \
--scopes=cloud-platform
# OCI: Use instance principal (no key management needed)
# Instance principals are configured via dynamic groups
oci iam dynamic-group create \
--compartment-id TENANCY_OCID \
--name "app-instances" \
--description "Application compute instances" \
--matching-rule "Any {instance.compartment.id = 'COMPARTMENT_OCID'}"MFA Comparison
| Feature | AWS | Azure | GCP | OCI |
|---|---|---|---|---|
| TOTP App | Yes | Yes (Authenticator) | Yes | Yes |
| FIDO2 / Passkeys | Yes (root + IAM) | Yes (passwordless) | Yes (Titan keys) | Yes |
| Push Notification | No | Yes (Authenticator app) | Yes (Google prompt) | Yes (Oracle Mobile) |
| Conditional MFA | Yes (IAM conditions) | Yes (Conditional Access) | Yes (context-aware access) | Yes (sign-on policies) |
| Enforceability | SCP + IAM conditions | Security Defaults or CA policies | Org policy + Context-Aware Access | Identity domain policies |
MFA for Privileged Accounts
Every cloud provider recommends MFA for all human accounts and enforces it for root or super-admin accounts. In a multi-cloud environment, use your identity provider (Okta, Entra ID) as the single MFA enforcement point through federation. This ensures consistent MFA policies across all clouds without configuring MFA separately on each platform. Hardware security keys (FIDO2) provide the strongest protection against phishing attacks.
Multi-Cloud IAM Best Practices
Recommended Architecture
| Principle | Implementation |
|---|---|
| Centralized Identity | Use a single IdP (Okta, Entra ID) federated to all clouds |
| No Long-Lived Credentials | Use workload identity federation, managed identities, instance profiles |
| Least Privilege | Start with minimal permissions, expand based on actual need |
| Just-In-Time Access | Use PAM/PIM tools for privileged escalation with time limits |
| Audit Everything | CloudTrail (AWS), Activity Log (Azure), Audit Log (GCP), Audit (OCI) |
| Automate Policy Review | Use Access Analyzer (AWS), Recommender (GCP), Advisor (Azure) |
# AWS: Check for overly permissive policies
aws accessanalyzer create-analyzer \
--analyzer-name my-analyzer \
--type ACCOUNT
aws accessanalyzer list-findings \
--analyzer-arn ARN \
--filter '{"status": {"eq": ["ACTIVE"]}}'
# GCP: Use IAM Recommender to find excess permissions
gcloud recommender recommendations list \
--project=MY_PROJECT \
--location=global \
--recommender=google.iam.policy.Recommender \
--format="table(name,description,primaryImpact)"
# Azure: Review access with Privileged Identity Management
az ad pim role assignment list \
--resource-type subscription \
--resource-id SUBSCRIPTION_IDCross-Cloud Credential-Free Authentication
Modern multi-cloud architectures should never pass credentials between clouds. Instead, use workload identity federation: a GCP service account can assume an AWS IAM role via OIDC federation, an Azure managed identity can access GCP resources via workload identity pools, and GitHub Actions can authenticate to all three clouds using its OIDC provider. This eliminates the risk of credential leaks in cross-cloud integrations.
Key Takeaways
- 1AWS uses JSON policies (identity-based + resource-based), Azure uses RBAC with scoped role assignments, GCP uses allow-based policies on resource hierarchy, and OCI uses policy language with verbs.
- 2Workload identity federation enables credential-free cross-cloud authentication on all four providers.
- 3Use a single identity provider (Okta, Entra ID) federated to all clouds for consistent MFA and SSO.
- 4Service identities (IAM Roles, Managed Identities, Service Accounts, Instance Principals) eliminate long-lived credentials.
- 5GCP IAM Recommender and AWS Access Analyzer automatically identify overly permissive policies.
- 6Hardware security keys (FIDO2) provide the strongest MFA protection against phishing across all providers.
Frequently Asked Questions
Which cloud has the best IAM model?
How do I manage IAM across multiple clouds?
Can I use the same roles across clouds?
Written by CloudToolStack Team
Cloud engineers and architects with hands-on experience across AWS, Azure, and GCP. We write guides based on real-world production patterns, not just documentation rewrites.
Disclaimer: This guide is for educational purposes. Cloud services change frequently; always refer to official documentation for the latest information. AWS, Azure, and GCP are trademarks of their respective owners.