

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 搭配 DynamoDB 使用屬性型存取控制
<a name="attribute-based-access-control"></a>

[屬性型存取控制 (ABAC)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html) 是一種授權策略，可根據身分型政策或其他 AWS 政策中的[標籤條件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html)定義存取許可，例如資源型政策和組織 IAM 政策。您可以將標籤附加至 DynamoDB 資料表，系統會根據標籤式條件進行評估。資料表所關聯的索引會繼承您新增至該資料表的標籤。每個 DynamoDB 資料表最多可新增 50 個標籤。資料表中所有標籤支援的大小上限為 10 KB。如需有關標記 DynamoDB 資源及標記限制的詳細資訊，請參閱[在 DynamoDB 中標記資源](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.Operations.html)與 [DynamoDB 中的標記限制](Tagging.md#TaggingRestrictions)。

如需使用標籤控制 AWS 資源存取的詳細資訊，請參閱《IAM 使用者指南》中的下列主題：
+ [什麼是 ABAC AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html)
+ [使用標籤控制對 AWS 資源的存取](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html)

使用 ABAC，您可以為團隊與應用程式設定不同的存取層級，並以更少的政策在 DynamoDB 資料表上執行操作。您可以在 IAM 政策的[條件元素](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)中指定標籤，以控制對 DynamoDB 資料表或索引的存取。這些條件決定 IAM 主體、使用者或角色對 DynamoDB 資料表與索引的存取層級。當 IAM 主體向 DynamoDB 提出存取請求時，系統會根據 IAM 政策中的標籤條件評估資源與身分的標籤。之後，僅在符合標籤條件時，該政策才會生效。這可讓您建立能實現以下任一條件的 IAM 政策：
+ *允許使用者僅管理具有標籤鍵`X`與值 `Y` 標籤的資源*。
+ *拒絕所有使用者存取具有標籤鍵 `X` 的資源*。

例如，您可以建立政策，僅允許使用者更新具有下列標籤鍵值對的資料表：`"environment": "staging"`。您可以使用 [aws：ResourceTag](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag) 條件鍵，根據附加至該資料表的標籤來允許或拒絕存取。

您可以在建立政策時或稍後使用 AWS 管理主控台、 AWS API、 AWS Command Line Interface (AWS CLI)、 AWS SDK 或 包含屬性型條件 AWS CloudFormation。

下列範例允許在名為 `MusicTable` 的資料表上執行 [UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) 動作，前提是該資料表具有名稱為 `environment`、值為 `production` 的標籤鍵值。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:UpdateItem"
      ],
      "Resource": "arn:aws:dynamodb:*:*:table/MusicTable",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/environment": "production"
        }
      }
    }
  ]
}
```

------

**Topics**
+ [為什麼要使用 ABAC？](#why-use-abac)
+ [使用 DynamoDB 實作 ABAC 的條件鍵](#condition-keys-implement-abac)
+ [搭配 DynamoDB 使用 ABAC 的注意事項](#abac-considerations)
+ [在 DynamoDB 中啟用 ABAC](abac-enable-ddb.md)
+ [在 DynamoDB 資料表與索引中使用 ABAC](abac-implementation-ddb-tables.md)
+ [使用 ABAC 搭配 DynamoDB 資料表與索引的範例](abac-example-use-cases.md)
+ [疑難排解 DynamoDB 資料表與索引的常見 ABAC 錯誤](abac-troubleshooting.md)

## 為什麼要使用 ABAC？
<a name="why-use-abac"></a>
+ **更簡單的政策管理：**您可以減少使用的政策數量，因為不需為每個 IAM 主體建立不同的政策來定義其存取層級。
+ **可擴展的存取控制：**使用 ABAC 可讓存取控制更容易擴展，因為在建立新的 DynamoDB 資源時，無需更新政策。您可以使用標籤授權存取那些擁有與資源標籤相符標籤的 IAM 主體。您可以新增 IAM 主體或 DynamoDB 資源，套用適當的標籤，即可自動授予必要的權限，無需修改任何政策。
+ **細粒度權限管理：**在建立政策時，最佳實務是[授與最低權限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)。使用 ABAC，您可以為 IAM 主體建立標籤，並依據這些標籤授與符合的特定動作與資源的存取權限。
+ **與公司目錄對應：**您可以將標籤對應至公司目錄中的員工屬性，使存取控制政策與組織結構保持一致。

## 使用 DynamoDB 實作 ABAC 的條件鍵
<a name="condition-keys-implement-abac"></a>

您可以在 AWS 政策中使用下列條件索引鍵來控制 DynamoDB 資料表和索引的存取層級：
+ [aws:ResourceTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag)：根據 DynamoDB 資料表或索引上的標籤鍵值組是否與政策中的標籤鍵和值相符來控制存取。此條件鍵適用於所有針對現有資料表或索引運作的 API。

  這些 `dynamodb:ResourceTag` 條件的評估方式與資源未附加任何標籤時相同。
+ [aws:RequestTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag)：可用於比較請求中傳遞的標籤鍵值組與政策中指定的標籤鍵值組。此條件鍵適用於在請求承載中包含標籤的 API。包含這些 API：[CreateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html) 與 [TagResource](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TagResource.html)。
+ [aws:TagKeys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys)：用於比較請求中的標籤鍵與政策中指定的標籤鍵。此條件鍵適用於在請求承載中包含標籤的 API。相關 API 包含 `CreateTable`、`TagResource` 與 `UntagResource`。

## 搭配 DynamoDB 使用 ABAC 的注意事項
<a name="abac-considerations"></a>

當您將 ABAC 用於 DynamoDB 資料表或索引時，請注意以下事項：
+ DynamoDB Streams 不支援標籤與 ABAC。
+ DynamoDB 備份不支援標籤與 ABAC。若要在備份中使用 ABAC，建議您使用 [AWS Backup](https://docs.aws.amazon.com/aws-backup/latest/devguide/whatisbackup.html)。
+ 標籤不會在還原的資料表中保留。您必須先將標籤新增至還原的資料表，才能在政策中使用標籤式條件。

# 在 DynamoDB 中啟用 ABAC
<a name="abac-enable-ddb"></a>

對於大多數 AWS 帳戶，預設為啟用 ABAC。使用 [DynamoDB 主控台](https://console.aws.amazon.com/dynamodb/)，您可以確認帳戶是否已啟用 ABAC。若要執行此操作，請使用具有 [dynamodb：GetAbacStatus](#required-permissions-abac) 權限的角色開啟 DynamoDB 主控台。接著，開啟 DynamoDB 主控台的**設定**頁面。

若您未看到**屬性型存取控制**卡片，或卡片顯示狀態為**開啟**，即表示您的帳戶已啟用 ABAC。不過，如果您看到**屬性型存取控制**卡片顯示狀態為**關閉** (如下圖所示)，表示帳戶未啟用 ABAC。

## 屬性型存取控制 – 未啟用
<a name="abac-disabled-image"></a>

![\[DynamoDB 主控台的設定頁面，顯示屬性型存取控制卡片。\]](http://docs.aws.amazon.com/zh_tw/amazondynamodb/latest/developerguide/images/ddb-console-settings-page.png)


ABAC 不會 AWS 帳戶 為其身分型政策或其他政策中指定的標籤型條件啟用。若您的帳戶未啟用 ABAC，政策中針對 DynamoDB 資料表或索引設計的標籤式條件，將會以資源或 API 請求不含任何標籤的狀態進行評估。當您為帳戶啟用 ABAC 時，系統會依據附加至資料表或 API 請求的標籤，評估帳戶中政策內的標籤式條件。

若要啟用帳戶的 ABAC，我們建議您先依 [政策稽核](#policy-audit-for-abac) 一節所述稽核您的政策。接著，在 IAM 政策中加入 [ABAC 所需的權限](#required-permissions-abac)。最後，依 [在主控台啟用 ABAC](#abac-enable-console) 所述步驟，在目前區域為帳戶啟用 ABAC。啟用 ABAC 後，您可在加入後七個日曆天內選擇退出。

**Topics**
+ [啟用 ABAC 前稽核政策](#policy-audit-for-abac)
+ [啟用 ABAC 所需的 IAM 權限](#required-permissions-abac)
+ [在主控台啟用 ABAC](#abac-enable-console)

## 啟用 ABAC 前稽核政策
<a name="policy-audit-for-abac"></a>

在啟用帳戶的 ABAC 前，請稽核政策，確認帳戶內的標籤式條件均已按預期設定。稽核政策可協助避免啟用 ABAC 後，DynamoDB 工作流程中出現授權變更的意外情況。若要查看使用屬性型條件與標籤的範例，以及 ABAC 實作前後的行為變化，請參閱 [使用 ABAC 搭配 DynamoDB 資料表與索引的範例範例使用案例](abac-example-use-cases.md)。

## 啟用 ABAC 所需的 IAM 權限
<a name="required-permissions-abac"></a>

您需要 `dynamodb:UpdateAbacStatus` 權限，才能在目前區域為帳戶啟用 ABAC。若要確認帳戶是否已啟用 ABAC，您也必須具備 `dynamodb:GetAbacStatus` 權限。具備此權限後，您可在任何區域檢視帳戶的 ABAC 狀態。除了存取 DynamoDB 主控台所需的權限外，您還需要這些額外權限。

下列 IAM 政策授予權限，可啟用 ABAC 並檢視目前區域內帳戶的狀態。

```
{
"version": "2012-10-17", 		 	 	 &TCX5-2025-waiver;
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:UpdateAbacStatus",
                "dynamodb:GetAbacStatus"
             ],
            "Resource": "*"
        }
    ]
}
```

## 在主控台啟用 ABAC
<a name="abac-enable-console"></a>

1. 登入 AWS 管理主控台 ，並在 https：//[https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) 開啟 DynamoDB 主控台。

1. 從頂端導覽窗格選取要啟用 ABAC 的區域。

1. 在左側的導覽窗格中，選擇**設定**。

1. 在**設定**頁面執行以下動作：

   1. 在**屬性型存取控制**卡片中，選取**啟用**。

   1. 在**確認屬性型存取控制設定**對話方塊中，選取**啟用**以確認設定。

      這將在目前區域啟用 ABAC，且**屬性型存取控制**卡片會顯示狀態為**開啟**。

      若您在主控台啟用 ABAC 後想退出，可在加入後七個日曆天內執行。若要退出，請前往**設定**頁面，於**屬性型存取控制**卡片中選取**停用**。
**注意**  
更新 ABAC 狀態屬於非同步作業。若政策中的標籤未立即生效，可能需等待一段時間，因為變更的套用會最終一致。

# 在 DynamoDB 資料表與索引中使用 ABAC
<a name="abac-implementation-ddb-tables"></a>

以下步驟示範如何使用 ABAC 設定權限。在此範例中，您將新增標籤至 DynamoDB 資料表，並建立包含標籤式條件的 IAM 角色。接著，您將透過比對標籤條件，測試 DynamoDB 資料表上可用的權限。

**Topics**
+ [步驟 1：將標籤新增至 DynamoDB 資料表](#abac-add-table-tags)
+ [步驟 2：建立包含標籤式條件的 IAM 角色與政策](#abac-create-iam-role)
+ [步驟 3：測試允許的權限](#abac-test-permissions)

## 步驟 1：將標籤新增至 DynamoDB 資料表
<a name="abac-add-table-tags"></a>

您可以使用 AWS 管理主控台、 AWS API、 AWS Command Line Interface (AWS CLI)、 AWS SDK 或 將標籤新增至新的或現有的 DynamoDB 資料表 AWS CloudFormation。例如，下列 [tag-resource](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/tag-resource.html) CLI 指令會將標籤新增至名為 `MusicTable` 的資料表。

```
aws dynamodb tag-resource —resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/MusicTable —tags Key=environment,Value=staging
```

## 步驟 2：建立包含標籤式條件的 IAM 角色與政策
<a name="abac-create-iam-role"></a>

使用 [aws：ResourceTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag) 條件金鑰[建立 IAM 政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html#access_policies_create-json-editor)，以比較政策中指定的標籤鍵值對與附加至資料表的鍵值對。下列範例政策允許使用者在資料表中放入或更新項目，前提是該資料表包含下列標籤鍵值對：`"environment": "staging"`。若資料表未具指定的標籤鍵值對，系統將拒絕執行這些操作。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem",
                "dynamodb:UpdateItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/environment": "staging"
                }
            }
        }
    ]
}
```

