

# DynamoDB 全局表安全性
安全性

全局表副本是 DynamoDB 表，因此，您可以使用与控制单区域表的访问权限相同的方法，来控制副本的访问权限，包括使用 Amazon Identity and Access Management（IAM）身份策略和基于资源的策略。本主题介绍如何使用 IAM 权限和 Amazon Key Management Service（Amazon KMS）加密来保护 DynamoDB 多账户全局表。您将了解对于多区域最终一致性（MREC）表，用于实现跨区域、跨账户复制和自动扩缩的基于资源的策略与服务相关角色（SLR），以及创建、更新和删除全局表所需的 IAM 权限。您还将学习用于安全地管理跨区域复制的 Amazon KMS 加密密钥。

其中提供了详细信息，介绍建立跨账户和跨区域表复制所需的基于资源的策略和权限。对于需要实施安全的跨账户数据复制解决方案的客户来说，了解这种安全模型至关重要。

## 复制的服务主体授权


DynamoDB 的多账户全局表使用不同的授权方法，因为复制是跨账户边界执行的。此过程使用 DynamoDB 的复制服务主体完成：`replication.dynamodb.amazonaws.com`。每个参与账户都必须在副本表的资源策略中明确允许该主体，向其授予权限，这些权限可以根据键（例如 `aws:SourceAccount`、`aws:SourceArn` 等）的源上下文条件限制到特定副本，有关更多详细信息，请参阅 [Amazon 全局条件键](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html)。权限是双向的，这意味着所有副本都必须明确地相互授予权限，然后才能在任何特定的副本对之间建立复制关系。

对于跨账户复制，以下服务主体权限至关重要：
+ `dynamodb:ReadDataForReplication` 授予读取数据用于复制用途的能力。通过此权限可以读取一个副本中的更改，并将更改传播到其他副本。
+ `dynamodb:WriteDataForReplication` 允许将复制的数据写入目标表。通过此权限可以在全局表中的所有副本之间同步更改。
+ `dynamodb:ReplicateSettings` 实现了跨副本的表设置同步，从而为所有加入的表提供一致的配置。

每个副本都必须向所有其他副本及其自身授予上述权限，也就是说，源上下文条件必须包括构成全局表的完整副本集。在将每个新副本添加到多账户全局表时，都会对其验证这些权限。这可以确保只有获得授权的 DynamoDB 服务才能执行复制操作，并且只能在所需的表之间执行。

## 多账户全局表的服务相关角色


DynamoDB 多账户全局表跨所有副本复制设置，因此每个副本的设置完全相同，吞吐量一致，并提供无缝的失效转移体验。这些设置的复制通过服务主体上的 `ReplicateSettings` 权限进行控制，不过也可以依靠服务相关角色（SLR）来管理某些跨账户跨区域复制和自动扩缩功能。每个 Amazon 账户只需设置一次这些角色。创建后，同一个角色将用于您的账户中的所有全局表。有关服务相关角色的更多信息，请参见《IAM 用户指南》中的[使用服务相关角色](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_create-service-linked-role.html)。

### 设置管理服务相关角色


当您在账户中创建第一个多账户全局表副本时，Amazon DynamoDB 会自动创建 AWSServiceRoleForDynamoDBGlobalTableSettingsManagement 服务相关角色（SLR）。此角色管理您的跨账户跨区域复制设置。

在将基于资源的策略应用于副本时，请确认您没有拒绝在 `AWSServiceRoleForDynamoDBGlobalTableSettingsManagement` 中定义的向 SLR 主体授予的任何权限，因为这可能会影响到设置管理，并且如果副本或 GSI 的吞吐量不匹配，则可能会损害复制。如果您拒绝所需的 SLR 权限，则与受影响副本之间的复制将停止，副本表的状态将更改为 `REPLICATION_NOT_AUTHORIZED`。对于多账户全局表，如果副本保持在 `REPLICATION_NOT_AUTHORIZED` 状态的时间超过 20 小时，则该副本将不可逆地转换为单区域 DynamoDB 表。SLR 具有以下权限：
+ `application-autoscaling:DeleteScalingPolicy`
+ `application-autoscaling:DescribeScalableTargets`
+ `application-autoscaling:DescribeScalingPolicies`
+ `application-autoscaling:DeregisterScalableTarget`
+ `application-autoscaling:PutScalingPolicy`
+ `application-autoscaling:RegisterScalableTarget`

