惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
T
Threat Research - Cisco Blogs
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 叶小钗
Security Latest
Security Latest
Spread Privacy
Spread Privacy
aimingoo的专栏
aimingoo的专栏
N
News and Events Feed by Topic
Webroot Blog
Webroot Blog
U
Unit 42
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Scott Helme
Scott Helme
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
T
The Blog of Author Tim Ferriss
A
About on SuperTechFans
爱范儿
爱范儿
S
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Schneier on Security
Schneier on Security
Latest news
Latest news
GbyAI
GbyAI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
PCI Perspectives
PCI Perspectives
Jina AI
Jina AI
AI
AI
NISL@THU
NISL@THU
I
Intezer
G
GRAHAM CLULEY
B
Blog
S
Secure Thoughts
IT之家
IT之家
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
有赞技术团队
有赞技术团队
V2EX - 技术
V2EX - 技术
Recorded Future
Recorded Future
Hacker News - Newest:
Hacker News - Newest: "LLM"

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
AWS IAM Deep Dive
kt · 2026-05-17 · via DEV Community

Introduction

Every action on AWS goes through an HTTPS API, and IAM (Identity and Access Management) sits in front of every single one of them.

Once you actually run things on AWS, you notice IAM is where you get stuck. "It says AccessDenied." "The policy says Allow, why is it still rejected?" "I assumed the role but my credentials are still the old ones." The patterns are predictable.

This article takes IAM apart in the order auth happens: authentication, then authorization, then operations.

  1. What IAM actually solves: authentication vs authorization
  2. Principals: who is making the call
  3. SigV4: how AWS verifies the caller is real
  4. The six policy types and what each one does
  5. The shape of a policy JSON
  6. Policy evaluation: why Deny beats Allow
  7. IAM Identity Center and short-lived credentials
  8. The do / don't list

1. What IAM Solves: Authentication and Authorization

Start by separating authentication (AuthN) from authorization (AuthZ).

AuthN and AuthZ overview

  • Authentication (AuthN): pins down "who are you". On AWS, the caller is whoever owns the credentials that produced this SigV4 signature.
  • Authorization (AuthZ): decides "can they do this". AWS answers it by combining multiple policies and evaluating them together.

The rest of the article follows that same order: AuthN first, then AuthZ.


2. Principals: Who Is Calling AWS

In AWS, the entity making a call is called a Principal. Anything that can execute against a resource.

Type Credential Authenticated by When to use
Root User Account email + password AWS itself Almost never. Billing changes and a few special tasks only.
IAM User Access key (long-lived) or password IAM One per human or system. Long-lived keys are a leak risk.
IAM Role Short-lived credentials issued by STS AssumeRole The default. Roles over Users in modern setups.
Federated Identity External IdP token, swapped for AWS creds via STS Identity Center / SAML / OIDC The modern way humans log in.

An IAM Group is not a principal. It is just a container for attaching policies to a set of users. The group itself never authenticates and you cannot put it in the Principal field of a policy.

Don't Use the Root User

Root has god-mode on the whole account. Only Root can change billing or close the account, and that is exactly why everything else should not be done as Root.

The AWS-recommended setup:

  1. After creating the account, set up MFA on Root immediately (basically required now).
  2. Never create an access key for Root.
  3. For day-to-day work, log in through IAM Identity Center or assume an IAM Role.
  4. Lock the Root credentials in a safe.

For MFA, TOTP (the 6-digit code from Google Authenticator, 1Password, etc.) works, but AWS recommends FIDO2 / WebAuthn passkeys or hardware keys like a YubiKey, because they resist phishing. AWS also recommends registering at least two MFA methods on Root so you don't get locked out if one is lost.

Use IAM Roles Instead of IAM Users

The access keys on an IAM User (the ones that start with AKIA...) are long-lived. Once leaked, they stay valid until you rotate them. The stream of "committed an access key to GitHub, got abused within hours" stories isn't slowing down.

IAM Roles solve this by handing out short-lived credentials via AssumeRole that expire after 1 hour by default (12 hours max).

