How to Set Up Multi-Cloud IAM in AWS, Azure, and GCP

How to Set Up Multi-Cloud IAM in AWS, Azure, and GCP

Implementing a storage bucket that restricts write access to a single service account serves as a critical test case for verifying cross-cloud security consistency. As organizations in 2026 increasingly distribute workloads across Amazon Web Services, Microsoft Azure, and Google Cloud Platform, the complexity of maintaining a unified security posture has scaled exponentially. The fundamental challenge lies not in the lack of security features, but in the divergent mental models each provider employs for identity management. While one platform might rely on flat JSON policy documents, another utilizes a hierarchical inheritance structure or a sophisticated role-based assignment system. Misalignment between these models often leads to over-provisioned accounts, where a developer mistakenly assumes that permissions in one cloud function identically in another. This technical debt creates invisible vulnerabilities that are frequently exploited before the infrastructure reaches production status.

To navigate this landscape, engineering teams must adopt a rigorous, systematic approach to Identity and Access Management (IAM). This requires a deep dive into how each provider authenticates identities, authorizes actions, and audits changes. The objective is to establish a least-privilege baseline where every machine and human identity possesses the absolute minimum set of permissions required to perform a specific task. By standardizing these configurations through a unified workflow, organizations can reduce the risk of lateral movement following a credential compromise. This article provides a comprehensive roadmap for configuring these environments, moving from basic tool installation to advanced automated auditing. Through the practical example of a restricted storage bucket, technical practitioners can observe the nuances of each cloud’s logic and develop a robust defense-in-depth strategy that spans the entire multi-cloud ecosystem.

Step 1: Set Up and Verify the Three CLI Tools

The first operational requirement for managing a multi-cloud environment is the installation and configuration of the native command-line interfaces for each provider. While web consoles are useful for visual exploration, the CLI offers the precision, repeatability, and speed necessary for professional infrastructure management. For AWS, the CLI version 2 remains the standard, allowing for sophisticated credential management through named profiles. Azure’s CLI provides a seamless integration with Microsoft Entra ID, facilitating interactive logins that respect enterprise conditional access policies. Meanwhile, the Google Cloud CLI, part of the broader gcloud SDK, is essential for managing project-based resources and service account impersonation. Ensuring these tools are up to date is not merely a matter of convenience; it is a security necessity, as newer versions frequently include patches for authentication vulnerabilities and support for the latest encryption protocols.

Verification of these tools must go beyond simple installation checks. After executing the initial login commands—aws configure, az login, and gcloud auth login—practitioners should immediately run identity-check commands to confirm that the active session corresponds to the intended low-privilege environment. Running aws sts get-caller-identity, az account show, and gcloud config list provides a definitive snapshot of the current authentication state. This step prevents the common and dangerous mistake of applying experimental IAM policies to production subscriptions or accounts. In a multi-cloud context, the risk of “terminal confusion” is high, where a developer executes a command in the wrong window against the wrong cloud. Establishing a clear, verified starting point for each CLI session acts as a fundamental guardrail for all subsequent configuration steps, ensuring that every command reaches the intended destination without unintended side effects.

Step 2: Align Cross-Cloud Vocabulary

A primary source of multi-cloud security failure is the linguistic and conceptual mismatch between different cloud providers. In AWS, an IAM Role is a distinct identity that can be assumed by users or services, whereas in Microsoft Azure, the concept of a Managed Identity serves a similar purpose but is more tightly integrated into the Azure Resource Manager (ARM) hierarchy. Google Cloud Platform introduces Service Accounts, which act as both an identity and a resource, allowing for a unique form of impersonation that differs significantly from AWS’s STS-based role assumption. Understanding these nuances is critical because a policy that seems restrictive in one environment might be surprisingly permissive in another due to how inheritance and default permissions are handled. Organizations must build a translation matrix that maps these terms to a common internal standard to avoid architectural misunderstandings.

Furthermore, the hierarchy of resource organization dictates how permissions propagate across the environment. AWS operates on a relatively flat structure within a single account, often utilizing Service Control Policies (SCPs) at the organization level to set broad boundaries. Azure utilizes a deeply nested structure of Management Groups, Subscriptions, and Resource Groups, where Role-Based Access Control (RBAC) assignments at a higher level automatically flow down to individual resources. Google Cloud follows a similar hierarchical model of Organizations, Folders, and Projects. The implications for IAM are profound: a single “Allow” statement at a high-level folder in GCP or a Subscription in Azure can inadvertently grant access to thousands of resources, whereas AWS requires more explicit per-account configuration. Mapping these hierarchies ensures that the security team understands the full scope of a permission grant before it is committed to the live environment.