### 自动扩缩服务相关角色


在将全局表配置为调配容量模式时，必须为全局表配置自动扩缩。DynamoDB 自动扩缩功能使用 Amazon Application Auto Scaling 服务来动态调整全局表副本上的预调配吞吐能力。Application Auto Scaling 服务创建名为 [AWSServiceRoleForApplicationAutoScaling\$1DynamoDBTable](https://docs.amazonaws.cn/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html) 的服务相关角色（SLR）。当您首次为 DynamoDB 表配置自动扩缩时，将在您的 Amazon 账户中自动创建此服务相关角色。此角色允许 Application Auto Scaling 管理预调配的表容量并创建 CloudWatch 警报。

在将基于资源的策略应用于副本时，请确保不要拒绝在 [AWSApplicationAutoscalingDynamoDBTablePolicy](https://docs.amazonaws.cn/aws-managed-policy/latest/reference/AWSApplicationAutoscalingDynamoDBTablePolicy.html) 中定义的向 Application Auto Scaling SLR 主体授予的任何权限，因为这将中断自动扩缩功能。

## 全局表如何使用 Amazon IAM


以下各节介绍不同全局表操作所需的权限，并提供了策略示例，以帮助您为用户和应用程序配置适当的访问权限。

**注意**  
描述的所有权限都必须应用于受影响区域中的特定表资源 ARN。表资源 ARN 采用格式 `arn:aws:dynamodb:region:account-id:table/table-name`，您需要指定实际区域、账户 ID 和表名值。

以下是我们在接下来的各节中分步骤介绍的主题：
+ 创建多账户全局表和添加副本
+ 更新多账户全局表
+ 删除全局表和移除副本

### 创建全局表和添加副本


#### 创建全局表的权限


将新副本添加到区域表来构成多账户全局表或者添加到现有的多账户全局表时，执行操作的 IAM 主体必须获得所有现有成员的授权。要想成功添加副本，所有现有成员都需要在其表策略中授予以下权限：
+ `dynamodb:AssociateTableReplica`：此权限允许将表加入到全局表设置中。这是基础权限，用于建立初始复制关系。

这种精确的控制只允许授权账户加入全局表设置。

#### 用于创建全局表的 IAM 策略示例


##### 适用于双副本设置的 IAM 策略示例


多账户全局表的设置遵循用于提供安全复制的特定授权流程。接下来我们将了解它在实践中是如何运作的，在这个场景中，客户想要建立一个包含两个副本的全局表。第一个副本（ReplicaA）位于 ap-east-1 区域的账户 A 中，而第二个副本（ReplicaB）位于 eu-south-1 区域的账户 B 中。
+ 在源账户（账户 A）中，流程首先创建主副本表。账户管理员必须将基于资源的策略附加到此表，向目标账户（账户 B）明确授予执行关联所需的权限。此策略还授权 DynamoDB 复制服务执行基本的复制操作。
+ 目标账户（账户 B）遵循类似的流程，即在创建副本时附加相应的基于资源的策略，并引用用于创建副本的源表 ARN。此策略体现了账户 A 授予的权限，用于创建可信的双向关系。在建立复制之前，DynamoDB 会验证这些跨账户权限，以确保正确进行了授权。

要建立此设置，请执行以下操作：
+ 账户 A 的管理员必须首先将基于资源的策略附加到 ReplicaA。此策略向账户 B 和 DynamoDB 复制服务明确授予必要的权限。
+ 同样，在用于创建副本 B（引用副本 A 作为源表）的创建表调用中，账户 B 的管理员必须将匹配的策略附加到 ReplicaB，进行反向的账户引用以向账户 A 授予相应的权限。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "DynamoDBActionsNeededForSteadyStateReplication",
            "Effect": "Allow",
            "Action": [
                "dynamodb:ReadDataForReplication",
                "dynamodb:WriteDataForReplication",
                "dynamodb:ReplicateSettings"
            ],
            "Resource": "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
            "Principal": {"Service": ["replication.dynamodb.amazonaws.com"]},
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": [ "111122223333", "444455556666" ],
                    "aws:SourceArn": [
                        "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
                        "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB"
                    ]
                }
            }
        },
        {
            "Sid": "AllowTrustedAccountsToJoinThisGlobalTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:AssociateTableReplica"
            ],
            "Resource": "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
            "Principal": {"AWS": ["444455556666"]}
        }
    ]
}
```

------

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "DynamoDBActionsNeededForSteadyStateReplication",
            "Effect": "Allow",
            "Action": [
                "dynamodb:ReadDataForReplication",
                "dynamodb:WriteDataForReplication",
                "dynamodb:ReplicateSettings"
            ],
            "Resource": "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB",
            "Principal": {"Service": ["replication.dynamodb.amazonaws.com"]},
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": [ "111122223333", "444455556666" ],
                    "aws:SourceArn": [
                        "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
                        "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB"
                    ]
                }
            }
        }
    ]
}
```

