

# OpenTelemetry 指标的静态加密
<a name="cmk-encryption"></a>

## 什么是 CloudWatch 数据集
<a name="cmk-encryption-dataset-overview"></a>

您发送到 Amazon CloudWatch 的 OpenTelemetry（oTel）指标存储在名为“数据集”的资源中。在所有 OTel 指标所在的每个区域中，每个 Amazon Web Services 账户都有一个 `default` 数据集。该 `default` 数据集是唯一支持的数据集，您无法创建其他数据集。

可以像其他 Amazon 资源一样对数据集进行加密和标记。数据集 ARN 有以下格式：

`arn:{{{partition}}}:cloudwatch:{{{region}}}:{{{account-id}}}:dataset/default`

要查看数据集的当前加密配置，请使用 `GetDataset` API：

```
aws cloudwatch get-dataset \
    --dataset-identifier default
```

如果客户自主管理型密钥与数据集相关联，则响应将包含密钥 ARN。如果未关联任何客户自主管理型密钥，则使用 Amazon 拥有的密钥对数据集进行加密。

## 静态加密选项
<a name="cmk-encryption-options"></a>

CloudWatch 始终加密数据集静态数据。默认情况下，CloudWatch 使用 Amazon 拥有的密钥加密静态数据。无需执行任何操作，即可使用 Amazon 拥有的密钥来保护数据。有关更多信息，请参阅《Amazon Key Management Service Developer Guide》中的 [Amazon owned keys](https://docs.amazonaws.cn/kms/latest/developerguide/concepts.html#aws-owned-cmk)。

如果要管理用于加密数据集数据的密钥，则可以在 Amazon Key Management Service（Amazon KMS）中使用客户自主管理型密钥。有关更多信息，请参阅 Amazon Key Management Service 开发人员指南中的[ 客户托管密钥](https://docs.amazonaws.cn/kms/latest/developerguide/concepts.html#customer-cmk)。

若使用客户自主管理型密钥，则会收取 Amazon KMS 费用。有关定价的更多信息，请参阅 [Amazon Key Management Service 定价](https://www.amazonaws.cn/kms/pricing/)。

## CloudWatch 如何使用客户自主管理型密钥进行数据集加密
<a name="cmk-encryption-how-it-works"></a>

**重要**  
客户自主管理型密钥加密适用于 `default` 数据集。该 `default` 数据集是唯一支持的数据集，您无法创建其他数据集。

将客户自主管理型密钥与 `default` 数据集关联时，CloudWatch 会使用该密钥加密存储在该数据集中的所有 OTel 指标数据。

CloudWatch 会直接使用具有密钥策略权限的服务主体 (`cloudwatch.amazonaws.com`)。CloudWatch 不会使用授权或 IAM 角色来访问您的 Amazon KMS 密钥。

CloudWatch 不会缓存数据密钥。但是，CloudWatch 会缓存 `kms:Decrypt` 响应长达 15 分钟。对密钥策略的更改可能最多需要 15 分钟才能生效。

CloudWatch 在所有 Amazon KMS 加密操作中使用以下加密上下文：
+ 键：`aws:cloudwatch:arn`
+ 值：`arn:{{{partition}}}:cloudwatch:{{{region}}}:{{{account-id}}}:dataset/default`

## 配置数据集的客户自主管理型密钥
<a name="cmk-encryption-key-requirements"></a>

用于 CloudWatch 数据集的 Amazon KMS 密钥必须满足以下要求：
+ 该密钥必须为对称加密密钥 (SYMMETRIC\_DEFAULT)，且密钥使用情况为 ENCRYPT\_DECRYPT。不支持非对称密钥。
+ 不支持多区域密钥。
+ 密钥必须与数据集处于相同的 Amazon Web Services 区域。
+ 必须将密钥指定为完全限定的密钥 ARN。不支持密钥别名和密钥 ID。

## 配置密钥策略权限
<a name="cmk-encryption-permissions"></a>

要在 CloudWatch 数据集中使用客户自主管理型密钥，密钥策略必须向 CloudWatch 授予使用该密钥的权限。以下示例密钥策略会授予 CloudWatch 必要的权限，并包含混淆代理保护。

关联或使用数据集的调用方必须拥有 `kms:Decrypt` 权限，范围限于 CloudWatch `ViaService` 和加密上下文，如以下 `AllowCallerDecrypt` 声明中所示。将 {{YouApplicationRole}} 替换为用于调用 CloudWatch 数据集 API 的 IAM 角色。

**Example 用于 CloudWatch 数据集加密的密钥策略**  

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudWatchDatasetDescribeKey",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudwatch.amazonaws.com"
            },
            "Action": "kms:DescribeKey",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "{{account-id}}"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:cloudwatch:{{region}}:{{account-id}}:dataset/default"
                }
            }
        },
        {
            "Sid": "AllowCloudWatchDatasetEncryption",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudwatch.amazonaws.com"
            },
            "Action": [
                "kms:GenerateDataKey",
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "{{account-id}}",
                    "kms:EncryptionContext:aws:cloudwatch:arn": "arn:aws:cloudwatch:{{region}}:{{account-id}}:dataset/default"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:cloudwatch:{{region}}:{{account-id}}:dataset/default"
                }
            }
        },
        {
            "Sid": "AllowCallerDecrypt",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{{account-id}}:role/{{YourApplicationRole}}"
            },
            "Action": "kms:Decrypt",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "cloudwatch.{{region}}.amazonaws.com",
                    "kms:EncryptionContext:aws:cloudwatch:arn": "arn:aws:cloudwatch:{{region}}:{{account-id}}:dataset/default"
                }
            }
        }
    ]
}
```

将 {{account-id}} 和 {{region}} 替换为您的值。

有关密钥策略的更多信息，请参阅《Amazon Key Management Service 开发人员指南》中的 [Amazon KMS 中的密钥策略](https://docs.amazonaws.cn/kms/latest/developerguide/key-policies.html)。

## 将客户自主管理型密钥与数据集关联
<a name="cmk-encryption-associate"></a>

使用 `AssociateDatasetKmsKey` API 将客户自主管理型密钥与数据集关联。必须将 `default` 指定为数据集标识符。

要使用 Amazon CLI 关联客户自主管理型密钥，请运行以下命令：

```
aws cloudwatch associate-dataset-kms-key \
    --dataset-name default \
    --kms-key-arn arn:aws:kms:{{region}}:{{account-id}}:key/{{key-id}}
