

# Using attribute-based access control with DynamoDB
<a name="attribute-based-access-control"></a>

[Attribute-based access control (ABAC)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html) is an authorization strategy that defines access permissions based on [tag conditions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html) in your identity-based policies or other AWS policies, such as resource-based policies and organization IAM policies. You can attach tags to DynamoDB tables, which are then evaluated against the tag-based conditions. The indexes associated with a table inherit the tags you add to the table. You can add up to 50 tags for each DynamoDB table. The maximum size supported for all the tags in a table is 10 KB. For more information about tagging DynamoDB resources and tagging restrictions, see [ Tagging resources in DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.Operations.html) and [Tagging restrictions in DynamoDB](Tagging.md#TaggingRestrictions).

For more information about using tags to control access to AWS resources, see the following topics in the IAM User Guide:
+ [What is ABAC for AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html)
+ [Controlling access to AWS resources using tags](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html)

Using ABAC, you can enforce different access levels for your teams and applications to perform actions on DynamoDB tables using fewer policies. You can specify a tag in the [condition element](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html) of an IAM policy to control access to your DynamoDB tables or indexes. These conditions determine the level of access an IAM principal, a user, or role, has to DynamoDB tables and indexes. When an IAM principal makes an access request to DynamoDB, the resource and identity’s tags are evaluated against the tag conditions in the IAM policy. Thereafter, the policy becomes effective only if tag conditions are met. This enables you to create an IAM policy that effectively says one of the following:
+ *Allow the user to manage only those resources that have a tag with a key `X` and a value `Y`*.
+ *Deny access to all users to resources tagged with a key `X`*.

For example, you can create a policy that allows users to update a table only if it has the tag key-value pair: `"environment": "staging"`. You can use the [aws:ResourceTag](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag) condition key to allow or deny access to a table based on the tags that are attached to that table.

You can include attribute-based conditions while creating the policy or later using the AWS Management Console, AWS API, AWS Command Line Interface (AWS CLI), AWS SDK, or AWS CloudFormation.

The following example allows the [UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) action on a table named `MusicTable` if it includes a tag key with the name `environment` and value `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**
+ [

## Why should I use ABAC?
](#why-use-abac)
+ [

## Condition keys to implement ABAC with DynamoDB
](#condition-keys-implement-abac)
+ [

## Considerations for using ABAC with DynamoDB
](#abac-considerations)
+ [

# Enabling ABAC in DynamoDB
](abac-enable-ddb.md)
+ [

# Using ABAC with DynamoDB tables and indexes
](abac-implementation-ddb-tables.md)
+ [

# Examples for using ABAC with DynamoDB tables and indexes
](abac-example-use-cases.md)
+ [

# Troubleshooting common ABAC errors for DynamoDB tables and indexes
](abac-troubleshooting.md)

## Why should I use ABAC?
<a name="why-use-abac"></a>
+ **Simpler policy management:** You use fewer policies because you don't have to create different policies to define the level of access for each IAM principal.
+ **Scalable access control:** Scaling access control is easier with ABAC because you don't have to update your policies when you create new DynamoDB resources. You can use tags to authorize access to IAM principals that contain tags matching the resource's tags. You can onboard new IAM principals or DynamoDB resources and apply appropriate tags to automatically grant the necessary permissions without having to make any policy changes.
+ **Fine-grained permission management:** It's a best practice to [grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) when you create policies. Using ABAC, you can create tags for the IAM principal, and use them to grant access to specific actions and resources that match the tags on the IAM principal. 
+ **Alignment with corporate directory:** You can map tags with existing employee attributes from your corporate directory to align your access control policies with your organizational structure.

## Condition keys to implement ABAC with DynamoDB
<a name="condition-keys-implement-abac"></a>

You can use the following condition keys in your AWS policies to control the level of access to your DynamoDB tables and indexes:
+ [aws:ResourceTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag): Controls access based on whether or not the tag key-value pair on a DynamoDB table or index matches the tag key and value in a policy. This condition key is relevant to all APIs that operate on an existing table or index.

  The `dynamodb:ResourceTag` conditions are evaluated as if you didn't attach any tags to a resource.
+ [aws:RequestTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag): Allows comparing the tag key-value pair that was passed in the request with the tag pair that you specify in the policy. This condition key is relevant to APIs that contain tags as part of the request payload. These APIs include [CreateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html) and [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): Compares the tag keys in a request with the keys that you specify in the policy. This condition key is relevant to APIs that contain tags as part of the request payload. These APIs include `CreateTable`, `TagResource`, and `UntagResource`.

## Considerations for using ABAC with DynamoDB
<a name="abac-considerations"></a>

When you use ABAC with DynamoDB tables or indexes, the following considerations apply:
+ Tagging and ABAC aren't supported for DynamoDB Streams.
+ Tagging and ABAC aren't supported for DynamoDB backups. To use ABAC with backups, we recommend that you use [AWS Backup](https://docs.aws.amazon.com/aws-backup/latest/devguide/whatisbackup.html).
+ Tags aren't preserved in restored tables. You need to add tags to restored tables before you can use tag-based conditions in your policies.

# Enabling ABAC in DynamoDB
<a name="abac-enable-ddb"></a>

For most of the AWS accounts, ABAC is enabled by default. Using the [DynamoDB console](https://console.aws.amazon.com/dynamodb/), you can confirm if ABAC is enabled for your account. To do this, make sure that you open the DynamoDB console with a role that has the [dynamodb:GetAbacStatus](#required-permissions-abac) permission. Then, open the **Settings** page of the DynamoDB console.

If you don’t see the **Attribute-based access control** card or if the card displays a status of **On**, it means ABAC is enabled for your account. However, if you see the **Attribute-based access control** card with a status of **Off**, as shown in the following image, ABAC isn’t enabled for your account.

## Attribute-based access control – not enabled
<a name="abac-disabled-image"></a>

![\[Settings page on the DynamoDB console that shows the Attribute-based access control card.\]](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/images/ddb-console-settings-page.png)


ABAC isn't enabled for AWS accounts for which tag-based conditions specified in their identity-based policies or other policies still need to be audited. If ABAC isn't enabled for your account, the tag-based conditions in your policies that are intended to act on DynamoDB tables or indexes are evaluated as if no tags are present for your resources or API requests. When ABAC is enabled for your account, the tag-based conditions in the policies of your account are evaluated considering the tags attached to your tables or API requests.

To enable ABAC for your account, we recommend that you first audit your policies as described in the [Policy audit](#policy-audit-for-abac) section. Then, include the [required permissions for ABAC](#required-permissions-abac) in your IAM policy. Finally, perform the steps described in [Enabling ABAC in console](#abac-enable-console) to enable ABAC for your account in the current Region. After you enable ABAC, you can opt out within the next seven calendar days of opting in.

**Topics**
+ [

## Auditing your policies before enabling ABAC
](#policy-audit-for-abac)
+ [

## IAM permissions required to enable ABAC
](#required-permissions-abac)
+ [

## Enabling ABAC in console
](#abac-enable-console)

## Auditing your policies before enabling ABAC
<a name="policy-audit-for-abac"></a>

Before you enable ABAC for your account, audit your policies to confirm that the tag-based conditions which might exist in the policies within your account are set up as intended. Auditing your policies will help avoid surprises from authorization changes with your DynamoDB workflows after ABAC is enabled. To view examples of using attribute-based conditions with tags, and the before and after behavior of ABAC implementation, see [Examples for using ABAC with DynamoDB tables and indexesExample use cases](abac-example-use-cases.md).

## IAM permissions required to enable ABAC
<a name="required-permissions-abac"></a>

You need the `dynamodb:UpdateAbacStatus` permission to enable ABAC for your account in the current Region. To confirm if ABAC is enabled for your account, you must also have the `dynamodb:GetAbacStatus` permission. With this permission, you can view the ABAC status for an account in any Region. You need these permissions in addition to the permission needed for accessing the DynamoDB console.

The following IAM policy grants the permission to enable ABAC and view its status for an account in the current Region.

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

## Enabling ABAC in console
<a name="abac-enable-console"></a>

1. Sign in to the AWS Management Console and open the DynamoDB console at [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. From the top navigation pane, choose the Region for which you want to enable ABAC.

1. On the left navigation pane, choose **Settings**.

1. On the **Settings** page, do the following:

   1. In the **Attribute-based access control** card, choose **Enable**.

   1. In the **Confirm attribute-based access control setting** box, choose **Enable** to confirm your choice.

      This enables ABAC for the current Region and the **Attribute-based access control** card shows the status of **On**.

      If you want to opt out after enabling ABAC on the console, you can do so within the next seven calendar days of opting in. To opt out, choose **Disable** in the **Attribute-based access control** card on the **Settings** page.
**Note**  
Updating the status of ABAC is an asynchronous operation. If the tags in your policies aren't evaluated right away, you might need to wait for some time because the application of the changes is eventually consistent.

# Using ABAC with DynamoDB tables and indexes
<a name="abac-implementation-ddb-tables"></a>

The following steps show how to set up permissions using ABAC. In this example scenario, you'll add tags to a DynamoDB table and create an IAM role with a policy that includes tag-based conditions. Then, you'll test the allowed permissions on the DynamoDB table by matching the tag conditions.

**Topics**
+ [

## Step 1: Add tags to a DynamoDB table
](#abac-add-table-tags)
+ [

## Step 2: Create an IAM role with a policy including tag-based conditions
](#abac-create-iam-role)
+ [

## Step 3: Test allowed permissions
](#abac-test-permissions)

## Step 1: Add tags to a DynamoDB table
<a name="abac-add-table-tags"></a>

You can add tags to new or existing DynamoDB tables using the AWS Management Console, AWS API, AWS Command Line Interface (AWS CLI), AWS SDK, or AWS CloudFormation. For example, the following [tag-resource](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/tag-resource.html) CLI command adds a tag to a table named `MusicTable`.

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

## Step 2: Create an IAM role with a policy including tag-based conditions
<a name="abac-create-iam-role"></a>

[Create an IAM policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html#access_policies_create-json-editor) using the [aws:ResourceTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag) condition key to compare the tag key-value pair that's specified in the IAM policy with the key-value pair that's attached to the table. The following example policy allows users to put or update items in tables if these tables contain the tag key-value pair: `"environment": "staging"`. If a table doesn't have the specified tag key-value pair, these actions are denied.

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

****  

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

------

## Step 3: Test allowed permissions
<a name="abac-test-permissions"></a>

1. Attach the IAM policy to a test user or role in your AWS account. Make sure that the IAM principal you use doesn’t already have access to the DynamoDB table through a different policy.

1. Make sure that your DynamoDB table contains the `"environment"` tag key with a value of `"staging"`.

1. Perform the `dynamodb:PutItem` and `dynamodb:UpdateItem` actions on the tagged table. These actions should succeed if the `"environment": "staging"` tag key-value pair is present.

   If you perform these actions on a table that doesn’t have the `"environment": "staging"` tag key-value pair, your request will fail with an `AccessDeniedException`.

You can also review the other [sample use cases](abac-example-use-cases.md) described in the following section to implement ABAC and perform more tests.

# Examples for using ABAC with DynamoDB tables and indexes
<a name="abac-example-use-cases"></a>

The following examples depict some use cases to implement attribute-based conditions using tags.

**Topics**
+ [

## Example 1: Allow an action using aws:ResourceTag
](#abac-allow-example-resource-tag)
+ [

## Example 2: Allow an action using aws:RequestTag
](#abac-allow-example-request-tag)
+ [

## Example 3: Deny an action using aws:TagKeys
](#abac-deny-example-tag-key)

## Example 1: Allow an action using aws:ResourceTag
<a name="abac-allow-example-resource-tag"></a>

Using the `aws:ResourceTag/tag-key` condition key, you can compare the tag key-value pair that's specified in an IAM policy with the key-value pair that's attached in a DynamoDB table. For example, you can allow a specific action, such as [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html), if the tag conditions match in an IAM policy and a table. To do this, perform the following steps:

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

1. Create a table. The following example uses the [create-table](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html) AWS CLI command to create a table named `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. Add a tag to this table. The following [tag-resource](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/tag-resource.html) AWS CLI command example adds the tag key-value pair `Title: ProductManager` to the `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. Create an [inline policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies) and add it to a role which has the [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS managed policy attached to it, as shown in the following example.

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

****  

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

------

   This policy allows the `PutItem` action on the table when the tag key and value attached to the table matches with the tags specified in the policy.

1. Assume the role with the policies described in Step 3.

1. Use the [put-item](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/put-item.html) AWS CLI command to put an item to the `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. Scan the table to verify if the item was added to the table.

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

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

1. Create a table. The following example uses the [CreateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html) API to create a table named `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. Add a tag to this table. The [TagResource](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TagResource.html) API in the following example adds the tag key-value pair `Title: ProductManager` to the `myMusicTable`.

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

1. Create an [inline policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies) and add it to a role which has the [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS managed policy attached to it, as shown in the following example.

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

****  

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

------

   This policy allows the `PutItem` action on the table when the tag key and value attached to the table matches with the tags specified in the policy.

1. Assume the role with the policies described in Step 3.

1. Use the [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) API to put an item to the `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. Scan the table to verify if the item was added to the table.

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

------
#### [ Using the AWS SDK for Python (Boto3) ]

1. Create a table. The following example uses the [CreateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html) API to create a table named `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. Add a tag to this table. The [TagResource](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TagResource.html) API in the following example adds the tag key-value pair `Title: ProductManager` to the `myMusicTable`.

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

1. Create an [inline policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies) and add it to a role which has the [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS managed policy attached to it, as shown in the following example.

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

****  

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

------

   This policy allows the `PutItem` action on the table when the tag key and value attached to the table matches with the tags specified in the policy.

1. Assume the role with the policies described in Step 3.

1. Use the [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) API to put an item to the `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 the table to verify if the item was added to the table.

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

------

**Without ABAC**  
If ABAC isn't enabled for your AWS account, the tag conditions in the IAM policy and the DynamoDB table aren’t matched. Consequently, the `PutItem` action returns an `AccessDeniedException` because of the effect of the `AmazonDynamoDBReadOnlyAccess` policy.

```
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.
```

**With ABAC**  
If ABAC is enabled for your AWS account, the `put-item` action completes successfully and adds a new item to your table. This is because the inline policy on the table allows the `PutItem` action if the tag conditions in the IAM policy and the table match.

## Example 2: Allow an action using aws:RequestTag
<a name="abac-allow-example-request-tag"></a>

Using the [aws:RequestTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag) condition key, you can compare the tag key-value pair that's passed in your request with the tag pair that's specified in the IAM policy. For example, you can allow a specific action, such as `CreateTable`, using the `aws:RequestTag` if the tag conditions don't match. To do this, perform the following steps:

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

1. Create an [inline policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies) and add it to a role which has the [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/ReadOnlyAccess.html) AWS managed policy attached to it, as shown in the following example.

------
#### [ 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. Create a table that contains the tag key-value pair of `"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 AWS SDK for Python (Boto3) ]

1. Create an [inline policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies) and add it to a role which has the [AmazonDynamoDBReadOnlyAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBReadOnlyAccess.html) AWS managed policy attached to it, as shown in the following example.

------
#### [ 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. Create a table that contains the tag key-value pair of `"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'
           },
       ],
   )
   ```

------

**Without ABAC**  
If ABAC isn't enabled for your AWS account, the tag conditions in the inline policy and the DynamoDB table aren’t matched. Consequently, the `CreateTable` request fails and your table isn’t created.

```
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.
```

**With ABAC**  
If ABAC is enabled for your AWS account, your table creation request completes successfully. Because the tag key-value pair of `"Owner": "John"` is present in the `CreateTable` request, the inline policy allows the user `John` to perform the `CreateTable` action.

## Example 3: Deny an action using aws:TagKeys
<a name="abac-deny-example-tag-key"></a>

Using the [aws:TagKeys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys) condition key, you can compare the tag keys in a request with the keys that are specified in the IAM policy. For example, you can deny a specific action, such as `CreateTable`, using `aws:TagKeys` if a specific tag key is *not* present in the request. To do this, perform the following steps:

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

1. Add a [customer managed policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies) to a role which has the [AmazonDynamoDBFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBFullAccess.html) AWS managed policy attached to it, as shown in the following example.

------
#### [ 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. Assume the role to which the policy was attached, and create a table with the tag key `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 AWS SDK for Python (Boto3) ]

