Identity and Access Management Essentials
Identity and Access Management Essentials IAM is the discipline (and, in cloud platforms, the specific service) that answers two questions for every request: wh…
Identity and Access Management Essentials
IAM is the discipline (and, in cloud platforms, the specific service) that answers two questions for every request: who is this (authentication) and what are they allowed to do (authorization). Get IAM wrong and you either lock legitimate users out or — far more commonly and far more dangerous — leave overly broad access open that turns one compromised credential into a full breach. IAM is not just "a login system"; it's the policy layer that governs every resource in a system.
RBAC vs ABAC
Role-Based Access Control (RBAC) grants permissions to roles, and assigns users to roles — a user's access is the union of what their roles allow. It's simple to reason about and audit ("who has the Admin role?") but becomes unwieldy when access needs depend on context: a user might need access to only their own department's records, or only during business hours, which RBAC alone can't express without exploding the number of roles.
Attribute-Based Access Control (ABAC) evaluates policies against attributes of the user, the resource, and the environment at request time — department, resource owner, time of day, IP location, data classification. It's far more expressive and scales better for fine-grained, contextual rules, but it's harder to audit at a glance ("who can access this?" now requires evaluating a policy engine, not reading a role list) and harder to reason about performance-wise since every request needs policy evaluation.
Most real systems use both: RBAC for the coarse "what kind of user is this" layer (admin/editor/viewer), and ABAC-style conditions layered on top for resource-scoped rules ("editors can edit documents they own or that are shared with their team"). Cloud IAM policies (AWS/GCP/Azure) are effectively ABAC engines that most teams use in an RBAC-ish way by attaching broad managed policies to roles.
Principle of Least Privilege
Least privilege means every identity — human or service — gets exactly the access it needs to do its job, and no more. It's the single highest-leverage IAM practice because it bounds the blast radius of any single compromised credential: if a CI pipeline's deploy token can only push to one specific S3 bucket, a leaked token can't be used to read the customer database, even though both live in the same AWS account.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowDeployToSpecificBucketOnly",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-app-prod-assets",
"arn:aws:s3:::my-app-prod-assets/*"
]
},
{
"Sid": "AllowCloudFrontInvalidationOnly",
"Effect": "Allow",
"Action": "cloudfront:CreateInvalidation",
"Resource": "arn:aws:cloudfront::123456789012:distribution/EDFDVBD6EXAMPLE"
},
{
"Sid": "ExplicitDenyOnOtherBuckets",
"Effect": "Deny",
"Action": "s3:*",
"NotResource": [
"arn:aws:s3:::my-app-prod-assets",
"arn:aws:s3:::my-app-prod-assets/*"
]
}
]
}Notice this policy names specific actions (`s3:PutObject`, not `s3:*`) scoped to specific resource ARNs, not `"Resource": "*"`. The explicit deny at the bottom is a belt-and-suspenders guard — in AWS IAM, an explicit `Deny` always wins over any `Allow`, even from a different attached policy, so it's a useful backstop against a future overly-broad policy being attached to the same role by mistake.
Least privilege is a process, not a one-time setup — permissions accumulate over time ("just add this one more action to unblock the deploy") and rarely get removed. Regular access reviews and tools that flag unused granted permissions (AWS IAM Access Analyzer, GCP Recommender) are how teams keep this from rotting.
SSO and Federation
Single Sign-On (SSO) lets a user authenticate once with an identity provider (IdP) — Okta, Azure AD/Entra ID, Google Workspace — and access many downstream applications without re-entering credentials for each one. Federation is the underlying trust relationship: the application (the service provider, SP) trusts assertions signed by the IdP instead of managing its own username/password database.
SAML (Security Assertion Markup Language) is the older, XML-based federation protocol, still dominant in enterprise SSO — the IdP sends a signed XML assertion to the SP after login. OIDC (OpenID Connect) is the modern standard, built on top of OAuth 2.0, exchanging JSON Web Tokens (JWTs) instead of XML — it's what most consumer "Sign in with Google/GitHub" flows and modern SaaS SSO integrations use. OAuth 2.0 itself is a related but distinct protocol: it's about authorization (granting an app scoped access to a resource, like "read my calendar"), not authentication — OIDC layers an identity/authentication token on top of OAuth's authorization flow.
SSO's real security value isn't convenience — it's centralization: revoke a user's access in the IdP once, and it cuts off every downstream app simultaneously, rather than an admin having to remember and manually disable a dozen separate accounts. It also lets an org enforce MFA, session timeouts, and conditional access policies in one place instead of per-application.
Provisioning and Deprovisioning Lifecycle
Every identity has a lifecycle: joiner (provision access on hire/onboarding), mover (adjust access on role change), leaver (revoke access on termination). Deprovisioning is the stage that gets neglected and causes the most incidents — a departed employee or contractor with lingering access to production systems, a Slack workspace, or a cloud console is a routine finding in breach post-mortems.
SCIM (System for Cross-domain Identity Management) is the protocol that automates this: the IdP pushes user create/update/deactivate events to every connected app (Slack, GitHub, AWS via IAM Identity Center, etc.) so deprovisioning in the IdP cascades everywhere within minutes instead of requiring an admin to manually walk a checklist across a dozen tools. Without SCIM or an equivalent automated process, deprovisioning depends entirely on someone remembering to do it — which is exactly the kind of manual step that gets skipped under time pressure.
For service accounts and machine identities, the same lifecycle applies but is even easier to neglect: a decommissioned service's IAM role or API key often keeps working indefinitely because nothing prompts anyone to revoke it the way an HR offboarding ticket prompts human deprovisioning.
Common Pitfalls
Wildcard permissions (`"Action": "*", "Resource": "*"`) granted "temporarily" to unblock something, then never scoped down — this is the single most common cloud IAM misconfiguration behind breaches.
Shared/generic accounts (a single "deploy-bot" credential used by five different services) — they make it impossible to attribute an action to a specific identity during an incident and can't be revoked for one consumer without breaking the others.
Long-lived static credentials (API keys with no expiry) instead of short-lived tokens — a leaked long-lived key stays valid until someone notices and rotates it, whereas a short-lived token minimizes the exposure window automatically.
Role/permission sprawl — roles created ad hoc over time with overlapping, inconsistent permissions until nobody can say what a given role actually grants without reading every attached policy.
No deprovisioning automation — manual offboarding checklists get skipped; SCIM or equivalent automated deprovisioning closes this gap.
Confusing authentication with authorization — verifying who someone is (MFA, SSO) says nothing about what they should be allowed to do; both layers are required and neither substitutes for the other.
Treating admin/root credentials as everyday accounts — the root/owner account of a cloud account should be locked away with MFA and used only for account recovery, with day-to-day work done through scoped IAM roles.