```

## 更改或移除加密配置
<a name="cmk-encryption-change-disassociate"></a>

可以更改或移除用于加密数据集数据的客户自主管理型密钥。

### 更改客户自主管理型密钥
<a name="cmk-encryption-change-key"></a>

要更换客户自主管理型密钥，请使用新的密钥 ARN 再次调用 `AssociateDatasetKmsKey`。调用方必须同时拥有当前密钥和新密钥的 `kms:Decrypt` 权限。CloudWatch 开始使用新密钥进行后续的加密操作。

**注意**  
如果当前关联的密钥已被删除、计划删除、正在等待导入、不可用或已被禁用，则 CloudWatch 无需对当前密钥具有 `kms:Decrypt` 权限，轮换会继续进行。如果密钥只是被禁用，考虑重新启用密钥而不是进行轮换，因为重新启用后，CloudWatch 可以继续对使用该密钥加密的现有指标数据进行解密。

### 移除客户自主管理型密钥
<a name="cmk-encryption-disassociate"></a>

要移除客户自主管理型密钥并恢复为 Amazon 拥有的密钥加密，请调用 `DisassociateDatasetKmsKey`。调用方必须拥有当前关联密钥的 `kms:Decrypt` 权限。

```
aws cloudwatch disassociate-dataset-kms-key \
    --dataset-name default
```

**注意**  
如果当前关联的密钥已被删除、计划删除、正在等待导入、不可用或已被禁用，则 CloudWatch 无需对该密钥具有 `kms:Decrypt` 权限，解除关联会继续进行。如果密钥只是被禁用，考虑重新启用密钥而不是解除关联，因为重新启用后，CloudWatch 可以继续对现有的指标数据进行解密。

**重要**  
取消关联客户自主管理型密钥后，会有 3 小时的强制执行时段，在此期间，CloudWatch 仍需要先前已关联密钥的 `kms:Decrypt` 权限。在此时段内，请勿禁用或删除密钥。

## 恢复已删除或无法使用的 KMS 密钥
<a name="cmk-encryption-recovering"></a>

如果与数据集关联的客户自主管理型 KMS 密钥被删除、计划删除或不可用，则您的数据集将进入降级状态：
+ CloudWatch 无法对您发布到数据集的新指标数据进行加密，因此数据摄取失败。
+ CloudWatch 无法对使用不可用密钥加密的现有数据进行解密，因此查询操作失败。

恢复选项取决于密钥状态：
+ **密钥已禁用**：在 Amazon KMS 中重新启用密钥。这是首选的恢复路径，因为在密钥重新激活后，CloudWatch 可以继续对现有的指标数据进行解密。
+ **密钥待删除**：在等待期到期之前，在 Amazon KMS 中取消密钥删除。密钥恢复为启用状态后，CloudWatch 将恢复正常操作。
+ **密钥已被永久删除或无法恢复**：移除过期的关联或轮换到新密钥（见下文）。请注意，使用已删除密钥加密的现有数据将永久无法读取。

如果密钥已被永久删除或无法恢复，您可以解除关联或轮换到新密钥，而无需访问旧密钥：

### 移除过期的密钥关联
<a name="cmk-encryption-recovering-disassociate"></a>

调用 `DisassociateDatasetKmsKey`，以移除与不可用密钥的关联。对于新数据，CloudWatch 将恢复为 Amazon 自有密钥加密。使用已删除密钥加密的现有数据将无法再读取。

```
aws cloudwatch disassociate-dataset-kms-key \
    --dataset-name default
