IAM ユーザーまたはロールを、DynamoDB テーブルにある特定の属性に制限するにはどうすればよいですか?

最終更新日: 2020 年 9 月 3 日

AWS Identity and Access Management (IAM) のユーザーまたはロールが、Amazon DynamoDB テーブルにおける特定の属性にのみ、アクセスできるようにするにはどうすればよいですか?

簡単な説明

きめ細かなアクセスコントロール(FGAC)のための IAM ポリシー条件を使用します。FGAC を使用することで、DynamoDB テーブルでの読み取りと書き込み操作の両方について、個々の項目、もしくは項目の属性へのアクセスを制御できるようになります。

解決方法

定義済みの AWS 全体のキーDynamoDB 固有のキー を使用すると、アクセスポリシー内で条件を指定できます。DynamoDB 条件キーに関する、一般的なユースケースの例を次に示します。

  • dynamodb:LeadingKeys: ユーザーが特定のパーティションキー値を持つ項目にアクセスできるようにします。ユーザーは、対象となる項目のパーティションキー値が、一意のユーザー ID と一致する場合のみにアクセスが可能になります(例: ${www.amazon.com:user_id})。
  • dynamodb:Select: インデックスに対する クエリ または スキャン オペレーションにおいて、そのインデックスの射影される属性が要求されている場合にのみ、応答を返すようにします。実際の項目ではなく、項目数を要求するオペレーションのみを許可します。
  • dynamodb:Attributes: 特定の属性を要求するリクエストのみを許可します。PutItem では、対象の項目が、プライマリキーおよびソートキーの属性に加えて特定の属性を持つ場合にのみ、リクエストを許可します。
  • dynamodb:ReturnValues: UpdateItem において、ReturnValuesNONE(デフォルト)であるか、UPDATED_OLD(UpdateItem オペレーション前に表示されていた更新済み属性を返す)に設定されているリクエストのみを許可します。
  • dynamodb:ReturnConsumedCapacity: ReturnConsumedCapacityNONE に設定されている、または、このプロパティが使用されていないリクエストのみを許可します。

例: テーブルの項目における特定の属性に対する、読み取り専用アクセスを許可する

この例では、テーブルのプロパティを次のようにしています。

  • テーブル名: GameScores
  • プライマリパーティションキー: UserId 属性を持つ文字列を使用
  • プライマリソートキー:GameTitle 属性を持つ文字列を使用
  • 非キー属性: PersonalDetails、Wins、Losses、TopScore、TopScoreDateTime

たとえば、サードパーティアプリケーションに対し、各ユーザーの TopScore 属性と TopScoreDateTime 属性の読み取りを許可する必要があると仮定します。UserID と GameTitle はパーティションおよびソートキー属性であるため、IAM ポリシーでこれらの属性の読み取りも許可する必要があります。この例のポリシーでは、次の基準を満たしている必要があります。

  • クエリまたはスキャン API オペレーションの場合: Select パラメーターが SPECIFIC_ATTRIBUTES に設定されているリクエスト、または、ProjectionExpression に UserID、GameTitle、TopScore、またはTopScoreDateTime が含まれているリクエストのみを許可します。
  • GetItem、BatchGetItem、および TransactGetItem API オペレーションの場合: ProjectionExpression パラメーターに、UserId、GameTitle、TopScore、または TopScoreDateTime が含まれているリクエストのみを許可します。

注: アプリケーションが、テーブルのセカンダリインデックスを読み取る場合には、そのセカンダリインデックスのパーティションキーおよびソートキーも、ポリシーで許可している必要があります。

この例における IAM ポリシーでは、次のように dynamodb:Attributes 条件キーを使用しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "LimitAccessToSpecificAttributes",
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:Query",
                "dynamodb:BatchGetItem",
                "dynamodb:Scan",
                "dynamodb:TransactGetItems"
            ],
            "Resource": [
                "arn:aws:dynamodb:eu-west-1:123456789012:table/GameScores"
            ],
            "Condition": {
                "ForAllValues:StringEquals": {
                    "dynamodb:Attributes": [
                        "TopScoreDateTime",
                        "TopScore",
                        "UserId",
                        "GameTitle"
                    ]
                },
                "StringEquals": {
                    "dynamodb:Select": "SPECIFIC_ATTRIBUTES"
                }
            }
        }
    ]
}

クライアントのリクエストでは、許可された属性を指定する必要があります。リクエストが属性を指定していない場合には、DynamoDB はすべての属性を返そうとします。IAM ポリシーが、すべての属性の読み取りをクライアントに許可していないため、クライアントには AccessDeniedException が返されます。

次に示すのは、Select または ProjectionExpression を使用して許可された属性を指定していないため、AccessDeniedException が返されるクエリリクエストの例です。

$ aws dynamodb query --table-name GameScores --key-condition-expression "UserId = :useridval" --expression-attribute-values '{":useridval":{"S":"stefano_123"}}'

次に、TopScore、TopScoreDateTime、GameTitle の属性を指定しているため成功する、クエリリクエストの例を示します。

$ aws dynamodb query --table-name GameScores --key-condition-expression "UserId = :useridval" --expression-attribute-values '{":useridval":{"S":"stefano_123"}}' --projection-expression "TopScore, TopScoreDateTime, GameTitle"

成功する GetItem リクエストの例を次に示します。

$ aws dynamodb get-item --table-name GameScores --key '{"UserId":{"S":"stefano_123"},"GameTitle":{"S":"Game Zero"}}' --projection-expression "UserId, GameTitle, TopScore, TopScoreDateTime"

アクセス制限に条件キーを使用する別の例については、「 アクセス権限のユースケース」をご参照ください。