------

## 步驟 3：測試允許的權限
<a name="abac-test-permissions"></a>

1. 將 IAM 政策附加至 AWS 帳戶中的測試使用者或角色。確認您使用的 IAM 主體未經由其他政策擁有對 DynamoDB 資料表的存取權限。

1. 確認您的 DynamoDB 資料表包含值為 `"staging"` 的 `"environment"` 標籤鍵。

1. 在已標記的資料表上執行 `dynamodb:PutItem` 和 `dynamodb:UpdateItem` 動作。若 `"environment": "staging"` 標籤鍵值對存在，這些動作應可成功執行。

   若在不含 `"environment": "staging"` 標籤鍵值對的資料表上執行這些動作，請求將失敗並返回 `AccessDeniedException`。

您也可以檢閱下一節中說明的其他[範例使用案例](abac-example-use-cases.md)，以實作 ABAC 並進行更多測試。

# 使用 ABAC 搭配 DynamoDB 資料表與索引的範例
<a name="abac-example-use-cases"></a>

下列範例展示使用標籤實作屬性式條件的多種使用案例。

**Topics**
+ [範例 1：使用 aws:ResourceTag 允許動作](#abac-allow-example-resource-tag)
+ [範例 2：使用 aws:RequestTag 允許動作](#abac-allow-example-request-tag)
+ [範例 3：使用 aws:TagKeys 拒絕動作](#abac-deny-example-tag-key)

## 範例 1：使用 aws:ResourceTag 允許動作
<a name="abac-allow-example-resource-tag"></a>

使用 `aws:ResourceTag/tag-key` 條件鍵，您可以比較 IAM 政策中指定的標籤鍵值對與附加在 DynamoDB 資料表中的鍵值對。例如，若 IAM 政策與資料表的標籤條件相符，即可允許執行特定動作，如 [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)。請依下列步驟操作：

------
#### [ Using the AWS CLI ]

1. 建立資料表。下列範例使用 [create-table](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html) AWS CLI 命令來建立名為 的資料表`myMusicTable`。

   ```
   aws dynamodb create-table \
     --table-name myMusicTable \
     --attribute-definitions AttributeName=id,AttributeType=S \
     --key-schema AttributeName=id,KeyType=HASH \
     --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
     --region us-east-1
   ```

1. 為此資料表新增一個標籤。下列 [tag-resource](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/tag-resource.html) AWS CLI 命令範例會將標籤鍵值對新增至 `Title: ProductManager` `myMusicTable`。

   ```
   aws dynamodb tag-resource --region us-east-1 --resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/myMusicTable --tags Key=Title,Value=ProductManager
   ```

1. 建立[內嵌政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies)並將其新增至已連接 [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS 受管政策的角色，如下列範例所示。

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "dynamodb:PutItem",
         "Resource": "arn:aws:dynamodb:*:*:table/*",
         "Condition": {
           "StringEquals": {
             "aws:ResourceTag/Title": "ProductManager"
           }
         }
       }
     ]
   }
   ```

------

   當附加至資料表的標籤鍵和值與政策中指定的標籤相符時，此政策允許在該資料表上執行 `PutItem` 動作。

1. 依步驟 3 中說明的政策假設該角色。

1. 使用 [put-item](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/put-item.html) AWS CLI 命令將項目放入 `myMusicTable`。

   ```
   aws dynamodb put-item \
       --table-name myMusicTable --region us-east-1 \
       --item '{
           "id": {"S": "2023"},
           "title": {"S": "Happy Day"},
           "info": {"M": {
               "rating": {"N": "9"},
               "Artists": {"L": [{"S": "Acme Band"}, {"S": "No One You Know"}]},
               "release_date": {"S": "2023-07-21"}
           }}
       }'
   ```

1. 掃描資料表以確認項目是否已成功新增。

   ```
   aws dynamodb scan --table-name myMusicTable  --region us-east-1
   ```

------
#### [ Using the AWS SDK for Java 2.x ]

1. 建立資料表。下列範例使用 [CreateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html) API 建立名為 `myMusicTable` 的資料表。

   ```
   DynamoDbClient dynamoDB = DynamoDbClient.builder().region(region).build();
   CreateTableRequest createTableRequest = CreateTableRequest.builder()
       .attributeDefinitions(
           Arrays.asList(
               AttributeDefinition.builder()
               .attributeName("id")
               .attributeType(ScalarAttributeType.S)
               .build()
           )
       )
       .keySchema(
           Arrays.asList(
               KeySchemaElement.builder()
               .attributeName("id")
               .keyType(KeyType.HASH)
               .build()
           )
       )
       .provisionedThroughput(ProvisionedThroughput.builder()
           .readCapacityUnits(5L)
           .writeCapacityUnits(5L)
           .build()
       )
       .tableName("myMusicTable")
       .build();
   
   CreateTableResponse createTableResponse = dynamoDB.createTable(createTableRequest);
   String tableArn = createTableResponse.tableDescription().tableArn();
   String tableName = createTableResponse.tableDescription().tableName();
   ```

1. 為此資料表新增一個標籤。下列範例中，[TagResource](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TagResource.html) API 會將標籤鍵值對 `Title: ProductManager` 新增至 `myMusicTable`。

   ```
   TagResourceRequest tagResourceRequest = TagResourceRequest.builder()
       .resourceArn(tableArn)
       .tags(
           Arrays.asList(
               Tag.builder()
               .key("Title")
               .value("ProductManager")
               .build()
           )
       )
       .build();
   dynamoDB.tagResource(tagResourceRequest);
   ```

1. 建立[內嵌政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies)並將其新增至已連接 [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS 受管政策的角色，如下列範例所示。

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "dynamodb:PutItem",
         "Resource": "arn:aws:dynamodb:*:*:table/*",
         "Condition": {
           "StringEquals": {
             "aws:ResourceTag/Title": "ProductManager"
           }
         }
       }
     ]
   }
   ```

