

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# ABAC for AWS KMS
<a name="abac"></a>

基于属性的访问控制 (ABAC) 是一种基于属性定义权限的授权策略。 AWS KMS 支持 ABAC，允许您根据与 KMS 密钥关联的标签和别名来控制对客户托管密钥的访问。启用 ABAC 的标签和别名条件密钥 AWS KMS 提供了一种强大而灵活的方式来授权委托人使用 KMS 密钥，而无需编辑策略或管理授权。但是，您应该小心使用这些功能，以免委托人无意中允许或拒绝访问。

如果您使用 ABAC，请注意管理标签和别名的权限现在是访问控制权限。在部署依赖于标签或别名的策略之前，请确保您知道所有 KMS 密钥上的现有标签和别名。添加、删除和更新别名，以及标记和取消标记密钥时，采取合理的预防措施。仅授予需要管理标签和别名权限的委托人该权限，并限制他们可以管理的标签和别名。

**注意**  
使用 ABAC 时 AWS KMS，请谨慎行事，不要授予委托人管理标签和别名的权限。更改标签或别名可以允许或拒绝对 KMS 密钥的权限。不具有更改密钥策略或创建授权权限的密钥管理员可以控制对 KMS 密钥的访问，前提是他们有权管理标签或别名。  
标签和别名的更改最多可能需要 5 分钟的时间才能影响 KMS 密钥授权。最近的更改可能会在 API 操作中显示，然后才会影响授权。  
要根据 KMS 密钥别名控制对它的访问权限，必须使用条件键。您不能使用别名来表示策略语句的 `Resource` 元素中的 KMS 密钥元素。当别名出现在 `Resource` 元素时，策略语句将应用于别名，而不是关联的 KMS 密钥。

**了解详情**
+ 有关 AWS KMS 支持 ABAC 的详细信息（包括示例），请参阅[使用别名控制对 KMS 密钥的访问](alias-authorization.md)和。[使用标签控制对 KMS 密钥的访问](tag-authorization.md)
+ 有关使用标签控制 AWS 资源访问的更多一般信息，请参阅 [ABAC 有什么用 AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html)？ 以及[使用 *IAM 用户指南*中的资源标签控制对资源的访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html)权限。 AWS 

## ABAC 条件键适用于 AWS KMS
<a name="about-abac-kms"></a>

要根据 KMS 密钥的标签和别名授权访问 KMS 密钥，请在密钥政策或 IAM policy 中使用以下条件键。