Three pieces to know before reading the diagram:

  • STS (Security Token Service): the AWS service that issues temporary credentials. sts:AssumeRole and friends call into this.
  • Trust Policy: a policy attached to a Role that says "who is allowed to assume this role" (e.g. "only this specific IAM User", "only this GitHub Actions repo").
  • Temporary credentials: a triple of AccessKeyId, SecretAccessKey, and SessionToken, with an expiry.

AssumeRole sequence


3. SigV4: How AWS Verifies a Request Is Real

Once we know who the principal is, the next question is whether they actually signed the request. That is what SigV4 (Signature Version 4) does.

A typical REST API sends something like Authorization: Bearer <token> on every call. AWS does not. It never sends the Secret Key on the wire. It sends a signature computed from the Secret Key, every time.

The Big Picture

SigV4 signing sequence

What the 4 Steps Actually Do

SigV4 four steps

Three things to internalize:

  1. The Secret Key never leaves your machine. Only an HMAC derived from it goes on the wire.
  2. Clock skew will kill you. The timestamp is baked into the signature scope. If your laptop's clock is off, you get InvalidSignature immediately. AWS tolerates roughly 15 minutes of skew.
  3. Signatures have a short validity window. To shrink the replay window, API calls only accept signatures from the last 15 minutes.

In practice the SDK and CLI do all of this for you, so you almost never compute it by hand. But when you see "calling another region from inside Lambda fails with a signature error" or "every S3 call from this Docker container returns 403", the answer is almost always clock sync.


4. The Six Policy Types and Who Does What

Now for authorization. The reason AWS authorization feels complicated is that six different policy types are evaluated together.

Policy Attached to Role How often used
Identity Policy User / Group / Role "What can this principal do?" ★★★
Resource Policy S3 bucket, KMS Key, SNS, etc. "Who can touch this resource?" ★★★
SCP (Service Control Policy) OU / Account (Organizations) Per-account ceiling (a guardrail) ★★
Permissions Boundary User / Role Per-principal ceiling
Session Policy Args to AssumeRole / GetFederationToken Extra narrowing that only applies in a session
RCP (Resource Control Policy) Organizations Org-wide guardrail on resources Newer

The trick is to keep "ceiling" and "permission" separate in your head. Identity Policy is the "what you may do" list. SCP and Permissions Boundary are the "the most you will ever be allowed to do" list. No Allow anywhere means no access; a Deny in the ceiling kills it for sure.


5. The Shape of a Policy JSON

Every policy uses the same JSON structure, with five elements.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowReadOnlyMyBucket",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": ["203.0.113.0/24"]
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