------

   當附加至資料表的標籤鍵和值與政策中指定的標籤相符時，此政策允許在該資料表上執行 `PutItem` 動作。

1. 依步驟 3 中說明的政策假設該角色。

1. 使用 [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) API 將項目新增至 `myMusicTable`。

   ```
   HashMap<String, AttributeValue> info = new HashMap<>();
   info.put("rating", AttributeValue.builder().s("9").build());
   info.put("artists", AttributeValue.builder().ss(List.of("Acme Band","No One You Know").build());
   info.put("release_date", AttributeValue.builder().s("2023-07-21").build());
   
   HashMap<String, AttributeValue> itemValues = new HashMap<>();
   itemValues.put("id", AttributeValue.builder().s("2023").build());
   itemValues.put("title", AttributeValue.builder().s("Happy Day").build());
   itemValues.put("info", AttributeValue.builder().m(info).build());
   
   
   PutItemRequest putItemRequest = PutItemRequest.builder()
                   .tableName(tableName)
                   .item(itemValues)
                   .build();
   dynamoDB.putItem(putItemRequest);
   ```

1. 掃描資料表以確認項目是否已成功新增。

   ```
   ScanRequest scanRequest = ScanRequest.builder()
                   .tableName(tableName)
                   .build();
                   
   ScanResponse scanResponse = dynamoDB.scan(scanRequest);
   ```