Step 3: Initialize Test Storage Resources

To practically demonstrate cross-cloud IAM consistency, one must first establish identical target resources across all three platforms. In AWS, this involves creating an S3 bucket in a specific region, such as Sydney (ap-southeast-2), with all public access blocked by default. In Azure, the equivalent is a Storage Account containing a Blob container, which requires careful selection of the redundancy level and security settings to mirror the S3 environment. Google Cloud Platform requires a Cloud Storage bucket within a designated project. These resources act as the “proving ground” for the permission sets developed in later steps. By using a storage bucket as the test case, engineers can easily verify the most common IAM actions: reading metadata, writing objects, and deleting data. This controlled environment is essential for isolating IAM logic from other network-level or application-level interference.

During this initialization phase, specific attention must be paid to the default security settings that each provider applies to new storage resources. For instance, GCP buckets should be configured with “Uniform bucket-level access” to ensure that IAM policies are the sole source of truth for permissions, rather than legacy Access Control Lists (ACLs) that can create “shadow” access paths. Similarly, AWS buckets should have S3 Object Ownership set to “Bucket owner enforced” to disable ACLs entirely. Azure Storage accounts should be configured to require secure transfer and to disallow public blob access at the account level. By hardening these resources at creation, the team ensures that any access granted during the tutorial is the result of the specific IAM policies being tested, rather than a side effect of overly permissive default resource settings that might exist in a standard out-of-the-box configuration.

Step 4: Develop a Minimal-Access Identity in AWS IAM

Crafting a least-privilege identity in AWS starts with the creation of a focused IAM policy using the JSON format. This policy should explicitly list only the necessary actions, such as s3:PutObject and s3:GetObject, while targeting only the Amazon Resource Name (ARN) of the specific bucket created in the previous step. A common mistake is the use of wildcards, such as s3:*, which grants total control over the resource, including the ability to delete the bucket itself or modify its security settings. To add an extra layer of protection, an explicit “Deny” statement for the s3:DeleteObject action should be included. In AWS, a “Deny” statement always takes precedence over an “Allow” statement, providing a robust safety net against accidental permission escalation that might occur if the identity is later added to a more permissive group.

Once the policy is defined, it must be attached to an IAM Role rather than a static IAM User with long-lived access keys. Using roles is a best practice because they rely on temporary security credentials provided by the Security Token Service (STS), which expire automatically after a set duration. The role must also have a “Trust Policy” that defines which entities—such as an EC2 instance or a Lambda function—are permitted to assume it. This separation of the “Trust Policy” (who can use the role) and the “Permissions Policy” (what the role can do) is a hallmark of AWS security architecture. By deploying this configuration via the CLI, the engineer can ensure that the role is correctly provisioned and ready for the verification phase, providing a clear example of how AWS handles granular, resource-specific authorization in a multi-tenant environment.

Step 5: Build a Corresponding Role in Azure RBAC

Azure handles authorization through a Role-Based Access Control (RBAC) system that is significantly different from the policy-direct-attachment model of AWS. While Azure provides many built-in roles, such as “Storage Blob Data Contributor,” these are often too broad for a true least-privilege implementation because they include deletion rights. Therefore, a custom role definition is required. This definition is structured as a JSON object that specifies Actions, NotActions, DataActions, and NotDataActions. In the context of storage, the DataActions section is where the specific permissions for reading and writing blobs are defined. By placing the delete action in the NotDataActions category, the role is explicitly prohibited from performing deletions, mimicking the “Deny” logic used in the AWS example but within the native Azure RBAC framework.

After the custom role is defined, it must be assigned to a Managed Identity at the narrowest possible scope. In Azure, scope is a hierarchical concept; assigning a role at the Resource Group level is generally preferred over the Subscription level for localized tasks. This ensures that the identity has no visibility or power over resources in other resource groups within the same subscription. Managed Identities are the preferred identity type for Azure workloads because they eliminate the need for developers to manage credentials; the Azure infrastructure handles the rotation and protection of the underlying service principal’s secrets. This approach not only enhances security by reducing the risk of credential leakage but also simplifies the auditing process, as every action taken by the managed identity is logged with a clear link to the specific resource it was assigned to.

Step 6: Configure a Matching Policy Binding in GCP IAM

