AWS JSON 策略元素:Principal - AWS Identity and Access Management

AWS JSON 策略元素:Principal

在基于资源的 JSON 策略中使用 Principal 元素指定允许或拒绝访问资源的主体。

您必须使用基于资源的策略中的 Principal 元素。包括 IAM 在内的多项服务支持基于资源的策略。IAM 中唯一基于资源的策略类型是角色信任策略。在 IAM 角色中,在角色的信任策略中使用 Principal 元素来指定可担任该角色的对象。对于跨账户存取,您必须指定受信任账户的 12 位标识符。要了解您信任区域之外的账户(受信任的企业或账户)中的主体是否有权承担您的角色,请参阅什么是 IAM Access Analyzer?

注意

创建角色后,您可以将账户更改为 "*",允许所有人担任该角色。如果执行此操作,我们强烈建议您通过其他方法 (如将访问只限定为特定 IP 地址的 Condition 元素) 限制能够访问该角色的用户。不要将角色的访问权限开放给所有人!

支持基于资源的策略的其他资源示例包括 Amazon S3 存储桶或 AWS KMS key。

无法在基于身份的策略中使用 Principal 元素。基于身份的策略是附加到 IAM 身份(用户、群体或角色)的权限策略。在这些策略中,附加了策略的身份即是主体的身份。

指定主体

您可以在基于资源的策略的 Principal 元素中或在支持主体的条件密钥中指定主体。

您可以在策略中指定以下任意主体:

  • AWS 账户 和根用户

  • IAM 角色

  • 角色会话

  • IAM 用户

  • 联合身份用户会话

  • AWS 服务

  • 所有主体

您无法在策略(例如基于资源的策略)中将用户组标识为主体,因为组与权限相关,与身份验证无关,并且主体是经过身份验证的 IAM 实体。

您可以使用数组在以下部分中为每个主体类型指定多个主体。数组可以采用一个或多个值。如果您在该元素中指定多个主体,则表示您向每个主体授予权限。这是逻辑 OR 而不是逻辑 AND,因为您一次被认证为一个主体。如果包含多个值,请使用方括号([])并用逗号分隔数组的每个条目。以下示例策略定义了 123456789012 账户或 555555555555 账户的权限。

"Principal" : { "AWS": [ "123456789012", "555555555555" ] }
注意

您不能使用通配符匹配一部分主体名称或 ARN。

AWS 账户 主体

您可以在基于资源策略的 Principal 元素中或支持主体的条件键中指定 AWS 账户 标识符。这将权限委派给账户。当您允许访问其他账户时,该账户中的管理员必须为该账户中身份(IAM 用户或角色)授予访问权限。在指定 AWS 账户 时,您可以使用账户 ARN (arn:aws:iam::account-ID:root) 或 "AWS": 前缀后加账户 ID 构成的简略格式。

例如,给定账户 ID 为 123456789012 的情况下,您可以使用以下任一方法来在 Principal 元素中指定账户:

"Principal": { "AWS": "arn:aws:iam::123456789012:root" }
"Principal": { "AWS": "123456789012" }

账户 ARN 和缩短的账户 ID 的行为方式相同。两者都向账户委派权限。在 Principal 元素中使用账户 ARN 并不会将权限限制为该账户的根用户。

注意

当您保存包含缩短账户 ID 的基于资源的策略时,服务可能会将其转换为主体 ARN。这不会更改策略的功能。

某些 AWS 服务支持其他用于指定账户主体的选项。例如,Amazon S3 允许您使用以下格式指定规范用户 ID

"Principal": { "CanonicalUser": "79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be" }

您还可以指定多个 AWS 账户(或规范用户 ID)作为使用数组的主体。例如,您可以使用所有三种方法在存储桶策略中指定主体。

"Principal": { "AWS": [ "arn:aws:iam::123456789012:root", "999999999999" ], "CanonicalUser": "79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be" }

IAM 角色主体

您可以在支持主体的基于资源的策略或条件密钥的 Principal 元素中指定 IAM 角色主体 ARN。IAM 角色是身份。在 IAM 中,身份是您可以向其分配权限的资源。角色信任另一个身份验证来担任该角色。这包含 AWS 中的主体或来自外部身份提供程序 (IdP) 的用户。当主体或身份代入角色时,他们会收到具有代入角色权限的临时安全证书。当他们使用这些凭证在 AWS 中执行操作时,将变为角色会话主体

IAM 角色是 IAM 中存在的身份。角色信任另一个经过身份验证的身份,如 AWS 中的主体或来自外部身份提供程序的用户。当主体或身份代入角色时,他们会收到临时安全凭证。然后,他们可以使用这些凭证作为角色会话主体在 AWS 中执行操作。

