Overview
Cloud IAM controls who, and what, can perform which action on which resource. IAM is not a one-time setup step but an ongoing discipline: grant the minimum permission required, prefer temporary or platform-managed credentials over long-lived secrets, and continuously audit access as roles, workloads, and team membership change. The underlying model is portable even though provider terminology is not: a principal receives permissions at a resource scope, sometimes constrained by conditions and higher-level guardrails, and every request is evaluated against that effective access.
Quick Reference
| Concept | What it is |
|---|---|
| Identity | A user, service account, or workload that can make requests |
| Policy | A document defining allowed/denied actions on resources |
| Role | An identity that policies attach to, assumable by users or workloads |
| Least privilege | Granting only the minimum permissions actually needed |
| Temporary credentials | Short-lived, auto-expiring access instead of permanent keys |
| Provider | Workload principal | Permission definition | Binding and scope |
|---|---|---|---|
| AWS | IAM role | Identity/resource policy | Policy attachment plus resource ARN and Organizations guardrails |
| Azure | Service principal or managed identity | Azure role definition | Role assignment at management group, subscription, resource group, or resource |
| Google Cloud | Service account or federated principal | IAM role | Allow policy binding on organization, folder, project, or resource |
Syntax
AWS: narrow object-read policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-app-uploads/*"
}
]
}Azure: managed identity with scoped data access
az identity create \
--name app-reader \
--resource-group rg-app
az role assignment create \
--assignee-object-id <managed-identity-principal-id> \
--assignee-principal-type ServicePrincipal \
--role "Storage Blob Data Reader" \
--scope /subscriptions/<subscription-id>/resourceGroups/rg-app/providers/Microsoft.Storage/storageAccounts/appdataExamples
AWS workloads assume roles to receive temporary credentials:
# Assume a role for temporary, auto-expiring credentials instead
# of using a long-lived access key directly.
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/deploy-role \
--role-session-name ci-deployAzure-hosted workloads should use a managed identity so Microsoft Entra manages and rotates the credentials:
# Run from Azure compute with the user-assigned identity attached.
az login --identity --client-id <managed-identity-client-id>
az storage blob list \
--account-name appdata \
--container-name uploads \
--auth-mode loginWildcard permissions are a standing liability
AWS "Action": "*"/"Resource": "*", Azure Owner/Contributor at subscription scope, and broad Google Cloud primitive roles are easy shortcuts and dangerous defaults. Narrow the permission, principal, and scope before shipping, not after an incident.
Troubleshooting Access
I use the same sequence across providers:
- Identify the principal: prove the account, tenant/project, user or workload identity, and immutable principal/object ID. Display names and client IDs are not substitutes for object IDs.
- Separate authentication from authorization: missing, invalid, expired, or wrong-audience tokens point to authentication. A valid identity denied a specific action points to effective permissions, scope, conditions, or an explicit deny.
- Inspect the complete decision: include inherited roles, resource policies, permission boundaries, organization guardrails, deny assignments, and session conditions. One visible role assignment is rarely the whole decision.
- Distinguish control and data planes: permission to configure a storage resource does not necessarily grant permission to read its objects or blobs.
- Account for propagation and caching: verify the assignment first, then refresh the session/token. I do not repeatedly add broader roles while waiting for a correct narrow assignment to propagate.
For AWS-specific policy evaluation use AWS IAM. For Microsoft Entra objects, Azure RBAC, and managed identities use Microsoft Entra ID.
Visual Diagram
Common Mistakes
- Using long-lived static credentials (access keys) for workloads that could instead assume a temporary, auto-expiring role, a leaked static key is a standing liability until manually rotated.
- Treating an AWS role, Azure role definition, and Google Cloud role as the same kind of object because they share a name.
- Giving an Azure workload a client secret when a managed identity or workload identity federation can remove the stored credential entirely.
- Granting broad or wildcard permissions during development and never narrowing them before production, because the narrower policy wasn't known yet and nobody circled back.
- Attaching permissions directly to individual users instead of to roles/groups, making access impossible to audit consistently as the team changes.
- Treating IAM as a one-time setup instead of an ongoing practice, permissions accumulate over time (drift toward more access) unless actively reviewed and pruned.
Performance
- IAM policy evaluation happens on every single request and is designed to be fast, but very large, deeply nested policy sets (thousands of statements) can measurably slow down evaluation and are also harder to audit correctly.
- Temporary credential issuance (assuming a role) adds a network round-trip compared to a static key, which is a negligible cost relative to the security benefit, but does mean credential-fetch logic needs to handle that latency and expiration/renewal correctly.
Best Practices
- Default to temporary or platform-managed credentials: AWS role sessions, Azure managed identities/workload identity federation, and Google Cloud workload identity federation instead of long-lived static keys or client secrets.
- Grant permissions to roles/groups, not individual users, so access can be audited and changed structurally rather than one person at a time.
- I start every new policy as narrow as possible and expand only when a real, specific need is hit, not the other way around.
- Schedule regular access reviews specifically looking for unused permissions and stale credentials, since drift toward over-permissioning is the default trajectory without active correction.