------
#### [ Using the 適用於 Python (Boto3) 的 AWS SDK ]

1. 建立資料表。下列範例使用 [CreateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html) API 建立名為 `myMusicTable` 的資料表。

   ```
   create_table_response = ddb_client.create_table(
       AttributeDefinitions=[
           {
               'AttributeName': 'id',
               'AttributeType': 'S'
           },
       ],
       TableName='myMusicTable',
       KeySchema=[
           {
               'AttributeName': 'id',
               'KeyType': 'HASH'
           },
       ],
           ProvisionedThroughput={
           'ReadCapacityUnits': 5,
           'WriteCapacityUnits': 5
       },
   )
   
   table_arn = create_table_response['TableDescription']['TableArn']
   ```

1. 為此資料表新增一個標籤。下列範例中，[TagResource](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TagResource.html) API 會將標籤鍵值對 `Title: ProductManager` 新增至 `myMusicTable`。

   ```
   tag_resouce_response = ddb_client.tag_resource(
       ResourceArn=table_arn,
       Tags=[
           {
               'Key': 'Title',
               'Value': 'ProductManager'
           },
       ]
   )
   ```

1. 建立[內嵌政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies)並將其新增至已連接 [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS 受管政策的角色，如下列範例所示。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
           "Effect": "Allow",
           "Action": "dynamodb:PutItem",
           "Resource": "arn:aws:dynamodb:*:*:table/*",
           "Condition": {
               "StringEquals": {
               "aws:ResourceTag/Title": "ProductManager"
               }
           }
           }
       ]
       }
   ```

------

   當附加至資料表的標籤鍵和值與政策中指定的標籤相符時，此政策允許在該資料表上執行 `PutItem` 動作。

1. 依步驟 3 中說明的政策假設該角色。

1. 使用 [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) API 將項目新增至 `myMusicTable`。

   ```
   put_item_response = client.put_item(
       TableName = 'myMusicTable'
       Item = {
           'id': '2023',
           'title': 'Happy Day',
           'info': {
               'rating': '9',
               'artists': ['Acme Band','No One You Know'],
               'release_date': '2023-07-21'
           }
       }
   )
   ```

1. 掃描資料表以確認項目是否已成功新增。

   ```
   scan_response = client.scan(
       TableName='myMusicTable'
   )
   ```

------

**未啟用 ABAC**  
如果您的 未啟用 ABAC AWS 帳戶，則 IAM 政策和 DynamoDB 資料表中的標籤條件不相符。因此，`PutItem` 動作會因 `AmazonDynamoDBReadOnlyAccess` 政策的影響而返回 `AccessDeniedException`。

```
An error occurred (AccessDeniedException) when calling the PutItem operation: User: arn:aws:sts::123456789012:assumed-role/DynamoDBReadOnlyAccess/Alice is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-east-1:123456789012:table/myMusicTable because no identity-based policy allows the dynamodb:PutItem action.
```

**啟用 ABAC**  
如果您的 已啟用 ABAC AWS 帳戶，則`put-item`動作會成功完成，並將新項目新增至您的資料表。這是因為當 IAM 政策與資料表中的標籤條件相符時，資料表中的內嵌政策會允許執行 `PutItem` 動作。

## 範例 2：使用 aws:RequestTag 允許動作
<a name="abac-allow-example-request-tag"></a>

使用 [aws：RequestTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag) 條件金鑰，您可以比較請求中傳遞的標籤鍵值對與 IAM 政策中指定的鍵值對。例如，若標籤條件不相符，您可以使用 `aws:RequestTag` 來允許特定動作 (如 `CreateTable`)。請依下列步驟操作：

------
#### [ Using the AWS CLI ]

1. 建立[內嵌政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies)並將其新增至已連接 [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/ReadOnlyAccess.html) AWS 受管政策的角色，如下列範例所示。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "dynamodb:CreateTable",
                   "dynamodb:TagResource"
               ],
               "Resource": "arn:aws:dynamodb:*:*:table/*",
               "Condition": {
                   "StringEquals": {
                       "aws:RequestTag/Owner": "John"
                   }
               }
           }
       ]
   }
   ```