当您在基于资源的策略中指定角色主体时,主体的有效权限受限制该角色权限的任何策略类型的限制。这包括会话策略和权限边界。有关如何评估角色会话的有效权限的更多信息,请参阅 策略评估逻辑

要指定 Principal 元素中的角色 ARN,请采用以下格式:

"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" }
重要

如果角色信任策略的 Principal 元素中包含指向特定 IAM 角色的 ARN,在保存策略时该 ARN 将转换为该角色的唯一主体 ID。如果有人希望通过删除并重新创建角色来提升特权,这样有助于减轻此类风险。您通常不会在控制台中看到这个 ID,因为 IAM 在显示信任策略时使用反向转换回角色 ARN。但是,如果您删除角色,这种关系即被打破。即使您重新创建角色,策略也不再适用。因为新角色拥有新的主体 ID,与信任策略中存储的 ID 不匹配。发生这种情况时,主体 ID 会出现在基于资源的策略中,因为 AWS 无法将其映射回有效的 ARN。最终结果是,如果您删除并重新创建了信任策略的 Principal 元素所引用的角色,您必须编辑策略中的角色,用正确的 ARN 替换主体 ID。当您保存策略时,ARN 会再次转换为该角色新的主体 ID。

IAM 联合身份用户 — IAM 用户使用 aws:PrincipalArn 操作联合身份,为 IAM 用户生成联合身份用户会话主体。当您使用此密钥时,角色会话主体将根据所担任的角色的 ARN 而不是所生成的会话的 ARN 授予权限。由于 AWS 不将条件密钥 ARN 转换为 ID,如果您删除该角色,然后创建一个具有相同名称的新角色,则授予该角色 ARN 的权限将继续存在。基于身份的策略类型,例如权限边界或会话策略,不限制在 Principal 元素中使用带通配符(*)的 aws:PrincipalArn 条件键授予权限,除非基于身份的策略包含显式拒绝。

角色会话主体

您可以在支持主体的基于资源的策略或条件密钥的 Principal 元素中指定角色会话。当主体或身份代入角色时,他们会收到具有代入角色权限的临时安全证书。当他们使用这些凭证,在 AWS 中执行操作时,将变为角色会话主体

您用于角色会话主体的格式取决于用来代入角色的 AWS STS 操作。

此外,管理员可以设计一个流程来控制角色会话的发放方式。例如,他们可以为用户提供一键式解决方案,以创建可预测的会话名称。如果管理员执行此操作,则您可以在策略或条件密钥中使用角色会话主体。否则,您可以在 aws:PrincipalArn 条件键中将角色 ARN 指定为主体。如何将角色指定为主体可以更改所生成的会话的有效权限。有关更多信息,请参阅 IAM 角色主体

代入角色会话主体

代入的角色会话主体是使用 AWS STS AssumeRole 操作所产生的会话主体。有关哪些主体可以使用此操作代入角色的更多信息,请参阅 比较 AWS STS API 操作

要指定 Principal 元素中代入角色会话的 ARN,请采用以下格式:

"Principal": { "AWS": "arn:aws:sts::AWS-account-ID:assumed-role/role-name/role-session-name" }

当您在 Principal 元素中指定代入角色会话时,不能使用通配符 "*" 表示所有会话。主体必须始终指明特定会话。

OIDC 会话主体

OIDC 会话主体是使用 AWS STS AssumeRoleWithWebIdentity 操作产生的会话主体。您可以使用外部 OIDC 身份提供者(IdP)登录,然后使用此操作代入 IAM 角色。这利用了联合身份并发出角色会话。有关哪些主体可以使用此操作代入角色的更多信息,请参阅 比较 AWS STS API 操作

当通过 OIDC 身份提供者发出角色时,您将获得这种特殊类型的会话主体,其中包括 OIDC 身份提供者相关信息。

在策略中使用此主体类型可基于受信任的 Web 身份提供程序来允许或拒绝访问。要在角色信任策略的 Principal 元素中指定 OIDC 角色会话 ARN,请采用以下格式:

"Principal": { "Federated": "cognito-identity.amazonaws.com" }
"Principal": { "Federated": "www.amazon.com" }
"Principal": { "Federated": "graph.facebook.com" }
"Principal": { "Federated": "accounts.google.com" }

SAML 会话主体

SAML 会话主体是使用 AWS STS AssumeRoleWithSAML 操作产生的会话主体。您可以使用外部 SAML 身份提供程序 (IdP) 登录,然后使用此操作代入 IAM 角色。这利用了身份联合身份验证并发出角色会话。有关哪些主体可以使用此操作代入角色的更多信息,请参阅 比较 AWS STS API 操作

