托管策略与内联策略的区别:使用场景与选择建议
说到IAM策略,很多刚接触AWS的人都会问:策略到底写成内联好,还是做成托管策略好?这问题我几乎每次培训都会被问到。其实两种方式没有的对错,关键看你的场景和习惯。
先明确概念。托管策略是独立存在的IAM对象,可以挂到多个用户、组或角色上。内联策略则是直接嵌在某个实体里,跟那个实体绑定在一起。
我个人习惯先想一个问题:这份策略以后还要不要给别人用?如果答案是要,直接走托管策略。如果只是临时或者一次性,内联可能更轻量。
一句话总结:托管策略≈共享资源,内联策略≈私有资产。
一、核心差异速览
| 对比维度 | 托管策略 | 内联策略 |
|---|---|---|
| 可复用性 | 可附加给多个实体 | 只能属于一个实体 |
| 最大长度 | 每个策略 6,144 字符 | 每个实体内联策略总和 2,048 字符 |
| 版本管理 | 支持版本化,最多5个版本 | 不支持版本管理,修改即覆盖 |
| 跨账户共享 | 可通过策略授权给其他账户 | 无法跨账户 |
| 更新影响范围 | 所有附加的实体同步生效 | 只影响当前实体 |
| 删除风险 | 检查是否被引用,引用时无法删除 | 直接删除实体时一并删除,无提示 |
你看,最明显的区别就是复用性。托管策略能让你一次定义、到处使用。内联策略呢,就像在代码里硬编码配置,改起来麻烦。
二、什么时候该用托管策略?
我在项目中遇到过这样的场景:一个S3只读权限需要给20个开发人员,外加3个CI/CD角色。如果我给每个人写内联策略,光复制粘贴就得20次,而且万一要加个“禁止删除”条件,20个地方都得改。
- 通用权限需求 – 比如只读、管理员、特定服务操作。
- 多人或多角色共用同一组权限 – 团队标准权限直接挂托管。
- 需要版本控制 – 托管策略支持回滚到历史版本,应急时很有用。
- 跨账户授权 – 必须使用托管策略(结合角色信任策略)。
- 策略长度较大 – 超过2KB?托管策略上限更高。
补充一句:AWS自带的托管策略(比如 AdministratorAccess)也是托管策略的一种,虽然你不能改,但可以直接用。
三、什么时候内联策略反而更好?
你想想看,如果某个角色只需要一个非常特殊的权限,而且这个权限全公司就这一个实体用,写成托管策略反而浪费一个“名额”。内联策略最大的好处是“随实体而生,随实体而灭”。
- 一次性的、高度定制化的权限 – 比如给某个Lambda函数临时加入SQS发送权限。
- 实体级隔离 – 每个角色的权限各不相同,用内联更直观,不会误改到其他角色。
- 快速原型/实验 – 测试阶段用内联,确定后再重构为托管策略。
- 策略内容极短 – 只有一两条语句,长度远小于2KB。
我的小技巧:如果你不确定以后会不会扩展,先用内联。等出现第二个实体需要相同权限时,再抽成托管策略。不早不晚刚刚好。
四、选择决策流程图
下面这张图我把选择逻辑画成了流程。你可以跟着箭头走,看看自己属于哪条路。
五、代码示例对比
下面用S3只读权限为例,分别展示内联和托管写法。
内联策略(直接嵌入角色):
S3ReadOnlyRole → 内联策略文档:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*"
}
]
}
这个策略只能被 S3ReadOnlyRole 这一个角色使用。如果其他角色也需要,必须复制一遍。
托管策略(独立对象,可挂载):
先创建托管策略 MyS3ReadOnly:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*"
}
]
}
然后附加给角色 A、B、C。
我曾经踩过的坑:有一次我在一个生产环境的内联策略里加了“禁止删除”条件,结果发现半年后需要收回权限时,根本找不到哪个角色还有这个内联策略。每个角色都要点进去看,非常痛苦。后来我养成了习惯:只要策略可能被复用,就先定义为托管策略。
六、关于更新与回滚,再说两句
托管策略的版本管理是个很好用的特性。我习惯在修改托管策略前,先手动创建一个版本。万一新版本有问题,直接切回旧版本,秒恢复。内联策略就没有这待遇,一旦保存,上一个版本就丢了。
另外,删除托管策略时,AWS会检查它是否还被其他实体附加。如果还在用,它会拒绝删除,这就像一道安全门。内联策略则没有这个保护,你删除角色或用户,策略一起消失,连个确认都不会弹。
七、我的个人经验总结
做了这么多年IAM,我总结了三句话:
- 能复用就不写死 – 托管策略是首选,除非有明确理由。
- 内联策略只用于“独一份”的权限 – 比如某个Lambda的专属过墙权限。
- 定期评审 – 每季度检查一下内联策略,看有没有可以抽成托管的。
最后想说,策略管理其实是权限治理的第一步。选对托管还是内联,能让后面的审计和维护省掉很多麻烦。你想想看,如果代码都共享了,权限策略不共享,那不是自相矛盾吗?