Identity, Secrets & Encryption

The IAM Model

Four nouns explain every access decision in cloud infrastructure: an identity performs an action on a resource, and a policy says whether that is allowed. Everything else — roles, groups, conditions, boundaries — is a way of managing those four at scale.

The question this answers

Infrastructure question

When a request reaches a cloud service, what exactly decides whether it is allowed?

Application requirement

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".

What it provides

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.

Application RequirementInfrastructure RequirementComputeNetworkStorageIdentityDeploymentScalingReliabilityObservabilitySecurityCostTrade-offs

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.

One request, four nouns, one decision
signsallowno matching allow, or explicit denyevery decision is recordedIdentity image-workerRequest storage:GetObjectPolicy evaluation default deny; explicit deny winsResource uploads/8123/raw.jpgAudit trail who, what, when, from whereAccessDenied
ClientGateway / LBServiceWorkerDatabaseCacheQueue / LogObject storageCDNExternal system

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 kindExampleHow it authenticatesLifetimeThe mistake to avoid
HumanAn engineer debugging stagingInteractive login with MFAA sessionSharing the account, or letting an application reuse the credential
Application / workloadThe image workerPlatform-provided role credentialsMinutes, auto-renewedA static access key in an environment variable
CI/CD pipelineThe deploy jobFederated assertion from the CI providerOne job runA long-lived deploy key stored as a CI secret
Virtual machineAn instance in an autoscaling groupInstance metadata serviceMinutes, auto-renewedBaking credentials into the machine image
Container / podA pod in a clusterProjected service-account token exchanged for a cloud roleMinutes, auto-renewedMounting a node-wide credential into every pod
Serverless functionAn event handlerExecution role attached at invocationPer invocationOne shared role for every function in the account
AI agentA tool-using agentWorkload identity, ideally per taskShort, and revocable mid-taskBroad permissions because "we do not know what it will need"
Identity kinds and how each one should get its credential

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.

A workload policy that reads as one clear sentence
image-worker (container in the processing cluster)containerleast privilege
on bucket: user-media
Allowed
  • storage:GetObject on user-media/uploads/*
  • storage:PutObject on user-media/thumbnails/*
Actually needed
  • read the uploaded original
  • write the generated thumbnail
Explicitly denied
  • 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.

How it works
  • 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.
What you still own
  • 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.
How it fails
  • 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.
How it scales
  • 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.
Security
  • 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.
Cost shape
  • 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.
What to watch
  • 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.
Simpler alternatives
  • 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.
What adopting this costs
  • 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

Claim

IAM is about users and passwords.

Reality

Most identities are workloads with no password at all. Human login is the smallest part of the system.

Claim

If it is in a private subnet, IAM matters less.

Reality

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.

Claim

Granting a broader policy is a temporary fix.

Reality

It is a permanent fix, because nothing ever comes back to narrow it. Widening is an outage response; narrowing needs a scheduled owner.

Apply it