| ABAC 条件键 | 说明 | 策略类型 | AWS KMS 操作 | 
| --- | --- | --- | --- | 
| [aws：ResourceTag](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag) | KMS 密钥上的标签（键和值）与策略中的标签（键和值）或标签模式匹配 | 仅限 IAM policy | KMS 密钥资源操作 2 | 
| [aws:RequestTag/*tag*-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag) | 请求中的标签（键和值）与策略中的标签（键和值）或标签模式匹配 | 密钥政策和 IAM policy 1 | [TagResource](https://docs.aws.amazon.com/kms/latest/APIReference/API_TagResource.html), [UntagResource](https://docs.aws.amazon.com/kms/latest/APIReference/API_UntagResource.html) | 
| [aws：TagKeys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys) | 请求中的标签键与策略中的标签键匹配 | 密钥政策和 IAM policy 1 | [TagResource](https://docs.aws.amazon.com/kms/latest/APIReference/API_TagResource.html), [UntagResource](https://docs.aws.amazon.com/kms/latest/APIReference/API_UntagResource.html) | 
| [kms: ResourceAliases](conditions-kms.md#conditions-kms-resource-aliases) | 与 KMS 密钥关联的别名与策略中的别名或别名模式匹配 | 仅限 IAM policy | KMS 密钥资源操作 2 | 
| [kms: RequestAlias](conditions-kms.md#conditions-kms-request-alias) | 表示请求中的 KMS 密钥的别名与策略中的别名或别名模式匹配。 | 密钥政策和 IAM policy 1 | [加密操作](kms-cryptography.md#cryptographic-operations)，，[DescribeKey[GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html)](https://docs.aws.amazon.com/kms/latest/APIReference/API_DescribeKey.html) | 

1 任何可在密钥政策中使用的条件键也可以在 IAM policy 中使用，但只有在[密钥政策允许它](key-policy-default.md#key-policy-default-allow-root-enable-iam)时。

2 *KMS 密钥资源操作*是特定 KMS 密钥授权的操作。若要标识 KMS 密钥资源操作，请在 [AWS KMS 权限表](kms-api-permissions-reference.md#kms-api-permissions-reference-table)中，在操作的 `Resources` 列中查找的 KMS 密钥的值。

例如，您可以使用这些条件键创建以下策略。
+ 具有 `kms:ResourceAliases` 的 IAM policy，可授予将 KMS 密钥与特定别名或别名模式结合使用的权限。这与依赖标签的策略略有不同：尽管您可以在策略中使用别名模式，但每个别名在 AWS 账户 和区域中都必须是唯一的。这允许您对一组选定的 KMS 密钥应用策略，而无需在策略声明中列出 KMS 密钥 ARNs 的密钥。要从集中添加或删除 KMS 密钥，请更改 KMS 密钥的别名。
+ 带有 `kms:RequestAlias` 的密钥策略，可允许委托人在 `Encrypt` 操作中使用 KMS 密钥，但前提是仅当 `Encrypt` 请求使用该别名标识 KMS 密钥时。
+ 带有 `aws:ResourceTag/tag-key` 的 IAM policy，可拒绝将 KMS 密钥与特定标签键和标签值结合使用的权限。这使您可以将策略应用于一组选定的 KMS 密钥，而无需在策略声明中列出 KMS 密钥的密钥。 ARNs 要在集中添加或删除 KMS 密钥，请标记或取消标记 KMS 密钥。
+ 带有 `aws:RequestTag/tag-key` 的 IAM policy，可允许委托人仅删除 `"Purpose"="Test"` KMS 密钥标签。
+ 带有 `aws:TagKeys` 的 IAM policy，可拒绝使用 `Restricted` 标签键标记或取消标记 KMS 密钥的权限。

ABAC 使访问管理具有灵活性和可扩展性。例如，您可以使用 `aws:ResourceTag/tag-key` 条件键创建 IAM policy，该策略允许委托人仅在 KMS 密钥具有 `Purpose=Test` 标签时将 KMS 密钥用于特定操作。该策略适用于 AWS 账户的所有区域中的所有 KMS 密钥。

当附加到用户或角色时，以下 IAM policy 允许委托人将带有 `Purpose=Test` 标签的所有现有 KMS 密钥用于指定操作。要提供对新的或现有 KMS 密钥的访问权限，您不需要更改策略。只需将 `Purpose=Test` 标签附加到 KMS 密钥。同样，要从具有 `Purpose=Test` 标签的 KMS 密钥中删除此访问权限，请编辑或删除标签。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AliasBasedIAMPolicy",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
      ],
      "Resource": "arn:aws:kms:*:111122223333:key/*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Purpose": "Test"
        }
      }
    }
  ]
}
```

------

但是，如果您使用此功能，在管理标记和别名时要加小心。添加、更改或删除标签或别名可能会无意中允许或拒绝对 KMS 密钥的访问。不具有更改密钥策略或创建授权权限的密钥管理员可以控制对 KMS 密钥的访问，前提是他们有权管理标签和别名。为了减轻这种风险，请考虑[限制管理标签的权限](tag-permissions.md#tag-permissions-conditions)和[别名](alias-access.md#alias-access-limiting)。例如，您可能想要仅允许特色级委托人管理 `Purpose=Test` 标签。有关详细信息，请参阅 [使用别名控制对 KMS 密钥的访问](alias-authorization.md) 和 [使用标签控制对 KMS 密钥的访问](tag-authorization.md)。

## 标签还是别名？
<a name="abac-tag-or-alias"></a>

AWS KMS 支持带有标签和别名的 ABAC。这两种选项都提供了灵活、可扩展的访问控制策略，但它们彼此略有不同。

您可以根据自己的特定使用模式决定使用标签或 AWS 使用别名。例如，如果您已经向大多数管理员授予了标记权限，则基于别名控制授权策略可能会更容易。或者，如果您接近[每个 KMS 密钥的别名数量](resource-limits.md#aliases-per-key)配额，您可能更喜欢基于标签的授权策略。

以下益处是大家都感兴趣的。

**基于标签的访问控制的益处**
+ 对不同类型的 AWS 资源使用相同的授权机制。

  您可以使用相同的标签或标签键来控制对多种资源类型的访问，例如 Amazon Relational Database Service（Amazon RDS）集群、Amazon Elastic Block Store（Amazon EBS）卷和 KMS 密钥。此功能支持多种不同的授权模型，这些模型比传统的基于角色的访问控制更加灵活。
+ 授权访问一组 KMS 密钥。

  您可以使用标签来管理对同一 AWS 账户 和区域中的一组 KMS 密钥的访问权限。将相同的标签或标签键分配给您选择的 KMS 密钥。然后创建一个基于标签或标签密钥的简单 easy-to-maintain策略声明。要在授权组中添加或删除 KMS 密钥，请添加或删除标签；您无需编辑策略。

**基于别名的访问控制的益处**
+ 根据别名授权对加密操作的访问。

  大多数基于请求的属性策略条件，包括 a [ws:RequestTag/*tag-key*](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag)，仅影响添加、编辑或删除属性的操作。但是 k [ms: RequestAlias](conditions-kms.md#conditions-kms-request-alias) 条件密钥根据用于在请求中识别 KMS 密钥的别名来控制对加密操作的访问。例如，您可以授予委托人在 `Encrypt` 操作中使用 KMS 密钥的权限，但只有当 `KeyId` 参数的值为 `alias/restricted-key-1` 时。要满足此条件，需要以下所有条件：
  + KMS 密钥必须与该别名相关联。
  + 请求必须使用别名来标识 KMS 密钥。
  + 委托人必须拥有使用受 `kms:RequestAlias` 条件约束的 KMS 密钥的权限。

  如果您的应用程序通常使用别名或别名来引用 KMS 密钥 ARNs ，则此功能特别有用。
+ 提供非常有限的权限。

  在 AWS 账户 和区域中，别名必须是唯一的。因此，基于别名授予委托人访问 KMS 密钥的权限可能比基于标签授予他们访问权限更严格。与别名不同，标签可分配给同一账户和区域中的多个 KMS 密钥。如果选择，则可以使用别名模式（例如 `alias/test*`）为委托人授予对同一账户和区域中一组 KMS 密钥的访问权限。但是，允许或拒绝访问特定别名允许对 KMS 密钥进行非常严格的控制。

# 对 ABAC 进行故障排除 AWS KMS
<a name="troubleshooting-tags-aliases"></a>

基于 KMS 密钥的标签和别名控制对 KMS 密钥的访问非常方便，且功能强大。但是，它容易出现一些您希望防止的可预测错误。

## 由于标签更改而更改访问权限
<a name="access-denied-tag"></a>

如果某个标签被删除或其值被更改，则仅能基于该标签访问 KMS 密钥的委托人将被拒绝访问 KMS 密钥。当拒绝策略语句中包含的标签添加到 KMS 密钥时，也会发生这种情况。向 KMS 密钥添加与策略相关的标签可以允许访问应被拒绝访问 KMS 密钥的委托人。

例如，假设委托人可以基于 `Project=Alpha` 标签访问 KMS 密钥，例如以下示例 IAM policy 语句提供的权限。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "IAMPolicyWithResourceTag",
      "Effect": "Allow",
      "Action": [
        "kms:GenerateDataKeyWithoutPlaintext",
        "kms:Decrypt"
      ],
      "Resource": "arn:aws:kms:ap-southeast-1:111122223333:key/*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Project": "Alpha"
        }
      }
    }
  ]
}
```

------

如果该标签已从该 KMS 密钥中删除或标签值发生更改，则委托人不再具有将 KMS 密钥用于指定操作的权限。当委托人尝试在使用客户托管密钥的 AWS 服务中读取或写入数据时，这一点可能会变得显而易见。要跟踪标签的更改，请查看您的 CloudTrail日志[TagResource](ct-tagresource.md)或[UntagResource 条目](ct-untagresource.md)。

要在不更新策略的情况下恢复访问，请更改 KMS 密钥上的标签。这一措施除了短时间在整个 AWS KMS中生效之后，产生的影响极小。为了防止这样的错误，请仅向需要它的委托人授予标记和取消标记权限，并[将其标记权限限制](tag-permissions.md#tag-permissions-conditions)到他们需要管理的标签。更改标签之前，请搜索策略以检测依赖于标签的访问权限，并在具有该标签的所有区域中获取 KMS 密钥。您可以考虑在更改特定标签时创建 Amazon CloudWatch 警报。

## 由于别名更改而导致的访问权限更改
<a name="access-denied-alias"></a>

如果别名被删除或与其他 KMS 密钥关联，则仅能基于该别名访问 KMS 密钥的委托人将被拒绝访问 KMS 密钥。当拒绝策略语句中包含与 KMS 密钥关联的别名时，也会发生这种情况。向 KMS 密钥添加与策略相关的别名也可以允许访问应被拒绝访问 KMS 密钥的委托人。

例如，以下 IAM 策略声明使用 k [ms: ResourceAliases](conditions-kms.md#conditions-kms-resource-aliases) 条件密钥允许使用任意指定别名访问账户中不同区域的 KMS 密钥。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AliasBasedIAMPolicy",
      "Effect": "Allow",
      "Action": [
        "kms:List*",
        "kms:Describe*",
        "kms:Decrypt"
      ],
      "Resource": "arn:aws:kms:*:111122223333:key/*",
      "Condition": {
        "ForAnyValue:StringEquals": {
          "kms:ResourceAliases": [
            "alias/ProjectAlpha",
            "alias/ProjectAlpha_Test",
            "alias/ProjectAlpha_Dev"
          ]
        }
      }
    }
  ]
}
```

------

要跟踪别名更改，请查看 CloudTrail 日志中是否有[CreateAlias[UpdateAlias](ct-updatealias.md)](ct-createalias.md)、和[DeleteAlias](ct-deletealias.md)条目。

要在不更新策略的情况下恢复访问，请更改与 KMS 密钥关联的别名。由于每个别名只能与账户和区域中的一个 KMS 密钥相关联，因此管理别名比管理标签要困难一些。恢复一些委托人对一个 KMS 密钥的访问权限可能会拒绝相同或其他委托人对其他 KMS 密钥的访问。

为了防止出现此错误，请仅向需要它的委托人授予别名管理权限，并[将其别名管理权限限制](alias-access.md#alias-access-limiting)到他们需要管理的别名。在更新或删除别名之前，请搜索策略以检测依赖于别名的访问权限，并在与别名关联的所有区域中查找 KMS 密钥。

## 由于别名配额而拒绝访问
<a name="access-denied-alias-quota"></a>

如果 KMS 密钥超过该账户和地区[每个 [KMS 密钥配额的默认别名，则获得 kms: ResourceAliases](conditions-kms.md#conditions-kms-resource-aliases) 条件授权使用 KMS 密钥](resource-limits.md#aliases-per-key)的用户将获得`AccessDenied`例外。

要恢复访问，请删除与 KMS 密钥关联的别名，使其符合配额。或者使用备用机制授予用户访问 KMS 密钥的权限。

## 延迟的授权更改
<a name="tag-alias-auth-delay"></a>

您对标签和别名的更改最多可能需要 5 分钟的时间才能影响 KMS 密钥授权。因此，标签或别名更改可能会在 API 操作影响授权之前反映在响应中。这种延迟可能比影响大多数 AWS KMS 操作的短暂的最终一致性延迟要长。

例如，您可能拥有一个 IAM policy，允许某些委托人使用带有 `"Purpose"="Test"` 标签的任何 KMS 密钥。然后，您将 `"Purpose"="Test"` 标签添加到 KMS 密钥。尽管[TagResource](https://docs.aws.amazon.com/kms/latest/APIReference/API_TagResource.html)操作已完成且[ListResourceTags](https://docs.aws.amazon.com/kms/latest/APIReference/API_ListResourceTags.html)响应确认标签已分配给 KMS 密钥，但委托人可能在长达五分钟内无法访问 KMS 密钥。

为了防止出现错误，请将此预期延迟构建到您的代码中。

## 由于别名更新而失败的请求
<a name="failed-requests"></a>

当您更新别名时，您将现有别名与另一个 KMS 密钥关联。

[解密](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)和指定别名或[别名](concepts.md#key-id-alias-name) [ARN](concepts.md#key-id-alias-ARN) 的[ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html)请求可能会失败，因为该别名现在与未加密密文的 KMS 密钥相关联。这种情况通常会返回 `IncorrectKeyException` 或者 `NotFoundException`。或者如果请求中没有 `KeyId` 或 `DestinationKeyId` 参数，则操作可能会失败，并出现 `AccessDenied` 异常，因为调用方不再具有对加密密文的 KMS 密钥的访问权限。

您可以通过查看[CreateAlias[UpdateAlias](ct-updatealias.md)](ct-createalias.md)、和 CloudTrail 日志条目的[DeleteAlias](ct-deletealias.md)日志来跟踪更改。您还可以在[ListAliases](https://docs.aws.amazon.com/kms/latest/APIReference/API_ListAliases.html)响应中使用该`LastUpdatedDate`字段的值来检测更改。

例如，以下[ListAliases](https://docs.aws.amazon.com/kms/latest/APIReference/API_ListAliases.html)示例响应显示`kms:ResourceAliases`条件中的`ProjectAlpha_Test`别名已更新。因此，基于别名具有访问权限的委托人将失去对先前关联的 KMS 密钥的访问权限。相反，他们可以访问新关联的 KMS 密钥。

```
$ aws kms list-aliases --query 'Aliases[?starts_with(AliasName, `alias/ProjectAlpha`)]'

{
    "Aliases": [
        {
            "AliasName": "alias/ProjectAlpha_Test",
            "AliasArn": "arn:aws:kms:us-west-2:111122223333:alias/ProjectAlpha_Test",
            "TargetKeyId": "0987dcba-09fe-87dc-65ba-ab0987654321",
            "CreationDate": 1566518783.394,
            "LastUpdatedDate": 1605308931.903
        },
        {
            "AliasName": "alias/ProjectAlpha_Restricted",
            "AliasArn": "arn:aws:kms:us-west-2:111122223333:alias/ProjectAlpha_Restricted",
            "TargetKeyId": "1234abcd-12ab-34cd-56ef-1234567890ab",
            "CreationDate": 1553410800.010,
            "LastUpdatedDate": 1553410800.010
        }
    ]
}
```

这种变化的补救办法并不简单。您可以再次更新别名以将其与原始 KMS 密钥关联。但是，在执行操作之前，您需要考虑该更改对当前关联的 KMS 密钥的影响。如果委托人在加密操作中使用后一个 KMS 密钥，他们可能需要继续访问该密钥。在这种情况下，您可能需要更新策略以确保委托人有权使用这两个 KMS 密钥。

您可以防止出现这样的错误：在更新别名之前，搜索策略以检测依赖于别名的访问。然后，在与别名关联的所有区域中获取 KMS 密钥。请仅向需要它的委托人授予别名管理权限，并[将其别名管理权限限制](alias-access.md#alias-access-limiting)到他们需要管理的别名。