

# DynamoDB의 속성 기반 액세스 제어 사용
<a name="attribute-based-access-control"></a>

[속성 기반 액세스 제어(ABAC)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html)는 ID 기반 정책 또는 기타 AWS 정책(예: 리소스 기반 정책 및 조직 IAM 정책)의 [태그 조건](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tagging.html)을 기반으로 액세스 권한을 정의하는 권한 부여 전략입니다. DynamoDB 테이블에 태그를 연결하면 태그 기반 조건을 기준으로 평가됩니다. 테이블과 연결된 인덱스는 테이블에 추가하는 태그를 상속합니다. 각 DynamoDB 테이블에 최대 50개의 태그를 추가할 수 있습니다. 테이블의 모든 태그에 지원되는 최대 크기는 10KB입니다. 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 테이블 또는 인덱스에 대한 액세스를 제어할 수 있습니다. 이러한 조건은 DynamoDB 테이블 및 인덱스에 대해 IAM 위탁자, 사용자 또는 역할이 가진 액세스 수준을 결정합니다. IAM 위탁자가 DynamoDB에 액세스 요청을 하면 리소스 및 ID의 태그가 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 Management Console, AWS API, AWS Command Line Interface(AWS CLI), AWS SDK 또는 AWS CloudFormation을 사용하여 정책을 만드는 동안 속성 기반 조건을 포함할 수 있습니다.

다음 예제에서는 `MusicTable`이라는 테이블에 이름이 `environment`, 값이 `production`인 태그 키가 포함된 경우 [UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) 작업을 허용합니다.

------
#### [ 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)
+ [DynamoDB 테이블 및 인덱스와 함께 ABAC를 사용하는 예제](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 위탁자용 태그를 만들고 이를 사용하여 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 스트림에는 태그 지정 및 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/ko_kr/amazondynamodb/latest/developerguide/images/ddb-console-settings-page.png)


ID 기반 정책 또는 기타 정책에 지정된 태그 기반 조건을 여전히 감사해야 하는 AWS 계정에는 ABAC가 활성화되지 않습니다. 계정에 ABAC가 활성화되지 않은 경우 DynamoDB 테이블 또는 인덱스에 적용되도록 의도된 정책의 태그 기반 조건은 리소스 또는 API 요청에 태그가 없는 것처럼 평가됩니다. 계정에 ABAC가 활성화되면 테이블 또는 API 요청에 연결된 태그를 고려하여 계정 정책의 태그 기반 조건이 평가됩니다.

