Open6

DynamoDB で細かいアクセス制御やりたい場合に読む資料

hassaku63hassaku63

DDB へのアクセス制御において、IAM ポリシーを使ってできること

  • テーブル(or LSI, GSI) の特定の項目/属性に対して ReadOnly の制約を付与する
  • Identity に基づき、テーブルの特定の属性に対する書き込みを許可する

これらは Conditions を使って記述可能

hassaku63hassaku63

特定のアイテム、あるいは属性に対して制御をかけられる、というのが驚いた(感想)

(1) PK ベースでアクセス制限を掛けることができる

Row ベースな制御のイメージがある

ユースケースはゲームデータを格納するテーブルにおいて、ユーザーが所有しないアイテムはアクセスできない(見えなくなる (=いないのと同じ扱い) のか、それとも Deny されるのか。おそらく後者のような気はする)

(2) 属性のサブセットのみがユーザーに見えるようにすることもできる

こっちは Column ベースの制御、というイメージ

アクセス要件に応じて、見えてほしくない属性がある場合にそれをマスクするような使い方になる?

これはユースケースのイメージから、Allow/Deny というよりは「隠す」のイメージが近い感じがする

hassaku63hassaku63

ケーススタディ

全ユーザーがプレイしたゲームのスコアを管理するテーブル。

PK = UserId, SK = GameTitle

アクセス要件:

  • 各ユーザーは自分に関するデータにのみアクセス可能
  • ゲームをプレイするユーザーは GameRole というロールに所属する必要がある

policy は

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAccessToOnlyItemsMatchingUserID",
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:BatchGetItem",
                "dynamodb:Query",
                "dynamodb:PutItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem",
                "dynamodb:BatchWriteItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:us-west-2:123456789012:table/GameScores"
            ],
            "Condition": {
                "ForAllValues:StringEquals": {
                    "dynamodb:LeadingKeys": [
                        "${www.amazon.com:user_id}"
                    ],
                    "dynamodb:Attributes": [
                        "UserId",
                        "GameTitle",
                        "Wins",
                        "Losses",
                        "TopScore",
                        "TopScoreDateTime"
                    ]
                },
                "StringEqualsIfExists": {
                    "dynamodb:Select": "SPECIFIC_ATTRIBUTES"
                }
            }
        }
    ]
}
hassaku63hassaku63

ForAllValues:StringEquals ... StringEquals のブロックに含まれる条件式を全部満たす場合

"dynamodb:LeadingKeys": [
    "${www.amazon.com:user_id}"
],

↑ Partition key が User id にマッチする場合のみアクセスできる。 "${www.amazon.com:user_id}" は substitution variable というらしい。詳しくは Using Web Identity Federation を参照とのこと

                    "dynamodb:Attributes": [
                        "UserId",
                        "GameTitle",
                        "Wins",
                        "Losses",
                        "TopScore",
                        "TopScoreDateTime"
                    ]

↑ 属性アクセスの制限を記述している

                "StringEqualsIfExists": {
                    "dynamodb:Select": "SPECIFIC_ATTRIBUTES"
                }

↑ アプリが明示的に要求する属性を指定しなければならない(?)。かつ、全部の属性へのアクセスは要求できないということらしい。

If you use dynamodb:Attributes, you must specify the names of all of the primary key and index key attributes for the table and any secondary indexes that are listed in the policy. Otherwise, DynamoDB can't use these key attributes to perform the requested action.

dynamodb:Attributes を使用する場合、Primary Key あるいは Index key に指定するキー属性は全部ポリシーに記述されている必要がある。そうしなかった場合、それらの(指定から漏れた)キーを使ったリクエストは失敗する。

hassaku63hassaku63

Specifying Conditions: Using Condition Keys

ざっくり見て、そのうちまとめる

  • dynamodb:LeadingKeys
  • dynamodb:Select
  • dynamodb:Attributes
  • dynamodb:ReturnValues
  • dynamodb:ReturnConsumedCapacity