Skip to content
iD
InfoDive Labs
Back to blog
CloudIAMSecurity

Cloud IAM Best Practices Across AWS, Azure, and GCP

Master cloud IAM best practices for AWS, Azure, and GCP including least privilege, policy design, service accounts, and common misconfigurations to avoid.

May 15, 20257 min read

Cloud IAM Best Practices Across AWS, Azure, and GCP

Cloud identity and access management is where security either succeeds or fails. Misconfigured IAM policies are consistently the root cause of the largest cloud breaches - an overly permissive S3 bucket policy, a service account with owner privileges, or a forgotten access key in a public repository. The challenge is compounded by the fact that AWS, Azure, and GCP each implement IAM differently, with distinct concepts, terminology, and best practices.

This guide provides a unified framework for cloud IAM, covering the principles that apply universally and the platform-specific practices that matter most. Whether you operate in a single cloud or a multi-cloud environment, these patterns will help you reduce your attack surface without slowing down your engineering teams.

The Principle of Least Privilege in Practice

Least privilege sounds simple: give every identity only the permissions it needs to perform its job and nothing more. In practice, it is one of the hardest security principles to implement consistently because the path of least resistance is to grant broad permissions and move on.

AWS: Policies, Boundaries, and SCPs

AWS IAM uses JSON policy documents that specify which actions are allowed or denied on which resources under which conditions. Permissions are additive - if any attached policy grants an action, it is allowed (unless an explicit deny overrides it).

