IAM Policy Languages
Three dialects, one mental model
AWS policies are JSON with Effect/Action/Resource/Condition; Azure RBAC uses role definitions + assignments with scope; GCP roles are collections of permissions bound to members. Knowing each dialect lets you author access confidently.
What you will learn
- Author and read AWS IAM JSON policies
- Apply Azure RBAC role definitions and scope
- Map GCP roles and permissions
AWS: JSON policies with Effect (Allow/Deny), Action, Resource, Condition, evaluated with deny-wins. Azure: role definitions (actions/notActions) assigned to a principal at a scope; deny assignments override. GCP: roles bundle permissions; members are bound to roles at org/folder/project/resource.
What is this?
AWS IAM policy language: Version, Statement[ ], each with Sid, Effect, Action/NotAction, Resource/NotResource, Condition (StringEquals, Bool, ArnLike...). Azure RBAC: built-in and custom role definitions with actions, dataActions, notActions; role assignments at scope; deny assignments. GCP: primitive (owner/editor/viewer), predefined (roles/storage.admin etc.) and custom roles of IAM permissions (storage.objects.get). Policy evaluation on AWS is identity+resource policies ∩ SCPs − denies; Azure adds deny assignments; GCP adds org policy constraints.
Why do you need it?
- Cross-cloud authoring is a real job skill — differences bite.
- Condition keys are where least privilege actually lives.
- Misreading scopes is the most common 'I think I granted x' confusion.
- Translation between dialects is a portfolio interview task.
Mental model
Three lease agreements for the same building
IAM languages
Same building (resources), different paperwork. AWS's lease lists allowed rooms by number (JSON). Azure's lease is signed per-floor with 'I may unlock these doors' (role at scope). GCP's lease says 'holder of this badge may open doors X, Y, Z' (role binds permissions). Learning one makes the others a translation puzzle.
How it works
- AWS: build Action + Resource + optional Condition; test with simulator.
- Azure: pick or create a role definition (actions), assign to member at scope; deny assignments and dataActions exist.
- GCP: choose/define role containing permissions; bind member at the lowest useful node.
- Wildcard handling differs: AWS '*' works broadly; Azure notActions subtract; GCP primitive roles bundle.
- Conditions: AWS condition keys (aws:SourceIp, RequireMFA); Azure supports attribute-based access constraints; GCP limited condition expressions.
Three policy shapes.
In production
- Cross-cloud engineers translate 'read-only' to S3 GetObject/ListBucket vs storage.objectViewer vs Storage Blob Data Reader.
- A condition-scoped AWS policy gates prod promotions to MFA+IP.
- Azure 'Reader' at RG scope compared to 'GCP viewer' at project scope reveal boundary semantics.
Best practices
- Always test with the provider's simulator/analysis before apply.
- Prefer fewer, precisely-scoped policies over wildcard-everything.
- Write conditions as the crown jewel: MFA, SourceIp, OIDC sub.
- Comment policy diffs in review with the business reason.
Common mistakes
- Assuming provle roles like Reader/Owner map 1:1 between providers.
- notActions vs Actions confusion leaves accidental permission width.
- Writing string comparisons for conditions in the wrong case/format.
- Testing in prod because 'the policy is trivial'.
Common issues
Azure shows allow but action failsDeny assignment at a higher scope or dataActions gap
Slice Assignments + deny assignments for that scope and add the dataAction.
GCP permission 'missing' despite roleThe role bundles a permission subset or binding at wrong node
List the role's permissions and verify the binding node.
Debugging tips
- Denied action: decode the error alert naming the missing permission/action.
- Use each provider's policy visualizer/analyzer to see effective allow vs deny.
- Diff expected vs actual policy: drift usually comes from edits outside PRs.
- For cross-cloud, keep a translation table in your notes.
Interview checkpoint
Quick quiz
In Azure RBAC, a role assignment is valid across which dimension?