------

##### 适用于三副本设置的 IAM 策略示例


在此环境中，账户 A、账户 B 和账户 C 中分别有 3 个副本 ReplicaA、ReplicaB 和 ReplicaC。ReplicaA 是第一个副本，首先作为区域表创建，然后将 ReplicaB 和 ReplicaC 添加到其中。
+ 账户 A 的管理员必须先将基于资源的策略附加到 ReplicaA，允许所有成员进行复制，并允许账户 B 和账户 C 的 IAM 主体添加副本。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "DynamoDBActionsNeededForSteadyStateReplication",
            "Effect": "Allow",
            "Action": [
                "dynamodb:ReadDataForReplication",
                "dynamodb:WriteDataForReplication",
                "dynamodb:ReplicateSettings"
            ],
            "Resource": "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
            "Principal": {"Service": ["replication.dynamodb.amazonaws.com"]},
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": [ "111122223333", "444455556666", "123456789012" ],
                    "aws:SourceArn": [
                        "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
                        "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB",
                        "arn:aws:dynamodb:us-east-1:123456789012:table/ReplicaC"
                    ]
                }
            }
        },
        {
            "Sid": "AllowTrustedAccountsToJoinThisGlobalTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:AssociateTableReplica"
            ],
            "Resource": "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
            "Principal": { "AWS": [ "444455556666", "123456789012" ] }
        }
    ]
}
```

------
+ 账户 B 的管理员必须添加一个指向 ReplicaA（源）的副本，即 ReplicaB。ReplicaB 具有以下策略，允许在所有成员之间进行复制，并允许账户 C 添加副本：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "DynamoDBActionsNeededForSteadyStateReplication",
            "Effect": "Allow",
            "Action": [
                "dynamodb:ReadDataForReplication",
                "dynamodb:WriteDataForReplication",
                "dynamodb:ReplicateSettings"
            ],
            "Resource": "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB",
            "Principal": {"Service": ["replication.dynamodb.amazonaws.com"]},
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": [ "111122223333", "444455556666", "123456789012" ],
                    "aws:SourceArn": [
                        "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
                        "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB",
                        "arn:aws:dynamodb:us-east-1:123456789012:table/ReplicaC"
                    ]
                }
            }
        },
        {
            "Sid": "AllowTrustedAccountsToJoinThisGlobalTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:AssociateTableReplica"
            ],
            "Resource": "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB",
            "Principal": { "AWS": [ "123456789012" ] }
        }
    ]
}
```