Start with AWS managed policies, then scope down. AWS provides managed policies like ReadOnlyAccess or PowerUserAccess as starting points. Use these for initial access and then create custom policies based on actual usage. AWS Access Analyzer can generate least-privilege policies from CloudTrail logs.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-app-bucket/uploads/*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/Team": "engineering"
        }
      }
    }
  ]
}

Permission boundaries cap the maximum permissions that an IAM entity can have, regardless of other policies attached. They are essential for delegation - allowing developers to create IAM roles for their applications without the risk of privilege escalation.

Service Control Policies (SCPs) enforce organization-wide guardrails. Common SCPs include preventing the use of IAM users with long-lived access keys, requiring encryption on storage services, and restricting resource creation to approved regions.

Azure: RBAC, Conditional Access, and PIM

Azure uses a hierarchical RBAC model where permissions are assigned at the management group, subscription, resource group, or individual resource level. Assignments inherit downward.

Use built-in roles before creating custom ones. Azure provides over 300 built-in roles. Custom roles should be created only when no built-in role matches the required permissions.

Azure Conditional Access adds context-aware policies to authorization decisions. You can require MFA for specific applications, block sign-ins from risky locations, or require compliant devices before granting access to sensitive resources.

Privileged Identity Management (PIM) provides just-in-time, time-bound role activation with approval workflows and audit logging. Configure PIM for all privileged Azure roles so that no one holds permanent Owner, Contributor, or User Access Administrator permissions.

GCP: Resource Hierarchy, Org Policies, and Workload Identity

GCP IAM binds roles to members at levels of the resource hierarchy: organization, folder, project, or individual resource. Bindings inherit down the hierarchy, so a role granted at the folder level applies to all projects within that folder.

Prefer predefined roles over primitive roles. GCP's primitive roles (Owner, Editor, Viewer) are extremely broad. Predefined roles like roles/storage.objectViewer or roles/compute.instanceAdmin.v1 provide much finer granularity.

Organization policies restrict what is possible across the organization, similar to AWS SCPs. Key policies include disabling service account key creation, restricting external sharing of resources, and enforcing uniform bucket-level access on Cloud Storage.

Cross-Account and Cross-Project Access

In multi-account (AWS), multi-subscription (Azure), or multi-project (GCP) architectures, workloads frequently need to access resources in other environments. The key principle is to use federated, temporary access rather than shared credentials.

AWS: Cross-account IAM roles. Create a role in the target account with a trust policy that allows the source account to assume it. The source workload calls sts:AssumeRole and receives temporary credentials. Never share access keys between accounts.

Azure: Cross-subscription RBAC. Assign roles at the management group level to grant access across multiple subscriptions, or use Azure Lighthouse for managed service provider scenarios.

GCP: Cross-project service accounts. Grant a service account from Project A a role on a resource in Project B. Use Workload Identity Federation to let workloads running outside GCP (CI/CD pipelines, on-premises services) authenticate without service account keys.

Service Accounts: The Most Overlooked Risk

Service accounts and machine identities are frequently the weakest link in cloud IAM. They tend to accumulate excessive permissions over time, rarely have their credentials rotated, and often lack the monitoring applied to human accounts.

Best practices for service accounts across all clouds:

  1. Inventory all service accounts. Many organizations have hundreds of service accounts created by different teams with no central visibility. Start by building a comprehensive inventory.
  2. Eliminate unnecessary accounts. If a service account has not been used in 90 days, disable or delete it.
  3. Avoid long-lived credentials. Use instance metadata service (AWS), managed identities (Azure), or attached service accounts (GCP) so workloads authenticate without stored keys.
  4. Apply least privilege aggressively. Service accounts should never have admin or owner roles. Scope permissions to the specific resources the workload needs.
  5. Monitor for anomalous usage. Alert on service account activity from unexpected IP addresses, unusual API calls, or access at unusual times.
# AWS: Find access keys older than 90 days
aws iam generate-credential-report
aws iam get-credential-report --output text --query 'Content' | base64 -d | \
  awk -F, '$5 == "true" && $6 != "N/A"' | \
  while IFS=, read -r user _ _ _ _ key_date _; do
    age=$(( ($(date +%s) - $(date -d "$key_date" +%s)) / 86400 ))
    [ "$age" -gt 90 ] && echo "$user: key is $age days old"
  done

Temporary Credentials and Short-Lived Tokens

Long-lived credentials - API keys, service account JSON files, static passwords - are the primary target for credential theft attacks. Every cloud provider offers mechanisms to eliminate them.

  • AWS STS (Security Token Service) - AssumeRole, AssumeRoleWithWebIdentity, and AssumeRoleWithSAML all return temporary credentials that expire automatically. Use IAM roles for EC2, ECS tasks, and Lambda functions.
  • Azure Managed Identities - System-assigned and user-assigned managed identities provide tokens through the instance metadata service, eliminating the need for stored credentials in application configuration.
  • GCP Workload Identity Federation - Allows external workloads to exchange identity tokens from an external IdP for short-lived GCP access tokens. No service account keys required.

The target state: Zero long-lived credentials in your cloud environments. Every access key, service account key file, and static secret represents a credential that can be stolen and used indefinitely.

Audit, Compliance, and Continuous Monitoring

IAM policies drift over time. Permissions are granted for urgent projects and never revoked. New services are adopted without proper IAM review. Continuous monitoring catches these issues before they become breaches.

Enable comprehensive audit logging:

  • AWS: CloudTrail (management and data events) with log file validation enabled
  • Azure: Azure Activity Log and Azure AD sign-in/audit logs shipped to a SIEM
  • GCP: Admin Activity and Data Access audit logs enabled for all services

Automated compliance checks:

  • Use AWS IAM Access Analyzer, Azure Advisor, or GCP IAM Recommender to identify overly permissive policies and unused permissions.
  • Deploy cloud security posture management (CSPM) tools to continuously scan for IAM misconfigurations.
  • Run regular access reviews where resource owners confirm that each IAM binding is still necessary.

Common Misconfigurations to Avoid

These misconfigurations appear repeatedly in cloud security assessments:

  • Wildcard actions and resources - Policies with "Action": "*" or "Resource": "*" grant far more access than intended. Always scope to specific actions and resource ARNs.
  • Public access on storage - S3 bucket policies, Azure Blob containers, and GCS buckets with allUsers or allAuthenticatedUsers access are a top breach vector.
  • Overprivileged CI/CD pipelines - Build pipelines often run with admin-level permissions. Scope them to only the resources they deploy.
  • Missing MFA on root/global admin accounts - The root account in AWS and Global Administrator in Azure should have hardware MFA and be used only for break-glass scenarios.
  • Unused IAM users and roles - Dormant accounts are attractive targets. Automate deprovisioning or review access quarterly.

Need help building this?

Our team specializes in turning these ideas into production systems. Let's talk.