The question this answers
When a request reaches a cloud service, what exactly decides whether it is allowed?
The image worker must read from one bucket and write to another. The CI pipeline must deploy. A developer must debug in staging and not touch production. Nothing in this list is expressible as "give it access to the cloud account".
A uniform, auditable decision for every API call in the system: which identity made it, what it tried to do, to which resource, and which policy statement allowed or denied it.
Identity → Policy → Action → Resource
Every cloud API call is evaluated the same way. An identity is the actor: a person, a service, a pipeline, a virtual machine, a container, a function, an autonomous agent. An action is the specific operation requested — not "access", but storage:GetObject, db:Connect, compute:TerminateInstance. A resource is the specific thing acted on, identified by a path or an identifier, down to a bucket prefix or a single secret. A policy is the rule that connects them, and its output is allow or deny.
Two properties of the evaluation matter more than any syntax you will learn. First, the default is deny — nothing is permitted until something permits it, which is why a broken deployment usually shows up as an access-denied error rather than as data loss. Second, an explicit deny wins over any allow, which makes deny statements the tool for guardrails that a team cannot accidentally grant around.
Most of the complexity in real IAM systems is management machinery on top of these four nouns. Groups attach policies to many humans at once. Roles are identities you *assume* rather than *are*, which is how you get short-lived credentials (Roles vs Static Keys). Conditions narrow an allow by source network, time, request attribute or resource tag. Permission boundaries cap what a delegated administrator can grant. None of it changes the model; all of it exists because the model does not scale by hand.
The Security Engineering domain teaches authorization theory — RBAC, ABAC, the difference between authentication and authorization. What this domain adds is that in cloud infrastructure the *authorization system is the control plane*: it is not guarding a feature inside your application, it is guarding the ability to create, read, replace and destroy the infrastructure itself.
Identities are mostly not people
The word "user" misleads badly here. In a running system the overwhelming majority of identities are not humans, they authenticate without anyone present, and they act continuously. Counting them is a useful exercise: a small platform easily has three human identities and forty non-human ones.
They differ in how they obtain a credential, which is the property that decides how you should manage them. A human logs in interactively and should have multi-factor authentication. A virtual machine or container receives credentials from the platform through an instance metadata service or a projected token, with no secret stored anywhere. A CI pipeline federates from its provider using a signed assertion, so no long-lived key needs to exist. An AI agent is a workload identity whose *actions are chosen by a model reading untrusted input*, which is why its permissions deserve more scrutiny than any other identity in the system, not less.
The taxonomy is not academic. Every one of these gets a different answer to "where does the credential live, how long does it last, and what does offboarding look like" — and mixing them up is precisely the failure taught in Human vs Workload Identity.
| Identity kind | Example | How it authenticates | Lifetime | The mistake to avoid |
|---|---|---|---|---|
| Human | An engineer debugging staging | Interactive login with MFA | A session | Sharing the account, or letting an application reuse the credential |
| Application / workload | The image worker | Platform-provided role credentials | Minutes, auto-renewed | A static access key in an environment variable |
| CI/CD pipeline | The deploy job | Federated assertion from the CI provider | One job run | A long-lived deploy key stored as a CI secret |
| Virtual machine | An instance in an autoscaling group | Instance metadata service | Minutes, auto-renewed | Baking credentials into the machine image |
| Container / pod | A pod in a cluster | Projected service-account token exchanged for a cloud role | Minutes, auto-renewed | Mounting a node-wide credential into every pod |
| Serverless function | An event handler | Execution role attached at invocation | Per invocation | One shared role for every function in the account |
| AI agent | A tool-using agent | Workload identity, ideally per task | Short, and revocable mid-task | Broad permissions because "we do not know what it will need" |
Reading a policy as a sentence
A policy panel is the clearest way to see whether a grant is defensible, because it forces the four nouns to appear together. Read it as a sentence: *this identity may perform these actions on these resources, and may not perform those*. If the sentence is uncomfortably broad when spoken aloud, the policy is too broad.
The panel below is a well-scoped workload. It reads: the image worker may read objects under one prefix and write objects under another; it may not delete anything and may not touch any other prefix. That is a sentence a reviewer can evaluate in five seconds, which is the actual test of a good policy — not whether it is minimal in theory, but whether a human can tell.
The blast-radius line is the part most reviews skip and the part that matters most. It is the answer to "if this credential leaked right now, what would we be doing tonight?" For this policy the answer is bounded and unpleasant but survivable. For an administrator policy the answer is the whole account, which is why Least Privilege in Infrastructure treats blast radius as the unit of measurement.
- storage:GetObject on user-media/uploads/*
- storage:PutObject on user-media/thumbnails/*
- read the uploaded original
- write the generated thumbnail
- storage:DeleteObject on user-media/*
- storage:* on any other bucket
Blast radius: A leaked credential lets an attacker read uploaded originals and write arbitrary objects into the thumbnails prefix. Serious — user content is exposed and poisoned thumbnails could be served — but bounded: no deletion, no other bucket, no ability to change infrastructure or read the database.
Key points
- Every cloud access decision is identity + action + resource, evaluated against a policy, and the default is deny.
- An explicit deny always beats an allow, which makes deny the right tool for guardrails nobody can grant around.
- Most identities in a running system are not people; how each kind obtains its credential is what decides how you manage it.
- Groups, roles, conditions and boundaries are scaling machinery on top of the four nouns, not a different model.
- In cloud infrastructure the authorization system guards the control plane itself — the ability to create, replace and destroy the infrastructure.
- A good policy reads as one sentence a reviewer can judge in five seconds.
The loop, answered
Every field is required, which is why no lesson here can recommend something without saying what it costs and what simpler thing to consider first.
- • The caller signs the request with credentials that identify it — a session token, a role credential, a federated assertion.
- • The service extracts the identity, the requested action and the target resource from the request.
- • The policy engine gathers every policy that applies: attached to the identity, to the resource, to the group, plus any boundary or organization-level constraint.
- • It evaluates them: an explicit deny anywhere ends it; otherwise at least one allow must match the action and the resource, or the default deny applies.
- • The decision, the identity, the action, the resource and the source address are written to the audit trail — see Audit Trails.
- • Own the inventory of identities, especially the non-human ones nobody remembers creating.
- • Own the review cadence: policies accumulate grants and never lose them unless a person removes them.
- • Own the deprovisioning path for every identity kind — a workload role deleted with its workload, a human access revoked at offboarding.
- • Own the audit trail's retention and the alerting on top of it, because an unread audit log is only useful after a breach, not during one.
- • Own the guardrails: a small set of organization-wide explicit denies that no team can grant around by accident.
- • AccessDenied in production after a deployment, because the workload's role was never given the permission the new code path needs — the most common cloud deployment failure there is.
- • A permission granted to fix an incident at 02:00 and never removed, which is how policies drift toward administrator.
- • A wildcard resource that matched more than the author believed, usually because a prefix was not anchored.
- • An identity that still works months after the person or service it belonged to is gone.
- • A deny that fires unexpectedly because a boundary or organization-level policy applies at a level the team cannot see.
- • Policy count grows with services × environments, and hand-written policies stop being reviewable well before that number is large.
- • The fix is generation, not consolidation: define policies in infrastructure as code alongside the workload, so a new service brings its own narrow policy — see Infrastructure as Code.
- • Consolidating into a few broad shared roles is the tempting alternative and is how least privilege dies.
- • What actually runs out is review attention. A policy nobody reads is not a control.
- • This *is* the security boundary for infrastructure. Network controls limit reachability; IAM limits capability, and capability is what an attacker actually wants.
- • Grant to a role, not to a long-lived key, wherever the platform supports it — see Roles vs Static Keys.
- • Scope resources as narrowly as the service allows: a bucket prefix, a single secret, one table, one queue.
- • Separate control-plane permissions from data-plane permissions. Reading rows and deleting the database are wildly different powers that a careless policy grants together.
- • The audit trail is the only evidence you will have during an investigation. Its integrity and retention are part of the design, not an afterthought.
- • IAM itself is generally free; its cost is human — writing, reviewing and debugging policies.
- • The cost that matters is the cost of getting it wrong, which is an incident, and it is not linear in anything.
- • Over-broad policies have a quiet cost too: they make blast-radius estimation impossible, so every incident starts with an hour of scoping.
- • Audit-log storage and query is a real, growing line item on a large account — budget for it rather than discovering it.
- • AccessDenied rates by identity, which reveal both broken deployments and probing.
- • Use of high-privilege identities — every administrator action should be rare enough to be interesting.
- • Credentials not used in 90 days, which is the cheapest permission-pruning signal available.
- • Policy changes themselves, as events: who widened a policy, when, and in which change.
- • The signal that lies: "the application works". It works equally well with a correctly-scoped policy and with an administrator policy.
- • For a single-service, single-developer project, the platform's default service identity with a sensible starter policy is fine. Do not build a policy taxonomy for three resources.
- • Provider-managed predefined roles, which are broader than a hand-written policy but reviewed by the provider and vastly better than a wildcard someone wrote in a hurry.
- • Network-level isolation as a complement — a resource that cannot be reached is not protected, but it is a second wall. It is not a substitute for policy.
- • Application-level authorization for user-facing permissions. IAM governs infrastructure, and pushing per-user product rules into it produces thousands of policies nobody can review.
- • Buys precise, auditable capability control; costs real design and review effort per workload, forever.
- • Buys the ability to bound an incident; costs the friction of deployments that fail on a missing permission — which is the system working correctly.
- • Narrow policies buy small blast radii; they cost flexibility when the workload legitimately changes what it needs.
- • Provider-managed roles buy speed; they cost precision, because they are written for the general case rather than yours.
What people believe, and what is true
IAM is about users and passwords.
Most identities are workloads with no password at all. Human login is the smallest part of the system.
If it is in a private subnet, IAM matters less.
Network position limits who can reach a service; IAM limits what any reachable caller can do. Compromise one workload and the second wall is the only one left.
Granting a broader policy is a temporary fix.
It is a permanent fix, because nothing ever comes back to narrow it. Widening is an outage response; narrowing needs a scheduled owner.