------
+ 最后，账户 C 的管理员创建具有以下策略的副本，允许所有成员之间的复制权限。该策略不允许再添加任何副本。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "DynamoDBActionsNeededForSteadyStateReplication",
            "Effect": "Allow",
            "Action": [
                "dynamodb:ReadDataForReplication",
                "dynamodb:WriteDataForReplication",
                "dynamodb:ReplicateSettings"
            ],
            "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/ReplicaC",
            "Principal": {"Service": ["replication.dynamodb.amazonaws.com"]},
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": [ "111122223333", "444455556666" ],
                    "aws:SourceArn": [
                        "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
                        "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB"
                    ]
                }
            }
        }
    ]
}
```

------

### 更新多账户全局表


要使用 UpdateTable API 修改现有全局表的副本设置，对于进行 API 调用的区域中的表资源，您需要具有以下权限：`dynamodb:UpdateTable`

此外，您还可以更新其他全局表配置，例如自动扩缩策略和生存时间设置。这些额外的更新操作需要以下权限：

要使用 `UpdateTimeToLive` API 更新生存时间设置，对于包含副本的所有区域中的表资源，您必须具有以下权限：`dynamodb:UpdateTimeToLive`

要通过 `UpdateTableReplicaAutoScaling` API 更新副本自动扩缩策略，对于包含副本的所有区域中的表资源，您必须具有以下权限：
+ `application-autoscaling:DeleteScalingPolicy`
+ `application-autoscaling:DeleteScheduledAction`
+ `application-autoscaling:DeregisterScalableTarget`
+ `application-autoscaling:DescribeScalableTargets`
+ `application-autoscaling:DescribeScalingActivities`
+ `application-autoscaling:DescribeScalingPolicies`
+ `application-autoscaling:DescribeScheduledActions`
+ `application-autoscaling:PutScalingPolicy`
+ `application-autoscaling:PutScheduledAction`
+ `application-autoscaling:RegisterScalableTarget`

**注意**  
要成功更新表，您必须向所有副本区域和账户提供 `dynamodb:ReplicateSettings` 权限。如果多账户全局表中的任意副本未提供权限，导致无法将设置复制到任意其他副本，则在权限得到修复之前，所有副本的所有更新操作都将失败并出现 `AccessDeniedException`。

### 删除全局表和移除副本


要删除全局表，您必须移除所有副本。与同账户全局表不同，您不能使用 `UpdateTable` 删除远程区域中的副本表，您必须从控制副本表的账户中，通过 `DeleteTable` API 删除各个副本。

#### 删除全局表和移除副本的权限


删除单个副本和完全删除全局表均需要以下权限。删除全局表配置只会移除不同区域中表之间的复制关系。它不会删除剩下的最后一个区域中的基础 DynamoDB 表。最后一个区域中的表会作为标准 DynamoDB 表继续存在，具有相同的数据和设置。

在要移除副本的每个区域，您需要具有对表资源的以下权限：
+ `dynamodb:DeleteTable`
+ `dynamodb:DeleteTableReplica`

## 全局表如何使用 Amazon KMS


与所有 DynamoDB 表一样，全局表副本始终使用存储在 Amazon Key Management Service（Amazon KMS）中的加密密钥对静态数据进行加密。

**注意**  
与同账户全局表不同，多账户全局表中的不同副本可以配置为使用不同类型的 Amazon KMS 密钥（Amazon 拥有的密钥，或客户自主管理型密钥）。多账户全局表不支持 Amazon 托管式密钥。

使用 CMK 的多账户全局表要求每个副本的密钥策略向 DynamoDB 复制服务主体 (`replication.dynamodb.amazonaws.com`) 授予权限，以便访问密钥用于复制和设置管理。需要以下权限：
+ `kms:Decrypt`
+ `kms:ReEncrypt*`
+ `kms:GenerateDataKey*`
+ `kms:DescribeKey`

**重要提示**

DynamoDB 需要访问副本的加密密钥才能删除副本。如果您因删除副本而想要禁用或删除加密该副本所用的客户自主管理型密钥，则应先删除该副本，等待表从复制组中删除（通过在任一其他副本中调用 describe），然后再禁用或删除该密钥。

对于加密副本所用的客户自主管理型密钥，如果您禁用或撤销 DynamoDB 对密钥的访问权限，则复制到副本以及从副本进行复制的过程将停止，而副本状态将更改为 `INACCESSIBLE_ENCRYPTION_CREDENTIALS`。如果副本保持 `INACCESSIBLE_ENCRYPTION_CREDENTIALS` 状态的时间超过 20 小时，则该副本将不可逆地转换为单区域 DynamoDB 表。

### Amazon KMS 策略示例


Amazon KMS 策略允许 DynamoDB 访问两个 Amazon KMS 密钥，以便在副本 A 和 B 之间进行复制。每个账户中附加到 DynamoDB 副本的 Amazon KMS 密钥需要使用以下策略进行更新：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": { "Service": "replication.dynamodb.amazonaws.com" },
        "Action": [
            "kms:Decrypt",
            "kms:ReEncrypt*",
            "kms:GenerateDataKey*",
            "kms:DescribeKey"
        ],
        "Resource": "*",
        "Condition": {
            "StringEquals": {
                "aws:SourceAccount": [ "111122223333", "444455556666" ],
                "aws:SourceArn": [
                    "arn:aws:dynamodb:ap-east-1:111122223333:table/ReplicaA",
                    "arn:aws:dynamodb:eu-south-1:444455556666:table/ReplicaB"
                ]
            }
        }
      }
   ]
 }
```

------