Google Cloud Platform’s approach to IAM is centered around the concept of “Policy Bindings,” which link a “Member” (such as a Service Account) to a “Role” at a specific level of the resource hierarchy. To implement the write-only test case, one must first create a dedicated Service Account. Unlike AWS, where policies are documents you write, GCP encourages the use of predefined roles that are maintained by Google. For this scenario, the roles/storage.objectCreator role is ideal, as it natively allows for object creation without granting read or delete permissions. This predefined role reflects GCP’s “curated” approach to security, where common use cases are encapsulated into standard roles to reduce the likelihood of administrative errors when writing custom JSON statements.

The critical step in GCP is ensuring that the role binding occurs at the bucket level rather than the project level. If a service account is granted the objectCreator role at the project level, it would gain the ability to write to every bucket within that project, significantly increasing the blast radius of a potential compromise. By using the gcloud storage buckets add-iam-policy-binding command, the permission is restricted to the single target bucket. This resource-level binding is the GCP equivalent of the specific ARN targeting used in AWS and the Resource Group scoping used in Azure. It demonstrates the importance of “scoping down” permissions regardless of the cloud provider’s specific terminology, ensuring that the service account remains a true least-privilege entity that cannot interfere with other project assets.

Step 7: Validate Permission Boundaries

Validation is the process of proving that the security controls work as intended through active, empirical testing. For each cloud provider, a series of controlled tests must be conducted using the newly created identities. The first test is a “positive” test: attempting to upload a file to the storage bucket. Using the CLI, the practitioner impersonates the identity—or uses its temporary credentials—to execute a write command. Success here confirms that the “Allow” or “Creator” permissions are correctly configured. However, the more critical test is the “negative” test: attempting to delete the file that was just uploaded. In a correctly configured environment, this action must return an “Access Denied” or “Permission Denied” error. This failure is the ultimate proof that the least-privilege boundaries are holding firm and that the identity cannot exceed its authorized mandate.

Throughout this validation phase, engineers should pay close attention to the specific error messages returned by each platform. AWS might return a 403 Forbidden error with a detailed message if the policy has an explicit deny, while Azure might provide a more generic authorization failure. GCP’s error messages often include the specific permission that was missing, which is invaluable for troubleshooting. These logs should be cross-referenced with the management consoles to ensure that the attempted actions are being recorded correctly in the audit trails. This step closes the loop on the configuration process, transforming a theoretical security design into a verified operational reality. It also provides the team with a set of repeatable test scripts that can be used to perform automated “smoke tests” whenever the IAM configuration is updated in the future, ensuring that no regressions are introduced.

Step 8: Establish Emergency “Break-Glass” Protocols

In a strictly controlled IAM environment, there is a risk that legitimate administrators could be locked out of the system due to a misconfiguration or a failure of the primary identity provider. To mitigate this risk, organizations must establish “Break-Glass” protocols—highly secure, rarely used access paths designed for emergency situations. In AWS, this usually involves a dedicated IAM user with the AdministratorAccess policy, protected by a hardware MFA token stored in a physical safe. This account should be excluded from standard SSO configurations to ensure it remains accessible even if the external identity provider (like Okta or Azure AD) is down. Every login to this account should trigger a high-priority alert to the security operations center, as its use indicates a critical failure or a major architectural change.

Azure and GCP provide native tools to manage this high-stakes access more elegantly. Azure uses Privileged Identity Management (PIM), which allows administrators to be “eligible” for a role rather than having it permanently assigned. When access is needed, the user must request activation, provide a justification, and potentially go through an approval workflow. This “Just-In-Time” access significantly reduces the window of opportunity for an attacker to exploit an admin-level account. GCP offers a similar concept through conditional IAM bindings and short-lived service account tokens. The common goal across all three platforms is to ensure that “God-mode” access is never a standing permission. By designing these emergency paths during the initial setup, organizations ensure they can recover from disasters without having to resort to insecure workarounds that might leave the environment vulnerable after the crisis has passed.

Step 9: Activate Comprehensive Audit Trails

An IAM configuration is only as good as the visibility provided by its audit logs. Without a permanent record of who granted permissions and who exercised them, it is impossible to satisfy regulatory requirements or conduct an effective forensic investigation after a breach. In AWS, CloudTrail must be enabled across all regions to capture every API call, including IAM changes and S3 data access events. In 2026, it is standard practice to stream these logs to a centralized, locked-down S3 bucket in a separate security account, where they can be analyzed by automated threat detection tools. This ensures that even if a primary account is compromised, the audit trail remains intact and tamper-proof, providing a source of truth for investigators.