1. Add a [customer managed policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies) to a role which has the [AmazonDynamoDBFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBFullAccess.html) AWS managed policy attached to it, as shown in the following example.

------
#### [ 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. Assume the role to which the policy was attached, and create a table with the tag key `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'
           },
       ],
   )
   ```

------

**Without ABAC**  
If ABAC isn't enabled for your AWS account, DynamoDB doesn’t send the tag keys in the `create-table` command to IAM. The `Null` condition ensures that the condition evaluates to `false` if there are no tag keys in the request. Because the `Deny` policy doesn't match, the `create-table` command completes successfully.

**With ABAC**  
If ABAC is enabled for your AWS account, the tag keys passed in the `create-table` command are passed to IAM. The tag key `Title` is evaluated against the condition-based tag key, `CostCenter`, present in the `Deny` policy. The tag key `Title` doesn't match the tag key present in the `Deny` policy because of the `StringNotEquals` operator. Therefore, the `CreateTable` action fails and your table isn’t created. Running the `create-table` command returns an `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.
```

# Troubleshooting common ABAC errors for DynamoDB tables and indexes
<a name="abac-troubleshooting"></a>

This topic provides troubleshooting advice for common errors and issues that you might encounter while implementing ABAC in DynamoDB tables or indexes.

## Service-specific condition keys in policies result in an error
<a name="abac-troubleshooting-service-specific-keys"></a>

Service-specific condition keys aren't considered as valid condition keys. If you've used such keys in your policies, these will result in an error. To fix this issue, you must replace the service-specific condition keys with an appropriate [condition key to implement ABAC](attribute-based-access-control.md#condition-keys-implement-abac) in DynamoDB.

For example, say that you've used the `dynamodb:ResourceTag` condition key in an [inline policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#inline-policies) that performs the [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) request. Imagine that the request fails with an `AccessDeniedException`. The following example shows the erroneous inline policy with the `dynamodb:ResourceTag` condition key.

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

****  

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

------

To fix this issue, replace the `dynamodb:ResourceTag` condition key with `aws:ResourceTag`, as shown in the following example.

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

****  

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

------

## Unable to opt out of ABAC
<a name="abac-troubleshooting-unable-opt-out"></a>

If ABAC was enabled for your account through Support, you won't be able to opt out of ABAC through the DynamoDB console. To opt out, contact [Support](https://console.aws.amazon.com/support).

You can opt out of ABAC yourself *only if* the following are true:
+ You used the self-service way of [opting in through the DynamoDB console](abac-enable-ddb.md#abac-enable-console).
+ You're opting out within seven calendar days of opting in.