```

### 轮换到新密钥
<a name="cmk-encryption-recovering-rotate"></a>

使用全新且有效的 KMS 密钥 ARN 调用 `AssociateDatasetKmsKey`。CloudWatch 会验证新密钥并将其与数据集进行关联。无需访问先前关联的密钥。使用已删除密钥加密的现有数据将无法再读取，但新数据将使用新密钥进行加密。

```
aws cloudwatch associate-dataset-kms-key \
    --dataset-name default \
    --kms-key-arn arn:aws:kms:{{region}}:{{account-id}}:key/{{new-key-id}}
```

### 不可用密钥的错误响应
<a name="cmk-encryption-recovering-errors"></a>

当调用 `DisassociateDatasetKmsKey` 或 `AssociateDatasetKmsKey`（轮换路径）且当前关联的密钥无法访问时，CloudWatch 无需访问该密钥，操作仍可正常进行。这适用于以下情况：
+ 密钥已被删除（KMS 返回 `NotFoundException`）。
+ 密钥处于 `PendingDeletion`、`PendingImport` 或 `Unavailable` 状态。
+ 密钥已被禁用。

如果在密钥可访问但调用方缺少 `kms:Decrypt` 权限的情况下调用这些操作，操作将失败并返回以下错误之一。每条错误消息均包含用于故障排除的 KMS 请求 ID。

`ResourceNotFoundException`  
指定的 KMS 密钥不存在。消息格式：`KMS key {{key-arn}} does not exist. KMS request id: {{request-id}}.`

`ValidationException`  
指定的 KMS 密钥处于此代码路径上不能容忍的不可用状态。消息格式：`KMS key {{key-arn}} is in an unusable state: {{state-description}}. KMS request id: {{request-id}}.`

`AccessDeniedException`  
指定的 KMS 密钥已被禁用，或调用方缺少权限。消息格式：`KMS key {{key-arn}} is disabled. KMS request id: {{request-id}}.`

有关 KMS 密钥状态的更多信息，请参阅《Amazon Key Management Service 开发人员指南》**中的 [Amazon KMS 密钥的密钥状态](https://docs.amazonaws.cn/kms/latest/developerguide/key-state.html)。

## 缩小密钥策略访问权限的范围
<a name="cmk-encryption-scoping-access"></a>

您可以使用密钥策略中的条件来限制对 Amazon KMS 密钥的访问权限。

加密上下文条件  
使用 `kms:EncryptionContext:aws:cloudwatch:arn` 条件键，将密钥的使用限制在 `default` 数据集中。  

```
"Condition": {
    "StringEquals": {
        "kms:EncryptionContext:aws:cloudwatch:arn": "arn:aws:cloudwatch:{{region}}:{{account-id}}:dataset/default"
    }
}
```

混淆代理保护  
使用 `aws:SourceArn` 和 `aws:SourceAccount` 条件来防止跨账户混淆代理攻击。  

```
"Condition": {
    "StringEquals": {
        "aws:SourceAccount": "{{account-id}}"
    },
    "ArnLike": {
        "aws:SourceArn": "arn:aws:cloudwatch:{{region}}:{{account-id}}:dataset/default"
    }
}
```

kms:ViaService 条件  
使用 `kms:ViaService` 条件键，将密钥的使用限制在来自 CloudWatch 的请求中。  

```
"Condition": {
    "StringEquals": {
        "kms:ViaService": "cloudwatch.{{region}}.amazonaws.com"
    }
}
```

## 监控 CloudWatch 与 Amazon KMS 的互动
<a name="cmk-encryption-monitoring"></a>

您可以使用 Amazon CloudTrail 来跟踪 CloudWatch 代表您向 Amazon KMS 发送的请求。Amazon CloudTrail 日志条目使用服务主体 `cloudwatch.amazonaws.com` 和 `cloudwatch.{{{region}}}.amazonaws.com` 的 `ViaService` 值。

以下 CloudTrail 事件名称显示在 CloudWatch 数据集加密操作的日志条目中：
+ `GenerateDataKey`
+ `Encrypt`
+ `Decrypt`
+ `DescribeKey`
+ `ReEncrypt`

每个日志条目均包含加密上下文，您可以使用该上下文来标识操作所适用的特定数据集。

有关监控 Amazon KMS 密钥使用情况的更多信息，请参阅《Amazon Key Management Service 开发人员指南》中的[监控 Amazon Key Management Service](https://docs.amazonaws.cn/kms/latest/developerguide/monitoring-overview.html)。