Azure and GCP require similar configurations to achieve full visibility. Azure Monitor and Entra ID Audit Logs should be configured to export events to a Log Analytics workspace or a Sentinel instance for long-term retention and correlation. GCP provides Admin Activity logs by default, but Data Access logs—which record when someone actually reads or writes to a bucket—must be explicitly enabled for each service. These logs are high-volume and may incur costs, but they are essential for detecting “low and slow” data exfiltration attempts. By activating these comprehensive trails, the organization creates a “flight recorder” for their multi-cloud environment. This setup allows security teams to identify patterns of privilege abuse and provides the empirical data needed to pass audits for standards like APRA CPS 234 or the IRAP Protected framework in Australia.

Step 10: Codify Access Using Infrastructure as Code

Manual configuration through the web console or even the CLI is prone to human error and lacks a reviewable history. To achieve professional-grade multi-cloud IAM, organizations must transition to Infrastructure as Code (IaC) using tools like Terraform or OpenTofu. Terraform is particularly valuable in this context because it allows practitioners to define AWS Policies, Azure Role Assignments, and GCP IAM Bindings within a single set of configuration files. This codification ensures that the exact same security logic is applied across different environments (development, staging, and production), eliminating the “configuration drift” that often occurs when teams make manual “quick fixes” in one environment but forget to replicate them in others.

Furthermore, moving IAM into code enables the use of modern GitOps workflows. Every proposed change to a permission set must be submitted as a Pull Request, where it can be peer-reviewed by security specialists and tested against automated linting tools. For example, a pre-commit hook could scan a Terraform plan to see if any new AdministratorAccess roles are being created, automatically blocking the merge if they are. This shift-left approach to security ensures that over-privileged roles are caught in the design phase rather than being discovered by an auditor months later. By treating identity as code, the organization creates a self-documenting system where the intent behind every permission grant is recorded in commit messages, providing a clear audit trail and making it significantly easier for new team members to understand the security architecture.

Step 11: Extend Patterns to Human User Groups

While service identities handle machine-to-machine communication, human access requires a different set of management patterns centered around centralized identity providers. In 2026, the use of individual IAM users with long-lived passwords and manual MFA is considered an obsolete and dangerous practice. Instead, organizations should utilize AWS IAM Identity Center, Azure Entra ID, or Google Cloud Identity to federate human identities from a single source of truth. This allows users to sign in with their corporate credentials and gain access to all three clouds through a unified single sign-on (SSO) portal. This integration simplifies the user experience while centralizing the enforcement of security policies like password complexity, session duration, and device-based conditional access.

The management of these human identities must be group-based rather than individual-based. Permissions should never be assigned directly to a person; instead, they should be assigned to a functional group, such as “Cloud-Platform-Engineers” or “Data-Analysts.” When a new employee joins the company, adding them to the appropriate group in the central directory automatically grants them the correct level of access across all three cloud platforms. Conversely, when an employee leaves, removing them from that one central group instantly revokes their access to every AWS account, Azure subscription, and GCP project. This “one-in, one-out” philosophy is the most effective way to prevent the accumulation of “orphaned” accounts, which are a favorite target for attackers looking for an unmonitored entry point into a corporate network.

Step 12: Implement a Routine Access Audit

The final pillar of a robust multi-cloud IAM strategy is the implementation of a recurring access review process. Permissions that were necessary for a project six months ago may no longer be required, yet they often remain in place, creating a growing attack surface. To combat this “permission bloat,” teams must utilize the native auditing tools provided by each cloud. AWS IAM Access Analyzer can identify roles that haven’t been used in 90 days, while GCP’s IAM Recommender provides automated suggestions to downsize roles based on actual historical usage. Azure’s Access Reviews, part of Entra ID Governance, can automate the process of asking resource owners to re-verify that their team members still need specific high-level permissions.

Strategically, the organization prioritized these audits as a mandatory quarterly activity to ensure compliance with modern security standards. Administrators utilized automated reports to identify every identity with “Owner” or “Administrator” rights and required a documented business justification for each one. This proactive approach identified several dozen unused service accounts and over-privileged developer roles that were promptly remediated. By integrating these reviews into the standard operational calendar, the team transformed security from a one-time setup task into a continuous improvement process. The transition to a codified, audited, and group-based IAM model successfully reduced the organization’s risk profile, ensuring that the multi-cloud infrastructure remained resilient against both external threats and internal configuration errors. Actionable strategies were finalized to ensure that future expansions into new cloud regions would automatically inherit these hardened identity patterns from the established baseline.

Subscribe to our weekly news digest.

Join now and become a part of our fast-growing community.

Invalid Email Address
Thanks for Subscribing!
We'll be sending you our best soon!
Something went wrong, please try again later