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

Last updated: 2020-09-03

How can I be sure that an AWS Identity and Access Management (IAM) user or role can access only specific attributes in an Amazon a DynamoDB table?

Short description

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

Resolution

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

  • dynamodb:LeadingKeys: Allow a user to access items that have a specific partition key value. Allow a user to access only items with a partition key value that matches a unique user ID (for example, ${www.amazon.com:user_id}).
  • dynamodb:Select: Allow a query or scan operation on an index to return a response only if the operation requests the index's projected attributes. Allow only operations that request item count rather than the actual items.
  • dynamodb:Attributes: Allow only requests that request specific attributes. For PutItem, allow requests only when the item has specific attributes in addition to the primary key and sort key attributes.
  • dynamodb:ReturnValues: For UpdateItem, allow only requests that have ReturnValues set to NONE (default) or UPDATED_OLD (returns updated attributes, as they appeared before the UpdateItem operation).
  • dynamodb:ReturnConsumedCapacity: Allow 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 these 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

Assume that you need to 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 should meet these criteria:

  • For query or scan API operations: Only allow requests 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: Only allow requests when the ProjectionExpression parameter contains UserId, GameTitle, TopScore, or TopScoreDateTime.

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

The 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, 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.


Did this article help?


Do you need billing or technical support?