How can I restrict an IAM user or role to specific attributes in a DynamoDB table?

4 minute read
0

I want to make sure that an AWS Identity and Access Management (IAM) entity can access only specific attributes in an Amazon DynamoDB table.

Resolution

Use IAM policy conditions for fine-grained access control. Fine-grained access control lets you control access to individual items or item attributes for both read and write operations in a DynamoDB table.

Use predefined AWS keys and DynamoDB keys to specify conditions in an access policy. Here are some examples of common use cases for DynamoDB condition keys:

  • dynamodb:LeadingKeys: Allows a user to access items that have a specific partition key value. Allows a user to access only items with a partition key value that matches a unique user ID.
    For example, you can use a substitution variable, such as ${www.amazon.com:user_id}. For more information on substitution variables, see Using web identity federation.
    Note: You can also use ''dynamodb:LeadingKeys'': ["${aws:PrincipalArn}"] to match with the role's ARN Example: arn:aws:iam::Account-ID:role/myRole and "dynamodb:LeadingKeys": ["${aws:userid}"] to match with role-id:caller-specified-role-name. For information on using aws:userid for other principals, see Request information that you can use for policy variables.
  • dynamodb:Select: Allows a query or scan operation on an index to return a response only if the operation requests the index's projected attributes. Allows only operations that request item count rather than the actual items.
  • dynamodb:Attributes: Allows only requests that request specific attributes. For PutItem, allows requests only when the item has specific attributes in addition to the primary key and sort key attributes.
  • dynamodb:ReturnValues: For UpdateItem, allows only requests that have ReturnValues set to NONE (default) or UPDATED_OLD (returns updated attributes, as they appear before the UpdateItem operation).
  • dynamodb:ReturnConsumedCapacity: Allows only requests that have ReturnConsumedCapacity set to NONE or requests that don't specify ReturnConsumedCapacity.

Example: Allow read-only access to certain attributes of a table's items

The table in this example has the following properties:

  • Table name: GameScores
  • Primary partition key: a string with a UserId attribute
  • Primary sort key: a string with a GameTitle attribute
  • Non-key attributes: PersonalDetails, Wins, Losses, TopScore, TopScoreDateTime

You allow a third-party application to read the TopScore and TopScoreDateTime attributes for each user. Because UserId and GameTitle are the partition and sort key attributes, you must also allow these attributes in the IAM policy. The example policy must meet the following criteria:

  • For query or scan API operations: Allow requests only when the Select parameter is set to SPECIFIC_ATTRIBUTES or when ProjectionExpression contains UserId, GameTitle, TopScore, or TopScoreDateTime.
  • For GetItem, BatchGetItem, and TransactGetItem API operations: Allow requests only when the ProjectionExpression parameter contains UserId, GameTitle, TopScore, or TopScoreDateTime.

Note: If the application is reading a secondary index for this table, then the policy must allow the partition and sort keys for secondary index.

The following example IAM policy uses the dynamodb:Attributes condition key:

{
    "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"
                }
            }
        }
    ]
}

The client's requests must specify the allowed attributes. If the requests don't specify attributes, then DynamoDB tries to return all attributes. Because the IAM policy doesn't allow the client to read all attributes, the client gets an AccessDeniedException.

Here's an example of a query request that returns an AccessDeniedException because it doesn't use Select or ProjectionExpression to specify allowed attributes:

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

Here's an example of a successful query request that specifies the TopScore, TopScoreDateTime, and GameTitle attributes:

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

Here's an example of a successful GetItem request:

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

For another example of how to use condition keys to limit access, see Permissions use case.


Related information

Fine-grained access control for Amazon DynamoDB

Amazon DynamoDB API reference

AWS OFFICIAL
AWS OFFICIALUpdated 2 years ago