IAM policy 元素:变量和标签
在编写策略时,如果您不知道资源或条件键的精确值,可以使用 AWS Identity and Access Management (IAM) policy 变量作为占位符。
如果 AWS 无法解析变量,这可能会导致整个语句无效。例如,如果您使用 aws:TokenIssueTime
变量,只有在请求者(IAM 角色)使用临时凭证进行身份验证时,该变量才会解析为一个值。要防止变量导致无效的语句,请使用 ...IfExists 条件运算符。
介绍
在 IAM policy 中,您可通过很多操作为要控制其访问权限的特定资源指定名称。例如,以下策略允许用户在 Amazon S3 存储桶 mybucket
中列出、读取和写入具有前缀 David
的对象。
{ "Version": "2012-10-17", "Statement": [ { "Action": ["s3:ListBucket"], "Effect": "Allow", "Resource": ["arn:aws:s3:::mybucket"], "Condition": {"StringLike": {"s3:prefix": ["David/*"]}} }, { "Action": [ "s3:GetObject", "s3:PutObject" ], "Effect": "Allow", "Resource": ["arn:aws:s3:::mybucket/David/*"] } ] }
在某些情况下,您在编写策略时可能不知道资源的精确名称。您可能需要概括策略,这样无需为每个用户制作策略的唯一副本即可将该策略用于很多用户。例如,您要编写一条允许每位用户都可在 Amazon S3 存储桶中访问自己对象的策略,如上例所示。但不要为每个用户创建一个单独的策略,该策略明确指定用户的名称作为资源的一部分。相反,应创建一个适用于该组中的任何用户的组策略。
您可以通过使用策略变量实现这一点,该功能可让您在策略中指定占位符。当评估策略时,策略变量将被替换为来自请求本身上下文中的值。
您可以使用任何可用的单值条件密钥作为变量。您不能使用多值条件键作为变量。
以下示例显示了使用策略变量的 Amazon S3 存储桶的策略。
{ "Version": "2012-10-17", "Statement": [ { "Action": ["s3:ListBucket"], "Effect": "Allow", "Resource": ["arn:aws:s3:::mybucket"], "Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}} }, { "Action": [ "s3:GetObject", "s3:PutObject" ], "Effect": "Allow", "Resource": ["arn:aws:s3:::mybucket/${aws:username}/*"] } ] }
评估该策略时,IAM 将 ${aws:username}
变量替换为当前实际用户便于记忆的名称。这意味着适用于一组用户的单个策略可以控制对存储桶的访问。它通过将用户名作为资源名称的一部分来实现此目的。
该变量使用 $
前缀标记,后跟一对大括号 ({ }
)。在 ${ }
字符内,可以包含想要在策略中使用的请求中的值名称。本页稍后将讨论您可以使用的值。
为了使用策略变量,您必须在语句中包含 Version
元素,而且版本必须设置为支持策略变量的版本。变量是在 2012-10-17
版本中引入的。较早版本的策略语言不支持策略变量。如果您未添加 Version
元素,且没有将它设为相应的版本日期,则系统会将变量 (如 ${aws:username}
) 视为策略中的文字字符串。
Version
策略元素与策略版本不同。Version
策略元素用在策略之中,用于定义策略语言的版本。另一方面,当您更改 IAM 中的客户托管策略时,将创建一个策略版本。已更改的策略不会覆盖现有策略。而是由 IAM 创建新的托管策略版本。要了解 Version
策略元素的更多信息,请参阅IAM JSON 策略元素:Version。要了解策略版本的更多信息,请参阅IAM policy 版本控制。
您可以通过类似方式使用策略变量来允许每个用户管理自己的访问密钥。允许用户以编程方式更改用户 David
的访问密钥的策略如下所示:
{ "Version": "2012-10-17", "Statement": [{ "Action": ["iam:*AccessKey*"], "Effect": "Allow", "Resource": ["arn:aws:iam::
account-id
:user/David"] }] }
如果该策略附加到 用户 David
,那么该用户可以更改自己的访问密钥。对于访问特定用户的 Amazon S3 对象的策略,您必须为每位用户创建包含用户名称的单独的策略,然后将每个策略附加到各个用户。
通过使用策略变量,您可以创建如下所示的策略:
{ "Version": "2012-10-17", "Statement": [{ "Action": ["iam:*AccessKey*"], "Effect": "Allow", "Resource": ["arn:aws:iam::
account-id
:user/${aws:username}"] }] }
当您将策略变量用于这样的用户名称时,不必为每个单独的用户创建单独的策略。您可以改为将新策略附加到 IAM 组,该组包含应允许管理自己的访问密钥的每个人。当用户发出修改其访问密钥的请求时,IAM 将使用当前请求中的用户名称替代 ${aws:username}
变量并评估策略。
作为策略变量的标签
在某些 AWS 服务中,您可以将自己的自定义属性附加到这些服务创建的资源。例如,您可以将标签应用于 Amazon S3 存储桶或者 IAM 用户。这些标签是键值对。您要定义标签键名称以及与该键名称关联的值。例如,您可以创建一个具有 department
键和 Human Resources
值的标签。有关标记 IAM 实体的更多信息,请参阅 标记 IAM 资源。有关标记其他 AWS 服务创建的资源的信息,请参阅该服务的文档。有关使用标签编辑器的信息,请参阅《AWS Management Console 用户指南》中的使用标签编辑器。
您可以标记 IAM 资源来简化对您的 IAM 资源的发现、组织和跟踪。您也可以标记 IAM 身份以控制对资源或标记本身的访问。要了解有关使用标签控制访问的更多信息,请参阅使用标签控制对 IAM 用户和角色的访问以及他们进行的访问。
您可以使用策略变量的位置
您可以在 Resource
元素中和 Condition
元素的字符串比较中使用策略变量。
资源元素
您可以在 Resource
元素中使用策略变量,但只能在 ARN 的资源部分中使用策略变量。ARN 的这一部分出现在第五个冒号 (:) 之后。不能使用变量来替换 ARN 中第五个冒号之前的部分,例如服务或账户。有关 ARN 格式的更多信息,请参见IAM ARN。
以下策略可以关联到组。它给予 群组中的每位用户以编程方式访问 Amazon S3 中特定用户的数据元(自己的“主目录”)的完全权限。
{ "Version": "2012-10-17", "Statement": [ { "Action": ["s3:ListBucket"], "Effect": "Allow", "Resource": ["arn:aws:s3:::mybucket"], "Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}} }, { "Action": [ "s3:GetObject", "s3:PutObject" ], "Effect": "Allow", "Resource": ["arn:aws:s3:::mybucket/${aws:username}/*"] } ] }
此示例使用 aws:username
键,它将返回用户的易记名称 (比如“Adele”或“David”)。在某些情况下,您可能想要改用 aws:userid
键,它是全局唯一的值。有关更多信息,请参阅唯一标识符。
以下策略可用于 IAM 组。它为该组中的用户授予权限,以创建、使用和删除包含其名称以及位于 us-east-2 区域的队列。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "ListForConsole", "Effect": "Allow", "Action": "sqs:ListQueues", "Resource": "*" }, { "Sid": "AllQueueActions", "Effect": "Allow", "Action": "sqs:*", "Resource": "arn:aws:sqs:us-east-2:*:${aws:username}-queue" } ] }
要将 ARN 的一部分替换为标签值,请用 ${} 将前缀和键名称括起。例如,以下 Resource
元素仅指与请求用户的 department
标签中的值具有相同的命名的存储桶。
"Resource": ["arn:aws:s3:::bucket/${aws:PrincipalTag/department}"]
条件元素
您可以在任何涉及字符串运算符或 ARN 运算符的条件下对 Condition
值使用策略变量。字符串运算符包括 StringEquals
、StringLike
和 StringNotLike
。ARN 运算符包括 ArnEquals
和 ArnLike
。不能将策略变量与其他运算符(如Numeric
、Date
、Boolean
、Binary
、IP Address
或 Null
运算符)一起使用。有关条件运算符的更多信息,请参阅IAM JSON 策略元素:条件运算符。
以下 Amazon SNS 主题策略让 AWS 账户 999999999999
中的用户能够管理该主题(执行所有适用操作)。但是,仅当 URL 与其 AWS 用户名匹配时,才会授予此权限。
{ "Version": "2012-10-17", "Statement": [ { "Principal": { "AWS": "999999999999" }, "Effect": "Allow", "Action": "sns:*", "Condition": { "StringLike": { "sns:endpoint": "https://example.com/${aws:username}/" }, "StringEquals": { "sns:Protocol": "https" } } } ] }
当引用 Condition
元素表达式中的标签时,请将相关的前缀和标签键用作条件键。然后,使用要在条件值中测试的值。例如,以下策略示例仅在标签 costCenter
附加到用户时才允许完全访问 IAM 用户。该标签还必须具有值 12345
或 67890
。如果该标签没有值或具有任何其他值,则请求会失败。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:*user*" ], "Resource": "*", "Condition": { "StringLike": { "iam:ResourceTag/costCenter": [ "12345", "67890" ] } } } ] }
可以用于策略变量的请求信息
您可以使用 JSON 策略的 Condition
元素将请求上下文中的键与您在策略中指定的键值进行比较。当您使用策略变量时,AWS 使用请求上下文密钥中的值替换策略中的变量。
在所有请求中可用的信息
策略包含您可以使用其值作为策略变量的键。(某些情况下,密钥不包含值 - 请参阅此列表后的信息。)
-
aws:CurrentTime
这可用于检查日期和时间的条件。 -
aws:EpochTime
这是用纪元或 Unix 时间表示的日期,用于日期/时间条件。 -
aws:TokenIssueTime
这是颁发临时安全凭证的日期和时间,可用于日期/时间条件。注意:此键仅在使用临时安全凭证签名的请求中可用。有关临时安全凭证的更多信息,请参阅IAM 临时安全凭证。 -
aws:PrincipalType
该值表示主体是账户用户、联合身份用户还是担任的角色 - 请参阅后面的解释。 -
aws:SecureTransport
这是一个布尔值,该值指示是否已使用 SSL 发送请求。 -
aws:SourceIp
这是请求者的 IP 地址,用于 IP 地址条件。有关 IP 地址条件运算符 何时有效以及何时应该改用 VPC 特定键的信息,请参阅SourceIp
。 -
aws:UserAgent
此值是一个字符串,包含有关请求者的客户端应用程序的信息。此字符串由客户端生成,可能不可靠。您只能从 AWS CLI 中使用此上下文密钥。 -
aws:userid
该值是当前用户的唯一 ID - 参见下图。 -
aws:username
这是一个包含当前用户的易记名称的字符串 - 参见下图。 -
ec2:SourceInstanceARN
这是从中发起请求的 Amazon EC2 实例的 Amazon Resource Name (ARN)。仅在请求来自使用与 EC2 实例配置文件关联的 IAM 角色的 Amazon EC2 实例时,才提供此密钥。
密钥名称不区分大小写。例如,aws:CurrentTime
等同于 AWS:currenttime
。
主体键值
aws:username
、aws:userid
和 aws:PrincipalType
的值取决于发起请求的主体的类型。例如,可能使用 IAM 用户、IAM 角色或 AWS 账户根用户 的凭证发出请求。以下表为不同类型的主体显示这些键的值。
主体 | aws:username |
aws:userid |
aws:PrincipalType |
---|---|---|---|
AWS 账户根用户 | (不存在) | AWS 账户 ID | Account |
IAM 用户 | IAM 用户名称 |
唯一 ID | User |
联合身份用户 | (不存在) | 账户 :调用者指定的名称 |
FederatedUser |
Web 联合身份用户(Login with Amazon、Amazon Cognito、Facebook、Google) 有关在使用 Web 联合身份验证时可用的策略键的信息,请参阅使用 Web 联合身份验证识别用户的身份。 |
(不存在) |
其中, |
AssumedRole |
SAML 联合身份用户 有关在使用 SAML 联合身份验证时可用的策略键的信息,请参阅唯一标识基于 SAML 的联合中的用户。 |
(不存在) |
其中, |
AssumedRole |
担任的角色 | (不存在) |
其中, |
AssumedRole |
分配给 Amazon EC2 实例的角色 | (不存在) |
其中 |
AssumedRole |
匿名调用者(仅限 Amazon SQS、Amazon SNS 和 Amazon S3) | (不存在) | anonymous |
Anonymous |
对于此表中的项目请注意以下事项:
-
不存在 表示值在当前请求信息中不存在,并且匹配该值的任何尝试都失败并导致语句无效。
-
角色 ID
是在创建时分配给每个角色的唯一标识符。可以使用 AWS CLI 命令显示角色 ID:aws iam get-role --role-name
rolename
-
调用者指定的名称
和调用者指定的角色名称
是进行调用以获取临时凭证时调用进程 (例如应用程序或服务) 传递的名称。 -
ec2-instance-id
是在实例启动时分配给它的值,显示在 Amazon EC2 控制台的 Instances(实例)页面上。您还可以通过运行 AWS CLI 命令来显示实例 ID:aws ec2 describe-instances
联合身份用户的请求中的可用信息
联合身份用户是使用系统而不是 IAM 验证的用户。例如,公司可能拥有调用 AWS 的供内部使用的应用程序。为使用该应用程序的每位公司用户都提供 IAM 身份可能不现实。相反,该公司可能使用具有单一 IAM 身份的代理 (中间层) 应用程序,或该公司可能使用 SAML 身份提供程序 (IdP)。代理应用程序或 SAML IdP 会使用企业网络对单个用户进行身份验证。然后,代理应用程序可使用其 IAM 身份获取单个用户的临时安全凭证。实际上,SAML IdP 可以将身份信息交换为 AWS 临时安全凭证。然后,临时凭证即可用于访问 AWS 资源。
类似地,您可以创建用于移动设备的应用程序,该应用程序需要访问 AWS 资源。在这种情况下,您可以使用 Web 联合身份验证,其中应用程序使用知名身份提供程序 (如 Login with Amazon、Amazon Cognito,Facebook 或 Google) 对用户进行身份验证。随后,应用程序可以使用这些提供商提供的用户身份验证信息来获取访问 AWS 资源的临时安全凭证。
使用 Web 联合身份验证的推荐方法是利用 Amazon Cognito 和 AWS 移动开发工具包。有关更多信息,请参阅下列内容:
-
AWS Mobile SDK for Android 开发人员指南中的 Amazon Cognito 概述
-
AWS Mobile SDK for iOS 开发人员指南中的 Amazon Cognito 概述
特定服务的信息
请求还可以在其请求上下文中包含特定服务的密钥和值。示例包括:
-
s3:prefix
-
s3:max-keys
-
s3:x-amz-acl
-
sns:Endpoint
-
sns:Protocol
有关您可以用来获取策略变量值的特定服务键的信息,请参考与单个服务相关的文档。例如,请参阅以下主题:
-
Amazon Simple Storage Service 用户指南中的 Amazon S3 策略中的存储桶密钥
-
Amazon Simple Notification Service 开发人员指南中的 Amazon SNS 密钥。
特殊字符
有几个特殊预定义策略变量具有固定值,可用于表示字符 (这些字符本身有特殊的含义)。如果这些特殊字符是您尝试匹配的字符串的一部分,而您原样插入这些字符,则不能正确进行解释。例如,在字符串中插入 * 星号会解释为与任何字符匹配的通配符 (而不是解释为文本 *)。这种情况下,可以使用以下预定义策略变量:
-
${*} - 在需要 *(星号)字符的位置使用。
-
${?} - 在需要 ?(问号)字符的位置使用。
-
${$} - 在需要 $(美元符号)字符的位置使用。
在任何可以使用常规策略变量的字符串中,都可以使用这些预定义策略变量。
指定默认值
如果 AWS 无法解析变量,这可能会导致整个语句无效。然而,向策略添加变量时,您可以为变量指定默认值。如果未为变量指定值,则 AWS 会使用您提供的默认文本。
要向变量添加默认值,请用单引号 (' '
) 括起默认值,并用逗号和空格 (,
) 分隔变量文本和默认值。
例如,如果使用主体标记 team=yellow
,他们可以访问名为
的 DOC-EXAMPLE-BUCKET
-yellowExampleCorp's
Amazon S3 存储桶。使用此资源的策略可能允许团队成员访问自己的团队存储桶,但不能访问其他团队的存储桶。对于没有团队标签的用户,它将原定设置值设为 company-wide
存储桶名称。这些用户只能访问
存储桶,他们可以在其中查看广泛的信息,例如加入团队的说明。DOC-EXAMPLE-BUCKET
-company-wide
"Resource":"arn:aws:s3:::
-${aws:PrincipalTag/team, '
DOC-EXAMPLE-BUCKET
company-wide
'}"
有关更多信息
欲了解更多有关策略的信息,请参阅: