策略模板
策略模板是一种新的 IAM 构造,旨在定义合作伙伴在客户账户中请求的临时权限。与常规 IAM 策略一样,其使用包含 Effect、Action、Resource 和 Condition 元素的语句来定义权限。关键区别在于,策略模板包含的参数(例如 @{bucketName})在您创建委派请求时会替换为实际值。
策略模板工作原理
作为载入过程的一部分,您可以向 Amazon 注册策略模板。Amazon 为每个模板分配一个唯一的 ARN,您在创建委派请求时会引用该 ARN。
创建委派请求时,您将指定:
策略模板 ARN
要替换到模板中的参数值
Amazon 将模板与您的参数值相结合,生成标准 IAM 策略。客户在批准您的委派请求时会审查这一最终呈现的策略,从而确切地了解将授予哪些权限。
注意
最终呈现策略的最大大小限制为 2048 个字符。
以下是一个简单的示例,展示模板替换的工作原理。
策略模板:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::@{bucketName}/*" } ] }
委派请求中提供的参数:
{ "Name": "bucketName", "Values": ["customer-data-bucket"], "Type": "String" }
最终呈现的策略(客户看到的内容):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::customer-data-bucket/*" } ] }
模板语法
策略模板使用两项关键功能来提供灵活性:参数替换和条件语句。参数替换允许您在模板中定义占位符,这些占位符在创建委派请求时会替换为实际值。条件语句允许您根据参数值包含或排除整个策略语句。
参数替换和类型
使用 @{parameterName} 语法在策略模板中定义参数。创建委派请求时,您必须指定每个参数的类型。
字符串
直接替换到模板中的单个值。
模板:
"Resource": "arn:aws:s3:::@{bucketName}/*"
参数:
{ "Name": "bucketName", "Values": ["my-bucket"], "Type": "String" }
呈现的结果:
"Resource": "arn:aws:s3:::my-bucket/*"
StringList
生成多个资源条目的多个值。在资源 ARN 中使用 StringList 参数时,它会扩展为针对每个值创建单独的资源条目。
模板:
"Resource": "arn:aws:s3:::@{bucketNames}/*"
参数:
{ "Name": "bucketNames", "Values": ["bucket-1", "bucket-2"], "Type": "StringList" }
呈现的结果:
"Resource": [ "arn:aws:s3:::bucket-1/*", "arn:aws:s3:::bucket-2/*" ]
交叉乘积行为
在同一个资源 ARN 中使用多个参数时,StringList 参数会创建所有组合的交叉乘积。
模板:
"Resource": "arn:aws:s3:::@{bucketNames}/@{prefix}/*"
参数:
[ { "Name": "bucketNames", "Values": ["bucket-1", "bucket-2"], "Type": "StringList" }, { "Name": "prefix", "Values": ["data"], "Type": "String" } ]
呈现的结果:
"Resource": [ "arn:aws:s3:::bucket-1/data/*", "arn:aws:s3:::bucket-2/data/*" ]
条件语句
使用 @Enabled 指令可根据参数值有条件地包含或排除整个语句。
语法:
@Enabled: "parameterName":参数值为“True”时包含语句
@Enabled: "!parameterName":参数值不为“True”(否定)时包含语句
模板:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "*" }, { "@Enabled": "ENABLE_S3_WRITE", "Effect": "Allow", "Action": ["s3:PutObject"], "Resource": "arn:aws:s3:::@{bucketName}/*" } ] }
参数(ENABLE_S3_WRITE 为“True”时):
[ { "Name": "bucketName", "Values": ["my-bucket"], "Type": "String" }, { "Name": "ENABLE_S3_WRITE", "Values": ["True"], "Type": "String" } ]
呈现的结果:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "*" }, { "Effect": "Allow", "Action": ["s3:PutObject"], "Resource": "arn:aws:s3:::my-bucket/*" } ] }
参数(ENABLE_S3_WRITE 为“False”时):
[ { "Name": "bucketName", "Values": ["my-bucket"], "Type": "String" }, { "Name": "ENABLE_S3_WRITE", "Values": ["False"], "Type": "String" } ]
呈现的结果:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "*" } ] }
ENABLE_S3_WRITE 设置为“True”时,将包含条件语句。设置为“False”时,将从呈现的策略中排除该语句。
其他示例
以下示例展示在临时委派中使用策略模板的常见模式。其重点介绍如何创建具有权限边界的 IAM 角色以实现长期访问,并展示将权限范围限定为特定资源的不同策略。这些示例说明如何使用 ARN 前缀、资源标记和权限边界更新等技术,在灵活性与安全性之间取得平衡。
示例 1:授予对特定资源的长期访问权限
以下权限边界作为“partner.com”的“SQSAccessorBoundary”提交:
{ "Effect": "Allow", "Action": [ "sqs:DeleteMessage", "sqs:ReceiveMessage", "sqs:SendMessage" ], "Resource": "arn:aws:sqs:*:*:*", "Condition": { "StringEquals": { "aws:ResourceAccount": "${aws:PrincipalAccount}" } } }
注意
这包括一个同账户条件,以避免向其他账户中具有开放资源策略的队列授予访问权限。由于该边界在所有客户之间共享且无法进行模板化,因此不能直接引用客户的账户 ID。
由于这是此策略的第一个版本,因此其 ARN 为 arn:aws:iam::partner:policy/partner.com/SQSAccessorBoundary_20250115
已提交以下策略模板用于获取临时访问权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sqs:ListQueues" ], "Resource": "arn:aws:sqs:*:*:*" }, { "Effect": "Allow", "Action": [ "iam:CreateRole", "iam:PutRolePermissionsBoundary", "iam:PutRolePolicy" ], "Resource": "arn:aws:iam::@{AccountId}:role/partner.com/SQSAccessor", "Condition": { "StringEquals": { "iam:PermissionsBoundary": "arn:aws:iam::partner:policy/partner.com/SQSAccessorBoundary_20250115" } } } ] }
示例 2:使用 ARN 前缀
权限边界可以指定资源 ARN 前缀来限制访问权限:
"Resource": "arn:aws:sqs:*:@{AccountId}:PartnerPrefix*"
这可将访问仅限于带有该前缀的资源,从而缩小可访问资源的范围。
示例 3:使用标签进行资源访问控制
您可以在临时委派的访问期间为资源添加标签,并依靠这些标签进行长期访问控制。
允许访问带标签资源的权限边界:
{ "Effect": "Allow", "Action": [ "sqs:DeleteMessage", "sqs:ReceiveMessage", "sqs:SendMessage" ], "Resource": "arn:aws:sqs:*:*:*", "Condition": { "Null": { "aws:ResourceTag/ManagedByPartnerDotCom": "false" }, "StringEquals": { "aws:ResourceAccount": "${aws:PrincipalAccount}" } } }
在创建新队列时为其添加标签的策略模板:
{ "Effect": "Allow", "Action": [ "sqs:CreateQueue", "sqs:TagQueue" ], "Resource": "arn:aws:sqs:*:*:*", "Condition": { "Null": { "aws:RequestTag/ManagedByPartnerDotCom": "false" } } }
为既有队列添加标签并创建角色的策略模板:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sqs:TagQueue" ], "Resource": "arn:aws:sqs:*:@{AccountId}:@{QueueName}", "Condition": { "ForAllValues:StringEquals": { "aws:TagKeys": "ManagedByPartnerDotCom" } } }, { "Effect": "Allow", "Action": [ "iam:CreateRole", "iam:PutRolePermissionsBoundary", "iam:PutRolePolicy" ], "Resource": "arn:aws:iam::@{AccountId}:role/partner.com/SQSAccessor", "Condition": { "StringEquals": { "iam:PermissionsBoundary": "arn:aws:iam::partner:policy/partner.com/SQSAccessorBoundary_20250115" } } } ] }
这种方法允许客户显式确认可以长期访问哪些特定资源。
示例 4:更新权限边界
要更新权限边界,请注册带有新日期后缀的新版本,并请求替换该版本的权限。
具有额外权限的更新权限边界:
{ "Effect": "Allow", "Action": [ "sqs:DeleteMessage", "sqs:PurgeQueue", "sqs:ReceiveMessage", "sqs:SendMessage" ], "Resource": "arn:aws:sqs:*:*:*", "Condition": { "StringEquals": { "aws:ResourceAccount": "${aws:PrincipalAccount}" } } }
作为第二个版本,此策略的 ARN 为:arn:aws:iam::partner:policy/partner.com/SQSAccessorBoundary_2025_01_20
更新现有角色权限边界的策略模板:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:PutRolePermissionsBoundary" ], "Resource": "arn:aws:iam::@{AccountId}:role/partner.com/SQSAccessor", "Condition": { "StringEquals": { "iam:PermissionsBoundary": "arn:aws:iam::partner:policy/partner.com/SQSAccessorBoundary_2025_01_20" } } } ] }
客户必须批准此委派请求,才能更新现有角色的权限边界。