------

1. 建立一個包含 `"Owner": "John"` 標籤鍵值對的資料表。

   ```
   aws dynamodb create-table \
   --attribute-definitions AttributeName=ID,AttributeType=S \
   --key-schema AttributeName=ID,KeyType=HASH  \
   --provisioned-throughput ReadCapacityUnits=1000,WriteCapacityUnits=500 \
   --region us-east-1 \
   --tags Key=Owner,Value=John \
   --table-name myMusicTable
   ```

------
#### [ Using the 適用於 Python (Boto3) 的 AWS SDK ]

1. 建立[內嵌政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies)並將其新增至已連接 [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS 受管政策的角色，如下列範例所示。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "dynamodb:CreateTable",
                   "dynamodb:TagResource"
               ],
               "Resource": "arn:aws:dynamodb:*:*:table/*",
               "Condition": {
                   "StringEquals": {
                       "aws:RequestTag/Owner": "John"
                   }
               }
           }
       ]
   }
   ```

------

1. 建立一個包含 `"Owner": "John"` 標籤鍵值對的資料表。

   ```
   ddb_client = boto3.client('dynamodb')
   
   create_table_response = ddb_client.create_table(
       AttributeDefinitions=[
           {
               'AttributeName': 'id',
               'AttributeType': 'S'
           },
       ],
       TableName='myMusicTable',
       KeySchema=[
           {
               'AttributeName': 'id',
               'KeyType': 'HASH'
           },
       ],
           ProvisionedThroughput={
           'ReadCapacityUnits': 1000,
           'WriteCapacityUnits': 500
       },
       Tags=[
           {
               'Key': 'Owner',
               'Value': 'John'
           },
       ],
   )
   ```

------

**未啟用 ABAC**  
如果您的 未啟用 ABAC AWS 帳戶，則內嵌政策和 DynamoDB 資料表中的標籤條件不相符。因此，`CreateTable` 請求會失敗，資料表將不會建立。

```
An error occurred (AccessDeniedException) when calling the CreateTable operation: User: arn:aws:sts::123456789012:assumed-role/Admin/John is not authorized to perform: dynamodb:CreateTable on resource: arn:aws:dynamodb:us-east-1:123456789012:table/myMusicTable because no identity-based policy allows the dynamodb:CreateTable action.
```

**啟用 ABAC**  
如果您的 已啟用 ABAC AWS 帳戶，則您的資料表建立請求會成功完成。由於 `"Owner": "John"` 的標籤鍵值對存在於 `CreateTable` 請求中，內嵌政策允許使用者 `John` 執行 `CreateTable` 動作。

## 範例 3：使用 aws:TagKeys 拒絕動作
<a name="abac-deny-example-tag-key"></a>

使用 [aws：TagKeys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys) 條件金鑰，您可以比較請求中的標籤金鑰與 IAM 政策中指定的金鑰。例如，若請求中未包含特定標籤鍵 *not*，您可以使用 `aws:TagKeys` 來拒絕特定動作 (如 `CreateTable`)。請依下列步驟操作：

------
#### [ Using the AWS CLI ]

1. 將[客戶受管政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies)新增至已連接 [AmazonDynamoDBFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBFullAccess.html) AWS 受管政策的角色，如下列範例所示。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Deny",
               "Action": [
                   "dynamodb:CreateTable",
                   "dynamodb:TagResource"
               ],
               "Resource": "arn:aws:dynamodb:*:*:table/*",
               "Condition": {
                   "Null": {
                       "aws:TagKeys": "false"
                   },
                   "ForAllValues:StringNotEquals": {
                       "aws:TagKeys": "CostCenter"
                   }
               }
           }
       ]
   }
   ```