What to focus on:

  • Effect: only Allow or Deny. Default is Deny (if nothing says Allow, you get denied).
  • Action: s3:GetObject style, in <service prefix>:<API name> form. Wildcards (s3:*, s3:Get*) work.
  • Resource: the target, expressed as an ARN (Amazon Resource Name), e.g. arn:aws:s3:::my-bucket/*.
  • Principal: "who". Not needed in an Identity Policy because the attachment target is implied. Required in a Resource Policy.
  • Condition: extra constraints like IP, MFA, tags, time, VPC endpoint, and so on.

Condition Is Where Real IAM Lives

Once you start writing IAM seriously, you live inside Condition. The ones I reach for most:

Key What it does Example
aws:SourceIp Source IP Allow only from the office IP block
aws:MultiFactorAuthPresent Did the caller use MFA? Require MFA
aws:PrincipalTag/Team Tag on the principal If Team = ml, allow only ml-bucket
s3:prefix Prefix being listed in S3 A user can only ls their own folder
aws:RequestedRegion Target region Deny anything outside ap-northeast-1
aws:SecureTransport HTTPS? Block plaintext HTTP access to S3

6. Policy Evaluation: Deny Beats Allow

AWS evaluates the six policy types in this order to reach a final decision.

Policy evaluation flow

(Note: this is the simplified, same-account version. Cross-account access has extra rules, e.g. the Resource Policy Allow is required, but the picture above is enough to grasp the principle.)

Three Iron Rules

  1. Default is Deny. If nothing says Allow, the answer is no.
  2. An explicit Deny overrides an explicit Allow. A single Deny anywhere ends the discussion.
  3. You need at least one Allow. No Allow = denied.

Without these three, you cannot debug "the policy says Allow but I still get AccessDenied".

Common "Why Am I Denied?" Patterns

Symptom Cause
Identity Policy says Allow, still Deny An SCP is blocking that service at the org level
Can't access your own bucket The bucket policy names a different Principal
Lost permissions after AssumeRole A Session Policy was passed as an argument
Only some actions get Deny'd A Permissions Boundary is narrowing via wildcards
Denied in only one region An SCP or IAM Policy has a Region condition

Why SCPs Are Powerful

An SCP (Service Control Policy) is an AWS Organizations feature that caps what an OU or account is allowed to do. Attach this SCP to a Sandbox OU and accounts under it cannot launch EC2 outside Tokyo.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyOutsideTokyo",
      "Effect": "Deny",
      "Action": "ec2:RunInstances",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": "ap-northeast-1"
        }
      }
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

Even if an IAM policy inside the account allows RunInstances in every region, the SCP Deny wins. That is what a guardrail buys you.


7. IAM Identity Center and Short-Lived Credentials

The era of humans logging in as IAM Users is over. The standard now is IAM Identity Center (formerly AWS SSO).

IAM Identity Center topology

The points:

  • The user logs in once via the company IdP (Google / Okta / Entra), and AssumeRole gives them short-lived credentials into every AWS account under it.
  • The contents of the role are defined as a Permission Set. Build a few of them ("ReadOnly is this, dev is that") and assign per user × account.
  • No access keys are ever issued, so leak risk goes away structurally.
  • aws sso login covers the CLI side, dropping a temp token in ~/.aws/sso/cache.

For EC2 / Lambda / GitHub Actions

Non-human callers (apps, CI) should also not use long-lived keys. The current playbook:

Runtime Authentication
EC2 Instance Profile (attach a Role directly)
Lambda Execution Role
ECS / EKS Task Role / IRSA / Pod Identity
GitHub Actions OIDC, then AssumeRoleWithWebIdentity into an AWS Role
GitLab CI Same as above
External Kubernetes IAM Roles for Service Accounts (IRSA)

GitHub Actions OIDC is the strongest of the bunch: you can scope AssumeRole by repository or branch. Long-lived keys in GitHub Secrets become entirely unnecessary.


8. The Do / Don't List

Tying the theory back to practice.

❌ Don't

  • Create an access key for the Root user
  • Do day-to-day work as Root
  • Commit IAM User long-lived keys to GitHub
  • Hand out wildcards like s3:*
  • Use Principal: * in a Resource Policy without a Condition
  • Mix production and staging in the same account
  • Skip MFA entirely

✅ Do

  • Put MFA on Root and lock the credentials away
  • Move humans onto SSO via IAM Identity Center
  • Have GitHub Actions assume a Role via OIDC
  • Cap developer permissions with a Permissions Boundary
  • Set an org-wide guardrail with an SCP
  • Apply least privilege and audit with IAM Access Analyzer
  • Turn CloudTrail on in every account

Three of these are worth calling out:

  1. Treat long-lived access keys as something you will eliminate in the next few years. Roles + STS + Identity Center can cover the same ground.
  2. Be suspicious of *. Action *, Resource *, Principal *, no Condition: that combination is how incidents happen.
  3. CloudTrail and IAM Access Analyzer must be on. If you can't reconstruct "who did what" after the fact, an incident becomes unsolvable.

9. Conclusion

  • IAM handles both authentication (who?) and authorization (allowed to?).
  • Principals come in four kinds: Root, User, Role, Federated. Groups are containers, not principals.
  • AuthN uses SigV4: the Secret Key never leaves you, clock drift is fatal, signatures live for 15 minutes.
  • There are six policy types (Identity / Resource / SCP / Permissions Boundary / Session / RCP) and they are all combined.
  • Evaluation rules: default Deny, explicit Deny beats explicit Allow, you need at least one Allow.
  • Modern best practice is Identity Center + Permission Sets + OIDC-based role assumption.
  • Long-lived keys are game over once leaked. Replace them with Role + STS.

References