云安全 · 权限治理
用 AWS Organizations SCP 实现精细化的服务访问控制
架构师 Johnson Ethan发布于 2026 年 4 月 6 日

几乎每个把业务铺开的团队,都会在某个时刻遇到同一个尴尬:AWS 账户越开越多,谁能用哪些服务、哪些区域不该碰,慢慢就理不清了。等到真出了岔子,往往才发现权限早已松松垮垮。
与其等问题发生,不如把护栏提前架好。AWS Organizations 的服务控制策略(SCP) 正是为此而生——它不负责"给"权限,而是从组织顶层划定一条"再往上也不能越过"的红线。下面是我们在实践里摸索出的一套做法,不算复杂,但很耐用。
先理清几条规则
真正动手之前,有四件事值得先记在心里,后面的设计基本都是围着它们转的:
- 每个 OU 最多挂 5 条 SCP——单层容量有限,所以别想着把所有规则堆在一处。
- OU 可以一层层嵌套,用层级去承载不同粗细的限制。
- 子账户会继承父级的全部 SCP,限制自上而下叠加,不必在每个账户里重复一遍。
- 想对个别账户网开一面?用 策略条件 就能做账户级的例外,不用改动结构。
把结构搭起来
我们习惯让组织树长成这样:Root 之下先按职责分出 Security 和 Business 两条主线,各自再向下嵌一层,真正的成员账户挂在最末端。
code
Root (Up to 5 SCPs)
├── Security OU (Up to 5 SCPs)
│ └── Production OU (Up to 5 SCPs)
│ ├── Prod Account A
│ └── Prod Account B
└── Business OU (Up to 5 SCPs)
└── Application Team OU (Up to 5 SCPs)
├── App Account C
└── App Account D好处是每一层都能独立挂自己的 SCP,限制随着层级一路向下叠加。粗粒度的红线放在高层,越往下越贴近具体业务,职责清清楚楚。
给个别账户留扇门
光有层层收紧还不够,现实里总有"这个账户确实需要破例"的情况。这时候 Condition 就派上用场了——思路是"先一律拒绝,再把白名单里的账户放出来":
json
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:PrincipalAccount": ["111111111111", "222222222222"]
}
}
}读起来其实很直白:
- 默认拦下所有目标账户的这个操作;
- 唯独清单(
aws:PrincipalAccount)里的账户被放行; - 整个过程不碰 OU 结构,例外加得精准,回头也好审计。
一个账户到底被管成什么样
聊到这儿,常有人问:那某个账户最后到底受多少限制?答案是——把它这一路上经过的每一层 SCP 叠在一起,就是它真实的"活动范围"。
| 来源 | 说明 |
|---|---|
| Root SCPs | 组织根部的全局护栏 |
| Level 1 OU SCPs | 一级 OU(如 Security / Business)的限制 |
| Level 2 OU SCPs | 二级 OU(如 Production / Application Team)的限制 |
Root SCPs + Level 1 OU SCPs + Level 2 OU SCPs = 这个成员账户真正能做的事
落地之后
这套方法用下来,最直观的变化是心里踏实了不少:护栏由组织统一下发,不用再逐个账户去盯,也就少了策略悄悄跑偏的可能;真要开例外,靠白名单点对点放行,既精确又留痕;而随着账户越来越多,嵌套 OU 加继承的机制,也能跟着稳稳扩展,不至于哪天突然失控。
说到底,精细化权限管控不该是一锤子买卖,而是一套能长期陪着团队一起长大的机制。