一、IAM 是什么
IAM 是 Identity and Access Management 的缩写,中文叫身份与访问管理。它是 AWS 的"门禁系统",只回答一个问题:
谁 ,能对什么资源 ,做什么操作?
可以把 AWS 账号想象成一栋公司大楼:
- 大楼里的房间、柜子、机器,就是 AWS 的资源,比如存储桶、服务器、数据库。
- 进出大楼的人和程序,就是身份。
- 门禁系统决定谁能进哪个房间、能动哪些东西,这就是 IAM。
IAM 本身免费 ,而且是全局服务,不区分区域。
二、五个核心概念
| 概念 | 打个比方 | 说明 |
|---|---|---|
| Root 用户 | 老板的万能钥匙 | 注册 AWS 账号时用的邮箱账户,权限最大,不受普通 IAM 策略限制。日常不要用,锁好并开启 MFA |
| User(用户) | 员工的工牌 | 一个具体的人或程序在 AWS 里的长期身份 |
| Group(组) | 部门 | 把用户归到一起统一授权,比如"开发组""审计组" |
| Role(角色) | 前台的借用钥匙 | 不属于任何人,谁需要就临时借用,到时间自动作废 |
| Policy(策略) | 许可单 | 一份 JSON 文档,写明允许或禁止做哪些事 |
最重要的一点:User、Group、Role 本身没有任何权限,权限全部来自挂在它们身上的 Policy。
三、Policy:许可单怎么写
3.1 最小的例子
json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::shop-files/*"
}
]
}
逐行翻译:
| 字段 | 内容 | 意思 |
|---|---|---|
Version |
2012-10-17 |
策略语法的版本号,固定这么写 |
Statement |
[...] |
规则列表,可以写多条 |
Effect |
Allow |
允许(另一种取值是 Deny,表示禁止) |
Action |
s3:GetObject |
操作:读取 S3 里的文件 |
Resource |
arn:aws:s3:::shop-files/* |
作用对象:shop-files 存储桶里的所有文件 |
连起来读就是:允许读取 shop-files 里的所有文件。
3.2 四个字段
- Effect:允许还是禁止。
- Action :哪些操作,格式是
服务:操作,例如ec2:StartInstances(启动服务器)、s3:PutObject(上传文件)。 - Resource :作用在哪个资源上,用 ARN 表示。ARN 是 AWS 给每个资源起的"全名"。
- Condition (可选):附加条件,比如"只能操作打了
Env=dev标签的机器""必须输入过手机验证码"。
3.3 AWS 如何判断允许还是拒绝
只有三条规则,按优先级从高到低:
一个请求进来
│
├─ 有没有任何一条 Deny 命中? ── 有 ──► ❌ 拒绝(Deny 最优先,谁也推翻不了)
│ 没有
├─ 有没有任何一条 Allow 命中? ── 有 ──► ✅ 允许
│ 没有
└────────────────────────────────────► ❌ 拒绝(默认拒绝)
一句话概括:没写的都不允许,写了 Deny 的谁也放不开。
3.4 两种挂法
- 托管策略 :单独创建,可以同时挂到多个用户、组或角色上复用。AWS 也提供现成的托管策略,比如只读权限
ReadOnlyAccess。 - 内联策略:直接写在某个用户、组或角色身上,只属于它自己。
四、一个完整的例子
4.1 场景
一家公司在 AWS 上运行一个电商网站,用到这些资源:
- 一个 S3 存储桶
shop-files,存放用户上传的图片和发布包。 - 两台 EC2 服务器:开发机打了标签
Env=dev,生产机打了标签Env=prod。
使用者和需求如下:
| 使用者 | 需求 |
|---|---|
| 开发小张 | 可以启停开发机,可以查看文件。偶尔要发布生产,但必须验证手机验证码 |
| 审计员小王 | 所有资源都能看,但什么都不能改 |
| 生产机上跑的网站程序 | 能往 uploads/ 目录存取文件,能写日志。代码里不能出现任何密钥 |
4.2 整体设计
AWS 账号 111122223333
├── 组 Developers ──── 许可单 ShopDeveloperPolicy(自己写)
│ └── 用户 zhang(小张)
├── 组 Auditors ────── 许可单 ReadOnlyAccess(AWS 现成的)
│ └── 用户 wang(小王)
├── 角色 ProdDeployRole ──── 开发者带手机验证码才能借,用来发布生产
└── 角色 ShopWebServerRole ─ 绑定到生产服务器,给网站程序用
4.3 开发组的许可单 dev-policy.json
json
{
"Version": "2012-10-17",
"Statement": [
{ "Sid": "ViewEC2", "Effect": "Allow", "Action": "ec2:Describe*", "Resource": "*" },
{
"Sid": "ManageDevServersOnly",
"Effect": "Allow",
"Action": ["ec2:StartInstances", "ec2:StopInstances", "ec2:RebootInstances"],
"Resource": "arn:aws:ec2:*:111122223333:instance/*",
"Condition": { "StringEquals": { "aws:ResourceTag/Env": "dev" } }
},
{ "Sid": "ListFiles", "Effect": "Allow", "Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::shop-files" },
{ "Sid": "ReadFiles", "Effect": "Allow", "Action": "s3:GetObject",
"Resource": "arn:aws:s3:::shop-files/*" },
{ "Sid": "CanBorrowProdDeployRole", "Effect": "Allow", "Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111122223333:role/ProdDeployRole" }
]
}
| 规则(Sid 是规则的名字) | 意思 |
|---|---|
| ViewEC2 | 可以查看所有服务器的信息 |
| ManageDevServersOnly | 可以启动、停止、重启服务器,但只限带 Env=dev 标签的 |
| ListFiles | 可以列出 shop-files 里有哪些文件 |
| ReadFiles | 可以读取 shop-files 里的文件 |
| CanBorrowProdDeployRole | 可以申请借用"生产发布"这个角色 |
💡 新手常见的坑:"列出文件"(
ListBucket)作用于存储桶本身shop-files,"读取文件"(GetObject)作用于桶里的文件shop-files/*。两者的 Resource 写法不同。
4.4 生产发布角色 ProdDeployRole
每个角色都由两份策略组成。
① 信任策略 prod-trust.json:写"谁可以借我"
json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:root" },
"Action": "sts:AssumeRole",
"Condition": { "Bool": { "aws:MultiFactorAuthPresent": "true" } }
}]
}
翻译:本账号里的人可以借我,前提是输入过手机验证码(MFA)。
⚠️ 这里的
:root不是指 Root 用户,而是"整个账号"的意思。账号里具体谁能借,还要看这个人自己的许可单有没有允许借这个角色(见 4.3 的最后一条)。
② 权限策略 prod-deploy-policy.json:写"借到之后能做什么"
json
{
"Version": "2012-10-17",
"Statement": [
{ "Sid": "ManageEC2", "Effect": "Allow", "Action": "ec2:*", "Resource": "*" },
{ "Sid": "ManageFiles", "Effect": "Allow", "Action": "s3:*",
"Resource": ["arn:aws:s3:::shop-files", "arn:aws:s3:::shop-files/*"] },
{
"Sid": "NeverTerminateProd",
"Effect": "Deny",
"Action": "ec2:TerminateInstances",
"Resource": "*",
"Condition": { "StringEquals": { "aws:ResourceTag/Env": "prod" } }
},
{ "Sid": "NeverDeleteBucket", "Effect": "Deny", "Action": "s3:DeleteBucket",
"Resource": "arn:aws:s3:::shop-files" }
]
}
翻译:服务器和文件都可以管理,但绝不允许销毁生产服务器,也绝不允许删除整个存储桶。
这里先给了很大的权限,再用 Deny 挡住危险操作,正好演示了"Deny 最优先"。真实环境里,Allow 的范围应该收得更小。
4.5 网站程序角色 ShopWebServerRole
信任策略 ec2-trust.json:允许 EC2 服务器借我
json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}
权限策略 web-server-policy.json:只能存取 uploads/ 目录,并且能写日志
json
{
"Version": "2012-10-17",
"Statement": [
{ "Sid": "UploadsReadWrite", "Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::shop-files/uploads/*" },
{ "Sid": "WriteLogs", "Effect": "Allow",
"Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:us-east-1:111122223333:log-group:/shop/web:*" }
]
}
4.6 创建命令
下面的步骤都可以在网页控制台里点出来。这里给出等价的命令行写法,方便对照:
bash
# ① 开发组:建组 → 建许可单 → 挂到组上 → 建用户小张并加入组
aws iam create-group --group-name Developers
aws iam create-policy --policy-name ShopDeveloperPolicy --policy-document file://dev-policy.json
aws iam attach-group-policy --group-name Developers \
--policy-arn arn:aws:iam::111122223333:policy/ShopDeveloperPolicy
aws iam create-user --user-name zhang
aws iam add-user-to-group --user-name zhang --group-name Developers
aws iam create-login-profile --user-name zhang --password '<初始密码>' --password-reset-required
# ② 审计组:直接挂 AWS 现成的只读许可单
aws iam create-group --group-name Auditors
aws iam attach-group-policy --group-name Auditors --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
aws iam create-user --user-name wang
aws iam add-user-to-group --user-name wang --group-name Auditors
# ③ 生产发布角色:每次最多借 1 小时
aws iam create-role --role-name ProdDeployRole \
--assume-role-policy-document file://prod-trust.json --max-session-duration 3600
aws iam put-role-policy --role-name ProdDeployRole --policy-name ProdDeployAccess \
--policy-document file://prod-deploy-policy.json
# ④ 网站程序角色:EC2 不能直接挂角色,要先装进"实例配置文件"(Instance Profile),再绑到服务器上
aws iam create-role --role-name ShopWebServerRole --assume-role-policy-document file://ec2-trust.json
aws iam put-role-policy --role-name ShopWebServerRole --policy-name WebServerAccess \
--policy-document file://web-server-policy.json
aws iam create-instance-profile --instance-profile-name ShopWebServerProfile
aws iam add-role-to-instance-profile --instance-profile-name ShopWebServerProfile \
--role-name ShopWebServerRole
aws ec2 associate-iam-instance-profile --instance-id i-0123456789abcdef0 \
--iam-instance-profile Name=ShopWebServerProfile
4.7 效果验证
| 谁 | 做什么 | 结果 | 原因 |
|---|---|---|---|
| 小张 | 停止开发机 | ✅ | 开发组许可单允许 Env=dev |
| 小张 | 停止生产机 | ❌ | 没有 Allow,默认拒绝 |
| 小张 | 上传文件 | ❌ | 只允许了读取 |
| 小张借用 ProdDeployRole 后 | 停止生产机 | ✅ | 角色允许 ec2:* |
| 小张借用 ProdDeployRole 后 | 销毁生产机 | ❌ | Deny 最优先 |
| 小王 | 查看所有服务器 | ✅ | 只读许可单 |
| 小王 | 借用 ProdDeployRole | ❌ | 小王自己的许可单没有允许借用 |
| 网站程序 | 写入 uploads/a.jpg |
✅ | 角色允许 |
| 网站程序 | 写入 releases/v2.zip |
❌ | 只开放了 uploads/ |
五、Role 详解:借钥匙
5.1 Role 和 User 是什么关系
- User 是你的工牌:长期有效,只属于你一个人。
- Role 是前台的借用钥匙:不属于任何人,用的时候去借,到时间自动作废。
所以 Role 不会绑在某个 User 身上 。两者的关系是:User 需要时去借(扮演)Role。 这个动作在 AWS 里叫 AssumeRole ,由 AWS 的 STS 服务(安全令牌服务)负责发放临时凭证。
除了 User,下面这些身份也能借 Role:
- AWS 服务:EC2、Lambda、ECS 等,比如上面的网站程序角色。
- 另一个 AWS 账号:用于跨账号访问。
- 外部身份:公司统一登录(见第八节)、GitHub Actions 等。
5.2 借钥匙的三个步骤
vbnet
小张 AWS(STS)
│ ① 证明"我是小张",并申请借用 ProdDeployRole │
│ (用自己的 Access Key + 手机验证码) ──────────►│
│ │ ② 核对两张单子,两张都同意才放行:
│ │ · 小张的许可单:允许借这个角色吗?
│ │ · 角色的信任策略:信任小张吗?要求验证码吗?
│ ◄──────────── ③ 发放临时凭证(有效 1 小时)─────────│
│ ④ 用临时凭证操作生产服务器
借之前必须先证明自己是谁,不能匿名借用:
- 在网页上借(控制台的"切换角色"):小张已经用用户名、密码和验证码登录过,登录状态本身就证明了身份。
- 用命令行借 :命令行用小张自己的 Access Key 证明身份。
5.3 实操:用命令行借角色
推荐做法:在配置里定义好,之后命令行会自动去借。 编辑小张电脑上的 ~/.aws/config:
ini
[profile zhang]
region = us-east-1
[profile prod-deploy]
role_arn = arn:aws:iam::111122223333:role/ProdDeployRole
source_profile = zhang
mfa_serial = arn:aws:iam::111122223333:mfa/zhang
role_session_name = zhang-deploy
duration_seconds = 3600
region = us-east-1
| 配置项 | 意思 |
|---|---|
role_arn |
要借哪个角色 |
source_profile = zhang |
用小张自己的 Access Key 去证明身份 |
mfa_serial |
小张绑定的手机验证器 |
role_session_name |
给这次借用起个名字,会写进审计日志,事后能查到是谁借的 |
duration_seconds |
借多久,单位是秒 |
Profile(配置档)就是命令行里一组有名字的身份配置,用
--profile 名字选择使用哪一组。
使用效果:
bash
$ aws ec2 stop-instances --instance-ids i-0123456789abcdef0 --profile zhang
An error occurred (UnauthorizedOperation) ... # 用自己的身份操作生产机,被拒绝
$ aws ec2 stop-instances --instance-ids i-0123456789abcdef0 --profile prod-deploy
Enter MFA code for arn:aws:iam::111122223333:mfa/zhang: 123456
{ "StoppingInstances": [ ... ] } # 借用角色后,操作成功
背后发生了什么: 命令行替小张执行了下面这条借用命令。
bash
aws sts assume-role --profile zhang \
--role-arn arn:aws:iam::111122223333:role/ProdDeployRole \
--role-session-name zhang-deploy \
--serial-number arn:aws:iam::111122223333:mfa/zhang \
--token-code 123456 \
--duration-seconds 3600
5.4 临时凭证长什么样
上面的命令返回:
json
{
"Credentials": {
"AccessKeyId": "ASIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
"SessionToken": "FwoGZXIvYXdzE...(很长一串)",
"Expiration": "2026-10-14T10:30:00Z"
},
"AssumedRoleUser": {
"Arn": "arn:aws:sts::111122223333:assumed-role/ProdDeployRole/zhang-deploy"
}
}
- 临时凭证由三部分 组成:ID(以
ASIA开头)、Secret、SessionToken。还有一个过期时间Expiration。 - 审计日志里会记录
assumed-role/ProdDeployRole/zhang-deploy,所以能查到是小张做的。 - ⚠️ 借用期间,小张只有角色的权限,他自己原来的权限不会叠加进来。
5.5 过期了怎么办
过期后再操作,会报这个错:
vbscript
An error occurred (ExpiredToken): The security token included in the request is expired
原则:临时凭证不能续期,只能重新借一次,拿一份新的。 不同场景的处理方式:
| 场景 | 过期后会怎样 |
|---|---|
| 按 5.3 的方式配置了 profile | 命令行自动重新借用,只需要再输一次验证码 |
| 服务器(EC2、Lambda、ECS)上的程序 | AWS 在过期前就自动换新,程序完全感觉不到 |
| 自己写的长时间运行的程序 | 使用 SDK 自带的、会自动刷新的凭证类,比如 .NET 的 AssumeRoleAWSCredentials |
| 手动把临时凭证设成了环境变量 | 不会自动刷新,只能重新执行 assume-role |
| 网页控制台里切换了角色 | 到期后会被切回原身份,再切换一次即可 |
为什么要设计成会过期? 这样就算临时凭证被偷了,最多也只能用到过期为止。
5.6 有效期和提前作废
- 有效期:最短 15 分钟,最长等于角色设置的上限(默认 1 小时,最多可以设到 12 小时)。如果是"借了一个角色再去借另一个角色",最长只有 1 小时。
- 提前作废 :临时凭证不能删除,但可以在控制台的角色页面点 "撤销活动会话"(Revoke active sessions)。在此之前发出的所有临时凭证会立即失效。
- 离职时要注意 :删除小张这个 User 之后,他已经借到手 的角色临时凭证在过期前仍然有效,因为这份凭证用的是角色的权限。所以离职处理时,还要把相关角色的会话也撤销掉。
六、User 与 Access Key
6.1 User 的两种凭证
| 登录密码 | Access Key(长期) | Role 临时凭证(对比) | |
|---|---|---|---|
| 用途 | 人在网页控制台登录 | 命令行、程序调用 AWS | 命令行、程序调用 AWS |
| 组成 | 用户名 + 密码(+ 验证码) | AKIA... + Secret |
ASIA... + Secret + SessionToken |
| 有效期 | 长期(可以设置密码定期过期) | 永不过期,直到被删除 | 15 分钟到 12 小时 |
| 数量 | 1 个 | 每个用户最多 2 个 | 不限 |
两种凭证可以按需开通:只给程序用的 User 可以不设登录密码,只在网页上操作的人也可以没有 Access Key。
6.2 Access Key 是怎么拿到的
第 1 步:管理员给小张开账号。 创建 User zhang,并设置一个网页登录密码。这时小张还没有 Access Key。
第 2 步:小张登录网页,生成 Access Key。 依次点:
IAM → 用户 → zhang → "安全凭证"标签页 → "创建访问密钥" → 用途选择"命令行(CLI)" → 确认
页面会显示:
ini
Access key: AKIAIOSFODNN7EXAMPLE
Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY [显示] [下载 .csv 文件]
⚠️ Secret 只在这一页显示一次。 关掉页面后,谁都看不到它了,包括管理员和 AWS。丢了只能重新生成一把。
第 3 步:保存到自己电脑上。
bash
aws configure --profile zhang
按提示填入 Access Key ID、Secret、默认区域(us-east-1)和输出格式(json)。填完后,Key 保存在 ~/.aws/credentials 文件里:
ini
[zhang]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
为什么第一次必须在网页上生成? 用命令行生成 Key 本身就需要先有 Key,所以第一次只能用登录密码进网页去生成。
谁来生成更好? 管理员也可以替小张生成,但这样 Secret 就经过了别人的手。让小张自己生成更安全。为此,可以在开发组的许可单里加一条"只能管理自己的 Key",其中 ${aws:username} 会自动替换成当前登录的用户名:
json
{
"Sid": "ManageOwnAccessKeys",
"Effect": "Allow",
"Action": ["iam:CreateAccessKey", "iam:DeleteAccessKey", "iam:ListAccessKeys",
"iam:UpdateAccessKey", "iam:ChangePassword", "iam:GetUser"],
"Resource": "arn:aws:iam::111122223333:user/${aws:username}"
}
6.3 程序如何找到并使用 Key
去哪找: 命令行和各语言的 SDK 会按大致如下的顺序自动查找凭证,找到就用:
bash
命令行参数 → 环境变量(AWS_ACCESS_KEY_ID 等)→ ~/.aws 下的配置文件 → 容器的角色凭证 → EC2 服务器的角色凭证
所以代码里不需要、也不应该写死任何 Key。
怎么用: Access Key ID 相当于用户名,会随请求发给 AWS。Secret 相当于密码,但它不会在网络上传输,只在本机给每个请求做签名(SigV4)。AWS 收到后核对签名,就能确认请求确实来自小张。
6.4 为什么最多 2 把:为了不中断地轮换
bash
# 1. 生成第二把 Key,把程序切换到新 Key,并验证能正常工作
aws iam create-access-key --user-name zhang
# 2. 停用旧 Key(出了问题还能改回 Active)
aws iam update-access-key --user-name zhang --access-key-id <旧Key的ID> --status Inactive
# 3. 观察几天,确认旧 Key 已经没人在用
aws iam get-access-key-last-used --access-key-id <旧Key的ID>
# 4. 删除旧 Key
aws iam delete-access-key --user-name zhang --access-key-id <旧Key的ID>
6.5 Key 泄露了怎么办
长期 Key 最大的风险是:一旦泄露(比如被误提交到 GitHub),别人就能一直用下去。 发现泄露后:
- 立刻停用这把 Key。
- 在 CloudTrail(AWS 的操作审计日志)里按这个 Key 的 ID 查它做过什么,重点看有没有新建用户、新建 Key、启动大量服务器。
- 生成新 Key,删除旧 Key,清理攻击者可能留下的东西。
AWS 如果发现你的 Key 出现在公开的地方,会自动给这个用户挂上隔离策略并通知你。但不要依赖这个机制。
6.6 什么时候不该用 Access Key
| 场景 | 推荐做法 |
|---|---|
| 程序跑在 EC2、Lambda、ECS、EKS 上 | 用 Role(见第七节) |
| 开发人员本地使用命令行 | 用 IAM Identity Center(见第八节) |
| CI/CD 流水线(如 GitHub Actions) | 用 OIDC 借用 Role,流水线里不保存 Key |
| 服务器在 AWS 外面(比如自建机房) | 用 IAM Roles Anywhere(凭证书换临时凭证) |
| 第三方服务要访问你的账号 | 给它一个跨账号 Role + ExternalId,不要把 Key 交给它 |
| 以上都做不到 | 才用 Access Key:最小权限、定期轮换、监控最后使用时间 |
七、服务器上的程序:用 Role,不用 Key
以第四节的网站程序为例:
- 给生产服务器绑定
ShopWebServerRole(见 4.6 第 ④ 步)。 - 服务器内部有一个只有本机能访问的地址,叫实例元数据服务 。AWS 通过它给服务器提供角色的临时凭证,并且在过期前自动换新。
- 程序里的 SDK 会自动从这里取凭证,代码里一个密钥都不用写:
csharp
// 不传任何凭证,SDK 会自动拿到服务器角色的临时凭证
var s3 = new AmazonS3Client(RegionEndpoint.USEast1);
await s3.PutObjectAsync(new PutObjectRequest {
BucketName = "shop-files", Key = "uploads/a.jpg", FilePath = "a.jpg"
});
好处是:代码和配置里没有密钥可以泄露,凭证自动过期又自动更新,没有人需要手动管理。
八、IAM Identity Center:用公司账号统一登录
8.1 解决了什么问题
以前的做法:公司有好几个 AWS 账号(开发、测试、生产),就像有好几栋楼。每栋楼都要给小张单独办一张工牌,也就是 User 加 Access Key。楼越多,工牌越多。小张离职时,还要一栋一栋去收回。
用了 Identity Center 之后 :小张只用他的公司账号 ,就是平时登录邮箱、Teams 的那个。每次进楼前出示公司账号,门口当场发一张临时通行证。
8.2 和 Role 的关系
本质上还是借 Role。 只是证明身份的方式变了:以前靠 Access Key,现在靠浏览器里登录公司账号。
小张在浏览器登录公司账号(+ 验证码)
→ AWS 按管理员的配置,让他借用对应账号里的角色(比如"开发者")
→ 发放临时凭证,到期作废
8.3 小张怎么用
第一次:执行一次配置
bash
aws configure sso
它会问公司的登录地址,比如 https://mycompany.awsapps.com/start,这个地址由管理员提供。之后会自动弹出浏览器,小张登录公司账号,再选择进哪个 AWS 账号、用哪个角色。完成后,~/.aws/config 里会多出这样一段配置:
ini
[sso-session mycompany]
sso_start_url = https://mycompany.awsapps.com/start
sso_region = us-east-1
[profile zhang-dev]
sso_session = mycompany
sso_account_id = 111122223333
sso_role_name = Developer
region = us-east-1
平时:先登录,再干活
bash
aws sso login --profile zhang-dev # 弹出浏览器,用公司账号登录
aws s3 ls --profile zhang-dev # 登录后正常使用
过期怎么办 :登录状态有效期间,命令行会自动续临时凭证。登录状态也过期后,再执行一次 aws sso login,一般相当于每天登录一次,具体时长由管理员设置。小张电脑上只缓存临时凭证,没有任何长期密钥。
8.4 两种方式对比
| Access Key 方式 | Identity Center 方式 | |
|---|---|---|
| 电脑上存的是什么 | 永不过期的 Key | 只有临时凭证,过期就作废 |
| 用什么登录 | AWS 单独的一套账号 | 公司统一账号 |
| 有多个 AWS 账号时 | 每个账号都要建 User | 登录一次,选择进哪个账号 |
| 员工离职 | 要去每个账号删 User、删 Key | 公司账号一停用,所有 AWS 权限同时失效 |
8.5 管理员要做什么
- 开通 Identity Center,接入公司的账号系统,比如 Microsoft Entra ID。
- 创建权限集,也就是许可单模板,比如"开发者""只读"。
- 做分配,例如:"开发组"的人,在"开发账号"里,使用"开发者"权限集。
完成后,AWS 会自动在对应的账号里创建角色(名字形如 AWSReservedSSO_Developer_xxxx),员工登录后借用的就是这个角色。
九、最佳实践清单
- Root 用户:开启 MFA,不创建 Access Key,日常不使用。
- 最小权限:只给完成工作必需的权限。先从小开始,不够再加。
- 身份选型 :
- 人员登录用 IAM Identity Center。
- 程序在 AWS 上运行时用 Role。
- CI/CD 用 OIDC。
- 第三方访问用跨账号 Role。
- 按组授权:许可单挂在组上,人员进出只需调整组成员。
- 敏感操作要求验证码:在角色的信任策略里加 MFA 条件(见 4.4)。
- 用 Deny 兜底:对删库、销毁生产机这类不可逆操作,加显式 Deny。
- Access Key 是最后的选择:定期轮换,监控最后使用时间,绝不提交到代码仓库。
- 审计:用 CloudTrail 记录谁在什么时候做了什么;用 IAM Access Analyzer 找出权限过大或对外暴露的资源。
- 离职处理:停用账号的同时,撤销相关角色的活动会话。
十、常见问题
问:Role 会和 User 绑定吗? 不会。User 是在需要的时候去借用 Role,借用需要双方都同意:User 自己的许可单允许借,Role 的信任策略也信任这个 User。
问:借 Role 时需要提供自己的身份吗? 需要。必须先用自己的身份证明"我是谁":网页上靠登录状态,命令行靠 Access Key 或 Identity Center 的登录。不能匿名借用。
问:临时凭证过期了怎么办? 重新借一次。配置好的命令行、服务器上的程序都会自动处理,只有手动设置环境变量的情况需要自己重新执行。
问:Access Key 的 Secret 丢了能找回吗? 不能。重新生成一把新的,再删除旧的。
问:为什么说 Role 比 Access Key 安全? Access Key 永不过期,泄露后会一直有效。Role 的临时凭证会自动过期,而且不需要保存在代码或配置里。
十一、术语速查表
| 术语 | 一句话解释 |
|---|---|
| IAM | AWS 的身份与权限管理服务 |
| Root 用户 | 注册账号时的邮箱账户,权限最大 |
| User | 人或程序的长期身份 |
| Group | 一组 User,用于统一授权 |
| Role | 可以临时借用的身份,凭证会自动过期 |
| Policy | 用 JSON 写的许可单 |
| 信任策略 | 写在 Role 上,规定"谁可以借我" |
| 权限策略 | 规定"能做什么" |
| ARN | AWS 资源的全名,例如 arn:aws:s3:::shop-files |
| Access Key | 给命令行和程序用的长期凭证(ID + Secret) |
| STS / AssumeRole | 发放临时凭证的服务 / 借用角色这个动作 |
| SessionToken | 临时凭证特有的令牌,长期凭证没有 |
| MFA | 多因素认证,比如手机验证码 |
| Instance Profile | 把 Role 绑定到 EC2 服务器时用的"外壳" |
| Profile | 命令行里一组有名字的身份配置 |
| IAM Identity Center | 用公司账号统一登录 AWS 的服务 |
| 权限集 | Identity Center 里的许可单模板 |
| CloudTrail | 记录所有 AWS 操作的审计日志 |
总结
markdown
Policy(许可单:写明能做什么)
↙ 挂到 ↘ 挂到
User(长期身份) Role(临时身份)
· 登录密码 · 没有固定密码
· Access Key(永不过期) · 被借用时发临时凭证,到期作废
│ ↑
└────────── 去借 ───────────────┘
(服务器、CI 流水线、公司统一登录也都是借 Role)
记住三句话:
- IAM 回答"谁能对什么做什么":没写的都不允许,写了 Deny 的谁也放不开。
- User 是长期工牌,Role 是临时钥匙:借之前先证明自己是谁,借到的凭证到期就作废,过期了再借一次。
- 能用临时凭证,就不用长期密钥:人用 Identity Center,程序用 Role,Access Key 留到最后不得已时再用。