Skip to main content
Multi-CloudSecurityintermediate

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.

CloudToolStack Team24 min readPublished Mar 14, 2026

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

AspectAWSAzureGCPOCI
Policy ModelIdentity-based + Resource-based JSON policiesRBAC with built-in and custom roles at scopesAllow-only policies bound to resource hierarchyPolicy language with verbs, resources, and conditions
Default StanceImplicit deny (explicit deny overrides)Implicit denyImplicit deny (no deny policies until recently)Implicit deny
Resource HierarchyOrganizations → OUs → AccountsManagement Groups → Subscriptions → Resource GroupsOrganization → Folders → ProjectsTenancy → Compartments (6 levels deep)
Service IdentityIAM Roles (assumed by services)Managed Identities (system or user assigned)Service Accounts (act as both identity and resource)Instance Principals / Resource Principals
Federation StandardSAML 2.0, OIDCSAML 2.0, OIDC, WS-FederationSAML 2.0, OIDCSAML 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.

AWS IAM policy example
{
  "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"
        }
      }
    }
  ]
}
bash
# 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.

bash
# 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.

bash
# 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-sharing

OCI IAM Policies

bash
# 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.

FeatureAWSAzureGCPOCI
SSO ServiceIAM Identity CenterEntra ID (native)Cloud Identity / WorkspaceIdentity Domains
Workload IdentityIAM Roles Anywhere + OIDCWorkload Identity FederationWorkload Identity FederationInstance/Resource Principals
Temporary CredentialsSTS AssumeRole (max 12 hrs)Token lifetime (configurable)Access tokens (1 hr default)Security tokens (session-based)
Cross-Account/ProjectCross-account role assumptionLighthouse / B2B collaborationCross-project IAM bindingsCross-tenancy policies
MFA OptionsTOTP, FIDO2, SMS (deprecated for root)Authenticator, FIDO2, SMS, phone callTOTP, FIDO2, phone promptTOTP, 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

bash
# 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

FeatureAWSAzureGCPOCI
TOTP AppYesYes (Authenticator)YesYes
FIDO2 / PasskeysYes (root + IAM)Yes (passwordless)Yes (Titan keys)Yes
Push NotificationNoYes (Authenticator app)Yes (Google prompt)Yes (Oracle Mobile)
Conditional MFAYes (IAM conditions)Yes (Conditional Access)Yes (context-aware access)Yes (sign-on policies)
EnforceabilitySCP + IAM conditionsSecurity Defaults or CA policiesOrg policy + Context-Aware AccessIdentity 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

PrincipleImplementation
Centralized IdentityUse a single IdP (Okta, Entra ID) federated to all clouds
No Long-Lived CredentialsUse workload identity federation, managed identities, instance profiles
Least PrivilegeStart with minimal permissions, expand based on actual need
Just-In-Time AccessUse PAM/PIM tools for privileged escalation with time limits
Audit EverythingCloudTrail (AWS), Activity Log (Azure), Audit Log (GCP), Audit (OCI)
Automate Policy ReviewUse Access Analyzer (AWS), Recommender (GCP), Advisor (Azure)
bash
# 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_ID

Cross-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.

Multi-Cloud IAM Rosetta StoneAWS IAM Best PracticesGCP IAM & Organization Policies

Key Takeaways

  1. 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.
  2. 2Workload identity federation enables credential-free cross-cloud authentication on all four providers.
  3. 3Use a single identity provider (Okta, Entra ID) federated to all clouds for consistent MFA and SSO.
  4. 4Service identities (IAM Roles, Managed Identities, Service Accounts, Instance Principals) eliminate long-lived credentials.
  5. 5GCP IAM Recommender and AWS Access Analyzer automatically identify overly permissive policies.
  6. 6Hardware security keys (FIDO2) provide the strongest MFA protection against phishing across all providers.

Frequently Asked Questions

Which cloud has the best IAM model?
Each has strengths: AWS IAM is the most flexible with identity-based and resource-based policies. Azure RBAC is the most intuitive with built-in roles at scoped levels. GCP IAM is the simplest with allow-only policies inherited through the resource hierarchy. OCI policies are the most readable with English-like syntax. The 'best' depends on your team's experience and requirements.
How do I manage IAM across multiple clouds?
Use a centralized identity provider (Okta, Entra ID, Google Workspace) federated to all clouds via SAML/OIDC. This gives you single sign-on, centralized MFA enforcement, and unified user lifecycle management. For service-to-service authentication, use workload identity federation instead of managing credentials.
Can I use the same roles across clouds?
No. Each provider defines roles differently. AWS has managed and custom policies, Azure has built-in and custom roles, GCP has predefined and custom roles, and OCI uses policy statements. You need to map equivalent permissions across providers. The Multi-Cloud IAM Rosetta Stone guide provides these mappings.

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.