I am trying to get fine-grained DynamoDB access working by assuming an IAM role using a policy to specify which rows my user can query, as per the documentation.
The problem is that the permissions I pass in when I assume the role do not appear to be getting applied.
My table has a single string hash key that is formatted {user-id}:{guid}
and a global index on the user-id
column.
The permission policy statement I want to apply looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:*"
],
"Resource": [
"arn:aws:dynamodb:*:*:table/my-dynamo-table"
],
"Condition": {
"ForAllValues:StringLike": {
"dynamodb: LeadingKeys": [
"leading-key:*"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"dynamodb:Query",
"dynamodb:GetItem"
],
"Resource": [
"arn:aws:dynamodb:*:*:table/my-dynamo-table/index/*"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb: LeadingKeys": [
"leading-key"
]
}
}
}
]
}
From the command line I assume my role like this:
aws sts assume-role
--role-arn arn:aws:iam::12345678:role/test-dynamodb-role
--role-session-name dynamo-cmd-line-test
--policy { \"Version\": \"2012-10-17\",\"Statement\": [{\"Effect\": \"Allow\",\"Action\": [\"dynamodb:*\"],\"Resource\": [\"arn:aws:dynamodb:*:*:table/my-dynamo-table\"],\"Condition\": {\"ForAllValues:StringLike\": {\"dynamodb: LeadingKeys\": [ \"leading-key:*\" ]}}},{\"Effect\": \"Allow\",\"Action\": [\"dynamodb:Query\", \"dynamodb:GetItem\"],\"Resource\": [\"arn:aws:dynamodb:*:*:table/my-dynamo-table/index/*\"],\"Condition\": {\"ForAllValues:StringEquals\": {\"dynamodb: LeadingKeys\": [ \"leading-key\" ]}}}] }
I save the returned credentials into my .aws/credentials
file under [temp-sts]
then I try to call dynamodb get-item
:
aws dynamodb get-item --table-name my-dynamo-table --key "{ \"Id\": { \"S\": \"leading-key:93be7f8b-7c13-4248-1b28-ad2cf92b237f\"}}" --profile temp-sts
As things stand, with the IAM role created but no policies attached to it in the AWS IAM console, I get an error:
An error occurred (AccessDeniedException) when calling the GetItem operation:
User: arn:aws:sts::12345678:assumed-role/test-dynamo-role/dynamo-cmd-line-test is not authorized to perform: dynamodb:GetItem
on resource: arn:aws:dynamodb:region-1:123454321:table/my-dynamo-table
because no identity-based policy allows the dynamodb:GetItem action
In the AWS UI I can add a policy to the IAM role I am assuming to explicitly allow a GetItem action, but then it allows all queries, regardless of whether the leading-key
matches at all.
How can I apply the permissions in my sts assume-role
request policy to my assumed role?
After struggling with this for a lot longer I found the aws accessanalyzer validate-policy
tool (documented here), which finally let me track down the problem: "dynamodb: LeadingKeys"
should have been "dynamodb:LeadingKeys"
. With that resolved and a policy on the role being assumed to allow access to this dynamo database, I am able to assume the role and have queries limited to the correct subset of keys.