------

1. 以附加該政策的角色身分建立含有標籤鍵 `Title` 的資料表。

   ```
   aws dynamodb create-table \
   --attribute-definitions AttributeName=ID,AttributeType=S \
   --key-schema AttributeName=ID,KeyType=HASH  \
   --provisioned-throughput ReadCapacityUnits=1000,WriteCapacityUnits=500 \
   --region us-east-1 \
   --tags Key=Title,Value=ProductManager \
   --table-name myMusicTable
   ```

------
#### [ Using the 適用於 Python (Boto3) 的 AWS SDK ]

1. 將[客戶受管政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies)新增至已連接 [AmazonDynamoDBFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBFullAccess.html) AWS 受管政策的角色，如下列範例所示。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Deny",
               "Action": [
                   "dynamodb:CreateTable",
                   "dynamodb:TagResource"
               ],
               "Resource": "arn:aws:dynamodb:*:*:table/*",
               "Condition": {
                   "Null": {
                       "aws:TagKeys": "false"
                   },
                   "ForAllValues:StringNotEquals": {
                       "aws:TagKeys": "CostCenter"
                   }
               }
           }
       ]
   }
   ```

------

1. 以附加該政策的角色身分建立含有標籤鍵 `Title` 的資料表。

   ```
   ddb_client = boto3.client('dynamodb')
   
   create_table_response = ddb_client.create_table(
       AttributeDefinitions=[
           {
               'AttributeName': 'id',
               'AttributeType': 'S'
           },
       ],
       TableName='myMusicTable',
       KeySchema=[
           {
               'AttributeName': 'id',
               'KeyType': 'HASH'
           },
       ],
           ProvisionedThroughput={
           'ReadCapacityUnits': 1000,
           'WriteCapacityUnits': 500
       },
       Tags=[
           {
               'Key': 'Title',
               'Value': 'ProductManager'
           },
       ],
   )
   ```

------

**未啟用 ABAC**  
如果您的 未啟用 ABAC AWS 帳戶，DynamoDB 不會將`create-table`命令中的標籤金鑰傳送至 IAM。`Null` 條件可確保當請求中沒有標籤鍵時，條件的評估結果為 `false`。由於 `Deny` 政策不相符，`create-table` 指令將成功完成。

**啟用 ABAC**  
如果您的 已啟用 ABAC AWS 帳戶，則 `create-table`命令中傳遞的標籤金鑰會傳遞給 IAM。標籤鍵 `Title` 會根據 `Deny` 政策中所設定的條件型標籤鍵 `CostCenter` 進行比對。由於 `StringNotEquals` 運算子，`Title` 標籤鍵與 `Deny` 政策中的標籤鍵不相符。因此，`CreateTable` 動作將失敗，資料表不會建立。執行 `create-table` 指令時會傳回 `AccessDeniedException`。

```
An error occurred (AccessDeniedException) when calling the CreateTable operation: User: arn:aws:sts::123456789012:assumed-role/DynamoFullAccessRole/ProductManager is not authorized to perform: dynamodb:CreateTable on resource: arn:aws:dynamodb:us-east-1:123456789012:table/myMusicTable with an explicit deny in an identity-based policy.
```

# 疑難排解 DynamoDB 資料表與索引的常見 ABAC 錯誤
<a name="abac-troubleshooting"></a>

本主題提供在 DynamoDB 資料表或索引中實作 ABAC 時，可能遇到的常見錯誤與問題的疑難排解建議。

## 政策中使用服務特定條件金鑰會導致錯誤
<a name="abac-troubleshooting-service-specific-keys"></a>

服務特定條件金鑰不被視為有效的條件金鑰。若在政策中使用此類金鑰，將導致錯誤。若要解決此問題，請將服務特定條件金鑰替換為合適的[條件金鑰，以在 DynamoDB 中實作 ABAC](attribute-based-access-control.md#condition-keys-implement-abac)。

例如，假設您在執行 [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) 請求的[內嵌政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies)中使用了 `dynamodb:ResourceTag` 條件金鑰。假設請求因 `AccessDeniedException` 而失敗。下列範例顯示包含 `dynamodb:ResourceTag` 條件金鑰的錯誤內嵌政策。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/*",
            "Condition": {
                "StringEquals": {
                    "dynamodb:ResourceTag/Owner": "John"
                }
            }
        }
    ]
}
```

------

若要解決此問題，請將 `dynamodb:ResourceTag` 條件金鑰替換為 `aws:ResourceTag`，如下例所示。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Owner": "John"
                }
            }
        }
    ]
}
```

------

## 無法停用 ABAC
<a name="abac-troubleshooting-unable-opt-out"></a>

如果您的帳戶已透過 啟用 ABAC 支援，您將無法透過 DynamoDB 主控台選擇退出 ABAC。若要停用，請聯絡 [支援](https://console.aws.amazon.com/support)。

僅當 *only if* 下列條件成立時，您才可自行停用 ABAC：
+ 您已使用[透過 DynamoDB 主控台選擇加入](abac-enable-ddb.md#abac-enable-console)的自助式流程。
+ 您在選擇加入後七天內停用。