从 SAML 身份提供程序发出角色时,您将获得这种特殊类型的会话主体,其中包括有关 SAML 身份提供程序的信息。

在策略中使用此主体类型可基于受信任的 SAML 身份提供程序来允许或拒绝访问。要指定角色信任策略 Principal 元素中 SAML 身份角色会话的 ARN,请采用以下格式:

"Principal": { "Federated": "arn:aws:iam::AWS-account-ID:saml-provider/provider-name" }

IAM 用户主体

您可以在支持主体的基于资源的策略或条件键的 Principal 元素中指定 IAM 用户。

注意

Principal 元素中,Amazon Resource Name (ARN) 的用户名部分区分大小写。

"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/user-name" }
"Principal": { "AWS": [ "arn:aws:iam::AWS-account-ID:user/user-name-1", "arn:aws:iam::AWS-account-ID:user/user-name-2" ] }

当在 Principal 元素中指定用户时,不能使用通配符 (*) 表示“所有用户”。主体必须始终指明特定用户。

重要

如果角色信任策略的 Principal 元素中包含指向特定 IAM 用户的 ARN,则在保存策略时该 IAM 将 ARN 转换为该用户的唯一主体 ID。如果有人希望通过删除并重新创建用户来提升特权,这样有助于减轻此类风险。您通常不会在控制台中看到这个 ID,因为显示信任策略时它还会反向转换为用户的 ARN。但是,如果您删除角色,这种关系即被打破。即使您重新创建用户,策略也不再适用。这是因为:新用户拥有新的主体 ID,该 ID 与信任策略中存储的 ID 不匹配。发生这种情况时,主体 ID 会出现在基于资源的策略中,因为 AWS 无法将其映射回有效的 ARN。结果是,如果您删除并重新创建了信任策略的 Principal 元素所引用的用户,您必须编辑角色,用正确的 ARN 替换目前不正确的主体 ID。当您保存策略时,IAM 会再次将 ARN 转换为该用户新的主体 ID。

IAM Identity Center 主体

在 IAM Identity Center 中,必须将基于资源的策略中的主体定义为 AWS 账户 主体。要指定访问权限,请引用条件块中设置的权限的角色 ARN。有关详细信息,请参阅《IAM Identity Center 用户指南》中的引用资源策略、Amazon EKS 和 AWS KMS 中的权限集

AWS STS 联合身份用户会话主体

您可以在支持主体的基于资源的策略或条件密钥的 Principal 元素中指定 federated user sessions(联合身份用户会话)。

重要

AWS 建议只在必要时使用 AWS STS 联合身份用户会话,如需要使用根用户访问权限时。反过来,使用角色来委托权限

AWS STS 联合身份用户会话主体是使用 AWS STS GetFederationToken 操作产生的会话主体。在这种情况下,AWS STS 将联合身份而非 IAM 角色作为获取临时访问令牌的方法。

在 AWS 中,IAM 用户或 AWS 账户根用户 可以使用长期访问密钥进行身份验证。有关哪些主体可以使用此操作联合身份的更多信息,请参阅 比较 AWS STS API 操作

  • IAM 联合身份用户 — IAM 用户使用 GetFederationToken 操作联合身份,为 IAM 用户生成联合身份用户会话主体。

  • 联合身份根用户— 一个根用户联邦成员使用对该根用户产生联邦用户会话主体的 GetFederationToken 操作。

当 IAM 用户或根用户通过使用此操作的 AWS STS 请求临时凭证时,他们开启临时的联合身份会话。本会话的 ARN 基于联合身份的原始身份。

要指定 Principal 元素中联合身份用户会话的 ARN,请采用以下格式:

"Principal": { "AWS": "arn:aws:sts::AWS-account-ID:federated-user/user-name" }

AWS 服务主体

您可以在支持主体的基于资源的策略或条件密钥的 Principal 元素中指定 AWS 服务。一个服务主体是服务的标识符。

可以由 AWS 服务担任的 IAM 角色称为服务角色。服务角色必须包括信任策略。信任策略是附加到角色的基于资源的策略,这些策略定义了可担任该角色的主体。某些服务角色具有预定义的信任策略。但有些情况下,您必须在信任策略中指定服务主体。IAM policy 中的服务主体不能是 "Service": "*"

服务主体的标识符包括服务名称,通常采用以下格式:

service-name.amazonaws.com

服务主体由服务定义。可以通过以下方式找到某些服务的服务主体:打开 使用 IAM 的AWS服务,检查服务在 Service-linked role(服务相关角色)列中是否具有 Yes,然后打开 Yes(是)链接以查看该服务的服务相关角色文档。查找该服务的服务相关角色权限部分,查看服务主体。

