4. 服务控制策略SCP实战
服务控制策略(Service Control Policy,SCP)是 AWS Organizations 中用于集中限制成员账户可用权限边界的策略类型。它本身不授予任何权限,只负责“划定上限”:一个 IAM 身份或角色最终能否执行某个操作,取决于 SCP 允许的集合与 IAM 策略允许的集合之间的交集。理解这一点,是写好 SCP 的前提。
一、SCP 的语法结构
SCP 使用与 IAM 策略一致的 JSON 语法,核心字段包括 Version、Statement,以及语句中的 Sid、Effect、Action、Resource、Condition。与 IAM 策略不同的是,SCP 中的 Resource 通常写为 "*",因为 SCP 关注的是“能不能调用这个 API”,而不是“能操作哪个具体资源”。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyS3DeleteBucket",
"Effect": "Deny",
"Action": "s3:DeleteBucket",
"Resource": "*"
}
]
}
上面这段策略的含义是:禁止成员账户中任何身份删除 S3 存储桶。注意 Effect 只有 Allow 和 Deny 两种取值,Action 支持通配符如 s3:*、ec2:Describe*,Condition 可引用全局条件键,例如 aws:RequestedRegion、aws:PrincipalArn、aws:PrincipalTag 等。
二、允许与拒绝的判定逻辑
SCP 的判定遵循三条规则:
- 默认拒绝:如果没有任何 SCP 显式允许某个操作,该操作在成员账户中就被拒绝。
- 显式拒绝优先:只要任意一层 SCP 中出现
Deny,无论其他层是否Allow,该操作都会被拒绝。 - 必须逐层允许:从根到目标账户路径上的每一层 SCP,都必须对该操作存在
Allow,操作才可能被允许。
因此,SCP 的最终效果是“所有生效 SCP 的交集”。如果根上有一条 Allow *,某个 OU 上有一条 Allow s3:*,账户上又有一条 Allow ec2:*,那么该账户实际可用的服务范围是 s3 与 ec2 的交集,即两者都允许的部分;若账户上还有一条 Deny s3:DeleteBucket,则即使前面都允许,删除存储桶仍会被拒绝。
三、OU 级与账户级绑定
SCP 可以绑定到根、OU 或成员账户。绑定到 OU 时,该 OU 下所有账户(包括子 OU 中的账户)都会继承这条策略;绑定到账户时,只影响该账户。实际使用中,推荐“OU 级为主、账户级为辅”:把通用防护策略放在 OU 上,把个别账户的特殊限制放在账户级。
需要注意,SCP 不会影响管理账户(Management Account),也不会影响服务关联角色(Service-Linked Role)。此外,SCP 只对成员账户中的 IAM 用户和角色生效,对根用户同样生效,但根用户仍受其他限制约束。
四、常见防护策略编写
下面给出几条在生产环境中经常使用的 SCP 示例,可直接作为模板修改。
1. 禁止关闭 CloudTrail 与 GuardDuty
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ProtectSecurityServices",
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"guardduty:DeleteDetector",
"guardduty:DisassociateFromMasterAccount"
],
"Resource": "*"
}
]
}
2. 限制可使用的区域
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyNonApprovedRegions",
"Effect": "Deny",
"NotAction": [
"iam:*",
"organizations:*",
"cloudfront:*",
"route53:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"cn-north-1",
"cn-northwest-1"
]
}
}
}
]
}
这里使用 NotAction 排除全球性服务,避免误伤 IAM、Organizations 等必须跨区域调用的操作。
3. 禁止删除或修改关键资源
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyDestructiveActions",
"Effect": "Deny",
"Action": [
"s3:DeleteBucket",
"rds:DeleteDBInstance",
"ec2:TerminateInstances",
"kms:ScheduleKeyDeletion"
],
"Resource": "*"
}
]
}
4. 要求请求必须带特定标签
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequireProjectTag",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestTag/Project": "prod"
}
}
}
]
}
五、编写与验证建议
SCP 一旦绑定,影响范围大,建议先在测试 OU 或测试账户上验证。验证时可以使用 IAM Policy Simulator 或直接在成员账户中尝试目标操作,观察是否被拒绝。若发现误伤,优先检查 Deny 语句是否覆盖了不该覆盖的 Action,以及 Condition 中的条件键是否写错。
Allow *,再逐层在 OU 和账户上叠加限制,避免因一条策略导致整个组织无法操作。总结来说,SCP 的核心是“交集 + 显式拒绝优先”。掌握语法、理解判定逻辑、合理选择绑定层级,再配合常见防护模板,就能在 AWS Organizations 中建立起清晰、可维护的权限边界。