1. IAM 概述与核心概念:身份、认证、授权基础

说实话,刚接触 AWS IAM 的时候,我也被那一大堆术语搞晕过——用户、角色、策略、信任关系…… 后来带了几个项目才真正摸清门道。这一章我们先把地基打牢:身份、认证、授权这三个东西到底是什么,怎么配合。

别小看这三个词。我在不少客户环境里见过“策略权限放得太宽”的惨案——说白了就是没搞清谁在请求(身份),怎么证明是他(认证),以及允许他干什么(授权)。咱们一个个拆开看。

1.1 身份(Identity):谁在发起请求?

身份,英文叫 Principal。在 AWS 里,一个请求的发起方可以是:

  • IAM 用户 —— 长期存在的人或服务账号。
  • IAM 角色 —— 临时获取的一组权限,谁需要谁去“扮演”。
  • AWS 服务 —— 比如 EC2 实例、Lambda 函数,以服务角色身份去访问资源。
  • 联合身份 —— 企业 AD、Google、Facebook 等外部身份,通过 IAM 角色映射进来。
我的一点经验: 尽量少用长期 IAM 用户,多用角色 + 临时凭证。曾经有个项目因为 Access Key 泄露,被爬走了整张 DynamoDB 表…… 从那以后我每建一个用户都要掂量掂量。

1.2 认证(Authentication):你怎么证明是你?

身份说“我是张三”,认证要验证“你真的是张三”。AWS 支持多种认证方式:

  • 密码 —— 控制台登录用。
  • Access Key + Secret Key —— 程序调用 CLI、SDK、API 用。
  • 签名版本 4(SigV4) —— 每个请求都要用密钥签名,AWS 后端验证。
  • MFA —— 额外的一层保护,强烈建议对根用户和特权角色开启。
  • 角色切换时的令牌 —— 调用 AssumeRole 拿到的临时安全令牌。
⚠️ 千万别硬编码 Access Key: 代码里写死密钥是新手最容易犯的错。哪怕测试环境,也建议用环境变量或 AWS Secrets Manager。我接手过一个代码仓库,里面躺了 3 个没轮换过的 Access Key…… 那感觉就像门锁密码写在门框上。

1.3 授权(Authorization):你能干什么?

认证通过后,AWS 会问:这个身份有没有权限执行所请求的操作?授权靠的就是 策略(Policy)。策略是一系列 JSON 文档,声明允许或拒绝哪些操作、对哪些资源、在什么条件下。

授权决策的逻辑,我用一张表格讲清楚:

要素含义示例
Principal谁IAM 用户 Alice、角色 AdminRole
Action做什么s3:GetObject, ec2:RunInstances
Resource对什么arn:aws:s3:::my-bucket/*
Condition什么条件下IP 地址范围、是否使用 MFA、请求时间
Effect允许还是拒绝Allow / Deny

嗯,这里要注意:默认情况下所有请求都是隐式拒绝(Implicit Deny)。只有匹配到一条显式 Allow 策略,请求才会被放行。但是一旦有一条显式 Deny 策略命中,结果就是 Deny——不管有多少条 Allow 都救不回来。这种“显式拒绝优先”的机制,我经常用来做“安全护栏”:比如写一条 Deny 限制所有人(包括管理员)在非安络环境下上传敏感数据。

核心口诀: 没有显式 Allow → Deny;有显式 Deny → Deny。记住这个顺序,排查权限问题时能少走很多弯路。

1.4 三者关系:一张 SVG 图说清楚

下面这张图展示了身份、认证、授权在实际请求中的协作流程。我画这张图时才真正理解“策略评估点”在哪儿——很多开发小伙伴以为认证过了就能自由操作,其实后面还有一道授权审批。

身份、认证、授权协作流程 发起请求(谁?) 身份验证 授权检查 策略引擎 Allow / Deny 只有认证通过且授权允许的请求才能执行操作;认证失败或授权检查结果为 Deny 则直接拒绝。

1.5 身份、认证、授权组合策略的常见误解

我带团队的时候,发现很多新人会把“IAM 策略”和“桶策略”混为一谈。这里我必须声明:IAM 策略是附着在身份上的(用户、组、角色),而桶策略是附着在资源上的(S3 存储桶)。两者都能授权,但生效对象不一样。

举一个我见过的坑:某开发组在 S3 桶策略里写了 Allow 给一个 IAM 用户,但那个用户本身没有任何 S3 策略。实际上桶策略是生效的,因为桶策略可以直接指定 Principal。但如果用户需要做跨账号访问,那就必须配合 IAM 策略——光有桶策略远远不够。我曾经花了一下午排查一个“明明桶策略放开了,为什么还是 403”的问题,最后发现用户用的不是桶策略里指定的那些账号。

避坑指南: 测试权限时,用 aws s3 ls s3://bucket --no-sign-request 先测匿名访问,再用 IAM 用户凭证测试。这样能快速定位是身份问题还是授权问题。我记得有一次客户报“连不上”,结果是他本地配置的 ~/.aws/credentials 里 region 写错了…… 认证虽然过了,但操作被区域限制给阻拦——授权检查里的 Condition 没满足。

1.6 最小权限原则:贯穿始终的设计思想

聊聊每个 IAM 设计者都绕不开的原则——最小权限(Least Privilege)。简单说:每个身份只给完成工作所需的最小操作权限。不要一来就给 AdministratorAccess,虽然省事,但出事就是大事。

我在做安全审计的时候,经常看到类似这种松散的策略:

{
  "Effect": "Allow",
  "Action": "s3:*",
  "Resource": "*"
}

说实话,这条策略能让开发团队跑得飞快,但一旦有人在桶上误操作了 DeleteBucket,或者开了公开访问——后果不堪设想。正确做法是先读后写、限制桶前缀、加上条件:

{
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "Resource": "arn:aws:s3:::my-app-prod/uploads/*",
  "Condition": {
    "Bool": {"aws:SecureTransport": "true"}
  }
}

你看,只允许在 uploads/ 目录下读写,并且强制 HTTPS。这样即使密钥泄露,攻击者也搞不到其他目录的数据。

⚠️ 特别注意: 最小权限不是一成不变的。随着业务演进,要定期审查策略。我建议每季度用 IAM Access Analyzer 跑一次策略瘦身,把那些从来没调用过的权限移除。我在客户项目中发现过一个 IAM 角色里有 200 多个 Action,实际只用了 3 个…… 这就像带着一大串钥匙逛街,多一把就多一分丢的风险。

1.7 本章小结

身份、认证、授权是 IAM 的三根支柱。身份解决“谁来了”,认证解决“是不是他”,授权解决“他能做什么”。三者缺一不可,顺序也固定——先认证后授权。记住显式拒绝优先、隐式拒绝兜底,还有最小权限这个黄金法则,后面几章我们再深入用户、组、角色、策略的各种联合配置花样。

对了,上面那张 SVG 流程图,建议你保存下来贴在工位上。我当年就是这样把整个请求链记在脑子的——每次排权限问题就在脑海里过一遍这个流程,特别管用。