계정에 ABAC를 활성화하려면 먼저 [감사 정책](#policy-audit-for-abac) 섹션에 설명된 대로 정책을 감사하는 것이 좋습니다. 그런 다음 IAM 정책에 [ABAC에 필요한 권한](#required-permissions-abac)을 포함합니다. 마지막으로 [콘솔에서 ABAC 활성화](#abac-enable-console)에 설명된 단계를 수행하여 현재 리전의 계정에 ABAC를 활성화합니다. ABAC를 활성화하여 옵트인한 후 7일 이내에 옵트아웃할 수 있습니다.

**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 구현 전후의 동작을 보려면 [DynamoDB 테이블 및 인덱스와 함께 ABAC를 사용하는 예제사용 사례 예제](abac-example-use-cases.md) 섹션을 참조하세요.

## ABAC를 활성화하는 데 필요한 IAM 권한
<a name="required-permissions-abac"></a>

현재 리전의 계정에 ABAC를 활성화하려면 `dynamodb:UpdateAbacStatus` 권한이 필요합니다. 계정에 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 Management Console에 로그인하고 DynamoDB 콘솔([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/))을 엽니다.

1. 상단 탐색 창에서 ABAC를 활성화할 리전을 선택합니다.

1. 왼쪽 탐색 창에서 **설정**을 선택합니다.

1. **설정** 페이지에서 다음 작업을 수행합니다.

   1. **속성 기반 액세스 제어** 카드에서 **활성화**를 선택합니다.

   1. **속성 기반 액세스 제어 설정 확인** 상자에서 **활성화**를 선택하여 선택을 확인합니다.

      이렇게 하면 현재 리전에 대한 ABAC가 활성화되고 **속성 기반 액세스 제어** 카드에 **켜짐** 상태가 표시됩니다.

      콘솔에서 ABAC를 활성화한 후 옵트아웃하려면 옵트인 후 7일 이내에 옵트아웃할 수 있습니다. 옵트아웃하려면 **설정** 페이지의 **속성 기반 액세스 제어** 카드에서 **비활성화**를 선택합니다.
**참고**  
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 Management Console, AWS API, AWS Command Line Interface(AWS CLI), AWS SDK 또는 AWS CloudFormation을 사용하여 새 DynamoDB 테이블 또는 기존 DynamoDB 테이블에 태그를 추가할 수 있습니다. 예를 들어 다음 [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) IAM 정책에 지정된 태그 키-값 페어를 테이블에 연결된 키-값 페어와 비교합니다. 다음 예제 정책은 사용자가 테이블에 태그 키-값 페어 `"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. AWS 계정의 테스트 사용자 또는 역할에 IAM 정책을 연결합니다. 사용하는 IAM 위탁자가 다른 정책을 통해 DynamoDB 테이블에 이미 액세스할 수 없는지 확인합니다.

1. DynamoDB 테이블에 값이 `"staging"`인 `"environment"` 태그 키가 포함되어 있는지 확인합니다.

1. 태그가 지정된 테이블에서 `dynamodb:PutItem` 및 `dynamodb:UpdateItem` 작업을 수행합니다. `"environment": "staging"` 태그 키-값 페어가 있는 경우 이러한 작업이 성공합니다.

   `"environment": "staging"` 태그 키-값 페어가 없는 테이블에서 이러한 작업을 수행하면 `AccessDeniedException`과 함께 요청이 실패합니다.

다음 섹션에 설명된 다른 [샘플 사용 사례](abac-example-use-cases.md)를 검토하여 ABAC를 구현하고 추가 테스트를 수행할 수도 있습니다.

# DynamoDB 테이블 및 인덱스와 함께 ABAC를 사용하는 예제
<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 AWS SDK for Python (Boto3) ]

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이 없는 경우**  
AWS 계정에 ABAC가 활성화되지 않은 경우 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가 있는 경우**  
AWS 계정에 ABAC가 활성화된 경우 `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 AWS SDK for Python (Boto3) ]

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이 없는 경우**  
AWS 계정에 ABAC가 활성화되지 않은 경우 인라인 정책 및 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가 있는 경우**  
AWS 계정에 ABAC가 활성화된 경우 테이블 만들기 요청이 성공적으로 완료됩니다. 태그 키-값 쌍 `"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 정책에 지정된 키와 비교할 수 있습니다. 예를 들어 요청에 특정 태그 키가 *없는* 경우 `aws:TagKeys`를 사용하여 `CreateTable`과 같은 특정 작업을 거부할 수 있습니다. 이렇게 하려면 다음 단계를 수행하세요.

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

1. 다음 예제와 같이 [AmazonDynamoDBFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBFullAccess.html) AWS 관리형 정책이 연결된 역할에 [고객 관리형 정책](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies)을 추가합니다.

------
#### [ 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 AWS SDK for Python (Boto3) ]

1. 다음 예제와 같이 [AmazonDynamoDBFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonDynamoDBFullAccess.html) AWS 관리형 정책이 연결된 역할에 [고객 관리형 정책](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies)을 추가합니다.

------
#### [ 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이 없는 경우**  
AWS 계정에 ABAC가 활성화되지 않은 경우 DynamoDB는 `create-table` 명령의 태그 키를 IAM으로 전송하지 않습니다. `Null` 조건은 요청에 태그 키가 없는 경우 조건이 `false`로 평가되도록 합니다. `Deny` 정책이 일치하지 않으므로 `create-table` 명령이 성공적으로 완료됩니다.

**ABAC가 있는 경우**  
AWS 계정에 ABAC가 활성화된 경우 `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)에 문의하세요.

다음과 같은 *경우에만* ABAC를 직접 옵트아웃할 수 있습니다.
+ [DynamoDB 콘솔을 통해 옵트인](abac-enable-ddb.md#abac-enable-console)하는 셀프 서비스 방법을 사용했습니다.
+ 옵트인 후 7일 이내에 옵트아웃합니다.