IAM 与最小权限 · 云与可靠性
云账号里,谁可以做什么?
课程目录为什么需要它
云账号由权限策略来控制。策略太宽,一把泄露的密钥或一个 bug 就能变成对一切的访问:每个存储桶、每个数据库、每张账单。最小权限——只给每个应用它确实需要的权限,一点不多——是最有效的安全习惯之一,而它从正确读懂策略开始。
直觉理解
策略是一串语句。每条语句说:对这些资源上的这些操作,允许(Allow)或拒绝(Deny)。通配符很常见:s3:Get*、photos/*。
policy = [
{"effect": "Allow", "actions": ["s3:GetObject", "s3:PutObject"], "resources": ["shop-photos/*"]},
{"effect": "Deny", "actions": ["s3:*"], "resources": ["shop-photos/private/*"]},
]判断方法和 AWS IAM 一样(简化版):
- 找出操作和资源都匹配的语句。
- 只要有一条匹配的语句是 Deny → 拒绝。显式拒绝永远优先。
- 否则,只要有一条是 Allow → 允许。
- 否则 → 拒绝。没有任何语句允许的事情,一律不允许(隐式拒绝)。
最小权限的做法:列出应用真正要做的事(读照片、上传照片),只对这些资源允许这些操作。"actions": ["*"], "resources": ["*"] 正好相反。
定义
策略
A list of statements that allow or deny actions on resources.允许或拒绝对资源执行某些操作的一组语句。
显式拒绝
A matching Deny statement. It overrides every Allow.一条匹配的 Deny 语句。它压过所有 Allow。
最小权限
Granting only the actions and resources a job needs, nothing more.只授予完成工作所需的操作和资源,一点也不多。
示例
通配符
动手试试fnmatch 匹配 * 和 ? 的方式与 IAM 的模式相同。
import fnmatch
print(fnmatch.fnmatchcase("s3:GetObject", "s3:Get*"))
print(fnmatch.fnmatchcase("s3:PutObject", "s3:Get*"))
print(fnmatch.fnmatchcase("shop-photos/cats/1.jpg", "shop-photos/*"))
print(fnmatch.fnmatchcase("shop-photos", "shop-photos/*"))True False True False
- L3
- 匹配任意字符:Object。
True - L5这里的 * 也能跨过 /,所以文件夹下的一切都匹配。
True - L6模式要求名字后面有个 /,所以存储桶本身不匹配。
False
允许、拒绝、和什么都没有
动手试试显式拒绝压过允许;没有匹配就是不允许。
import fnmatch
def matches(patterns, value):
return any(fnmatch.fnmatchcase(value, p) for p in patterns)
def allowed(policy, action, resource):
hits = [s for s in policy if matches(s["actions"], action) and matches(s["resources"], resource)]
if any(s["effect"] == "Deny" for s in hits):
return False
return any(s["effect"] == "Allow" for s in hits)
policy = [
{"effect": "Allow", "actions": ["s3:GetObject", "s3:PutObject"], "resources": ["shop-photos/*"]},
{"effect": "Deny", "actions": ["s3:*"], "resources": ["shop-photos/private/*"]},
]
print(allowed(policy, "s3:GetObject", "shop-photos/cat.jpg"))
print(allowed(policy, "s3:GetObject", "shop-photos/private/id.png"))
print(allowed(policy, "s3:DeleteObject", "shop-photos/cat.jpg"))True False False
- L7操作和资源都匹配的语句。
- L8只要有匹配的拒绝,就拒绝。
- L18两条语句都匹配;Deny 胜出。
False - L19没有任何语句允许删除:隐式拒绝。
False
常见错误
对 "*" 允许 "*"
拥有全部权限的应用,任何 bug 或泄露的密钥都会变成整个账号被接管。列出它真正用到的操作。
以为 Allow 能压过 Deny
显式的 Deny 永远胜出,不管它来自哪里。「永远不许删除备份」这类护栏就是这么实现的。
长期有效的密钥
永不过期的访问密钥迟早会泄露。优先使用带短期凭证的角色,必须存在的密钥要定期轮换。
小测验
1. 一条语句允许对 `logs/*` 执行 `s3:*`;另一条拒绝对 `logs/*` 执行 `s3:DeleteObject`。应用能删除 `logs/a.txt` 吗?
查看答案
答案:A
顺序无关。任何匹配的 Deny 都压过所有 Allow。
2. 一个策略只允许 `s3:GetObject`。执行 `s3:PutObject` 会怎样?
查看答案
答案:A
隐式拒绝:没被允许的一律拒绝。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出判断每个请求
准确写出它打印的内容。
- 改需求最小权限
照片应用只需要读取和上传
shop-photos/uploads/下面的文件。它的策略却允许一切。把POLICY换成只对shop-photos/uploads/*允许s3:GetObject和s3:PutObject的策略。 - 从零写判断一个策略
自己写一个
allowed(policy, action, resource)。每条语句有"effect"("Allow"或"Deny")、"actions"和"resources"(带*和?的模式列表)。规则:- 只要有一个操作模式匹配
action,并且有一个资源模式匹配resource,这条语句就适用 - 有适用的 Deny →
False - 否则有适用的 Allow →
True - 否则
False
用
fnmatch.fnmatchcase(值, 模式)来匹配。 - 只要有一个操作模式匹配
本课术语
| 术语 | 中文 | 英文定义 |
|---|---|---|
| IAM | 身份与访问管理 | Identity and access management: who may do what in a cloud account. |
| Least privilege | 最小权限 | Only the permissions a job needs. |
| Implicit deny | 隐式拒绝 | Anything not explicitly allowed is refused. |