以下示例显示了一个可以附加到服务角色的策略。该策略可启用两个服务(Amazon ECS 和 Elastic Load Balancing)以担任该角色。然后,这些服务可执行由分配给该角色 (未显示) 的权限策略授权执行的任何任务。要指定多个服务主体,不用指定两个 Service 元素;您可以只使用一个该元素。实际上,您可以将一组多个服务主体作为单个 Service 元素的值。

"Principal": { "Service": [ "ecs.amazonaws.com", "elasticloadbalancing.amazonaws.com" ] }

选择加入区域的 AWS 服务主体

您可以在多个 AWS 区域以及您必须选择加入的其中一些区域启动资源。有关您必须选择加入的区域的完整列表,请参阅 AWS 一般参考 指南中的管理 AWS 区域

当选择加入区域中的 AWS 服务在同一区域内提出请求时,服务主体名称格式被标识为其服务主体名称的非区域化版本:

service-name.amazonaws.com

当选择加入区域中的 AWS 服务向另一个区域内提出跨区域请求时,服务主体名称格式被标识为其服务主体名称的区域化版本:

service-name.{region}.amazonaws.com

例如,您有一个 Amazon SNS 主题位于区域 ap-southeast-1,一个 Amazon S3 桶位于选择加入区域 ap-east-1。您想要配置 S3 桶通知以向 SNS 主题发布消息。要允许 S3 服务向 SNS 主题发布消息,您必须通过该主题的基于资源的访问策略授予 S3 服务主体 sns:Publish 权限。

如果您在主题访问策略中指定了 S3 服务主体的非区域化版本 s3.amazonaws.com,则从桶向主题发出的 sns:Publish 请求将失败。以下示例在 SNS 主题访问策略的 Principal 策略元素中指定了非区域化 S3 服务主体。

"Principal": { "Service": "s3.amazonaws.com" }

由于桶位于选择加入区域,并且请求是在同一区域之外发出的,因此 S3 服务主体显示为区域化服务主体名称 s3.ap-east-1.amazonaws.com。当选择加入区域中的 AWS 服务向另一个区域发出请求时,您必须使用区域化服务主体名称。指定区域化服务主体名称后,如果桶向位于另一个区域的 SNS 主题发出 sns:Publish 请求,则请求将成功。以下示例在 SNS 主题访问策略的 Principal 策略元素中指定了区域化 S3 服务主体。

"Principal": { "Service": "s3.ap-east-1.amazonaws.com" }

只有指定了区域化服务主体名称,资源策略或基于服务主体的允许列表才能成功处理从一个选择加入区域到另一个区域的跨区域请求。

注意

对于 IAM 角色信任策略,我们建议使用非区域化服务主体名称。IAM 资源是全局性的,因此可以在任何区域使用相同的角色。

所有主体

您可以在基于资源的策略的 Principal 元素或在支持主体的条件键中使用通配符(*)指定所有主体。使用 基于资源的策略 授予权限和条件键来限制策略语句的条件。

重要

我们强烈建议不要在带有 Allow 效果的基于资源的策略的 Principal 元素中使用通配符(*),除非您打算授予公共或匿名访问权限。否则,请在 Principal 元素中指定预期的主体、服务或 AWS 账户,然后进一步将访问权限限制在 Condition 元素内。对于 IAM 角色信任策略尤其如此,因为它们允许其他主体成为您账户中的主体。

对于基于资源的策略,使用带 Allow 效果的通配符(*)向所有用户(包括匿名用户)授予访问权限(公共访问权限)。对于账户中的 IAM 用户和角色主体,不需要其他权限。对于其他账户中的主体,他们还必须在其账户中拥有基于身份的权限,以允许他们访问您的资源。这称为 cross-account access(跨账户存取)。

对于匿名用户,以下元素是等效的:

"Principal": "*"
"Principal" : { "AWS" : "*" }

您不能使用通配符匹配一部分主体名称或 ARN。

以下示例说明了基于资源的策略(而非 使用将 NotPrincipal 与 Deny 一起使用)可用于显式拒绝 Condition 元素中指定的主体之外的所有主体。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "UsePrincipalArnInsteadOfNotPrincipalWithDeny", "Effect": "Deny", "Action": "s3:*", "Principal": "*", "Resource": [ "arn:aws:s3:::BUCKETNAME/*", "arn:aws:s3:::BUCKETNAME" ], "Condition": { "ArnNotEquals": { "aws:PrincipalArn": "arn:aws:iam::444455556666:user/user-name" } } } ] }

更多信息

有关更多信息,请参阅下列内容: