IAM: who can do what
Of the five primitives, IAM — Identity and Access Management — is the one that wraps all the others. Every single action in the cloud, by every person and every machine, passes through IAM first: is this actor allowed to do this thing to this resource? Get IAM right and your cloud is secure by construction. Get it wrong and nothing else matters — because over-permissive IAM is the single most common root cause of real cloud breaches. This lesson teaches the model and the one principle that governs it.
The core question IAM answers
IAM exists to answer one question, evaluated on every request:
Can this identity perform this action on this resource, under these conditions?
Break that into its pieces and you have the whole vocabulary:
- Identity (the who) — an actor that can be authenticated. Two flavors matter enormously:
- A user is a human (or a human's long-lived credential).
- A role (or service account) is an identity for a machine — an application, a VM, a function — so that software can act with its own permissions rather than borrowing a human's. This distinction is central; we'll return to it.
- Action (the what) — a specific operation, like "read an object," "delete a database," "launch a VM."
- Resource (the on what) — the specific thing acted upon: this bucket, that database.
- Policy (the rule) — a document that grants or denies a set of (action, resource) pairs to an identity. Policies are how permissions are actually written down.
Authentication vs authorization
Two words that sound alike and mean different things — IAM does both, in order:
- Authentication ("authn") — proving who you are. Logging in, presenting a key or token. It establishes your identity.
- Authorization ("authz") — deciding what you're allowed to do once your identity is known. This is the policy evaluation.
You authenticate to establish identity, then IAM authorizes each action against the policies attached to that identity. A valid login does not imply permission to do anything; authorization is a separate, per-action gate.
Policies, in practice
A policy is typically a small JSON document that lists allowed (or denied) actions on resources. Conceptually it reads like:
{
"Effect": "Allow",
"Action": ["storage:GetObject"],
"Resource": "bucket/my-app-assets/*"
}
In plain English: "Allow reading objects, but only from the my-app-assets bucket." Attach that policy to your application's role and the app can read those assets — and nothing else. The exact syntax differs per provider (this shape is AWS-flavored; GCP and Azure express the same idea differently), but the structure — who can do what to which resource — is durable across all of them.
Roles for machines: stop using long-lived keys
Here's a habit that separates secure cloud setups from insecure ones. When your application needs to read from a database or a bucket, it needs permission — but you should not give it a human's password or a long-lived secret key copied into the code. Instead, you attach a role (a machine identity) to the compute that runs the app. The cloud then hands the running code short-lived, automatically-rotated credentials for that role, behind the scenes. The app proves it is that compute and gets exactly the role's permissions — no secret to leak, no key to rotate by hand.
:::tip The durable rule for machine access Give machines roles, not keys. Attach a role/service account to your VM, container, or function and let the platform supply temporary credentials automatically. Hard-coded, long-lived access keys are a top source of breaches — they get committed to git, leaked in logs, and never rotated. Roles eliminate the secret entirely. This is one of the highest-leverage security habits in all of cloud. :::
The principle of least privilege
The one principle that governs all of IAM:
Least privilege: grant each identity the minimum permissions it needs to do its job — no more.
Not "admin access to be safe." Not "everything in this service just in case." If your function only reads one bucket, its role should allow reading that one bucket and nothing else. The reasoning is blast radius: if that identity is ever compromised — a leaked credential, a hacked server — the attacker inherits exactly its permissions. A least-privilege identity that can only read one bucket is a tiny, contained incident. An over-permissive "admin" identity is a catastrophe.
The opposite of least privilege — broad, lazy permissions — is the most common root cause of cloud breaches. A leaked key that can do everything is how a small mistake becomes a headline. Starting narrow and granting more only when something actually breaks is the durable discipline.
:::note Why IAM is the hardest 10% across providers Recall from Chapter 1 that the big three are ~90% the same — and IAM is the part of the remaining 10% that differs most. The concepts here (identity, action, resource, policy, role, least privilege) are universal and transfer everywhere. The exact policy syntax and role models are where AWS, GCP, and Azure genuinely diverge, and where porting between clouds takes real effort. Learn the concepts deeply; look up the per-provider specifics. :::
Why it matters
IAM wraps every other primitive: every action is gated by the question can this identity perform this action on this resource? You authenticate to prove identity, then IAM authorizes each action against policies. The two highest-leverage habits are durable and universal: give machines roles, not long-lived keys (so there's no secret to leak), and apply least privilege — the minimum permissions each identity needs — so a compromise has a tiny blast radius. Over-permissive IAM is the leading cause of cloud breaches, which makes this primitive the one most worth getting right. You now hold all five primitives — compute, storage, databases, networking, and identity. A short checkpoint locks them in, then Chapter 3 shows you how to provision all of them as code instead of by hand.
Where this leads: least privilege and machine roles are foundational to Cloud Security (Chapter 8), and they cross-link directly to the identity material in the Modern Security Engineer Guide.
Next: Chapter 2 checkpoint →