Reputation: 741
I have been referring to these blog articles from AWS to implement tenant data isolation in DynamoDB. I came up with the below IAM policy which is attached to the IAM Role going to be used to access the table I've created in DynamoDB.
{
"Version": "2012-10-17",
"Statement": [
{
"Condition": {
"ForAllValues:StringLike": {
"dynamodb:LeadingKeys": [
"tenant/t001/product/*"
]
}
},
"Action": "dynamodb:PutItem",
"Resource": "arn:aws:dynamodb:<REGION>:<ACCOUNT-NUMBER>:table/<TABLE-NAME>",
"Effect": "Allow"
},
{
"Condition": {
"ForAllValues:StringLike": {
"dynamodb:LeadingKeys": [
"tenant/t001/*"
]
}
},
"Action": "dynamodb:PutItem",
"Resource": "arn:aws:dynamodb:<REGION>:<ACCOUNT-NUMBER>:table/<TABLE-NAME>/index/<INDEX-NAME>",
"Effect": "Allow"
}
]
}
With this, I was denied access to perform PutItem on the table when the value I passed for the Partition Key (PartKey1) of the table's Primary Key is NOT following the pattern tenant/t001/product/*
. For example, I was denied access when I passed tenant/t002/product/p001
to PartKey1 as expected. Because I'm giving t002
as the tenant id, which should have been t001
to successfully perform PutItem.
But, it was not the same with the GSI. It simply accepts any value I pass into the Partition Key of the GSI (PartKey2).
Then I changed the dynamodb:PutItem
action to dynamodb:Query
ONLY in the second statement. So the new inline policy would look like this.
{
"Version": "2012-10-17",
"Statement": [
{
"Condition": {
"ForAllValues:StringLike": {
"dynamodb:LeadingKeys": [
"tenant/t001/product/*"
]
}
},
"Action": "dynamodb:PutItem",
"Resource": "arn:aws:dynamodb:<REGION>:<ACCOUNT-NUMBER>:table/<TABLE-NAME>",
"Effect": "Allow"
},
{
"Condition": {
"ForAllValues:StringLike": {
"dynamodb:LeadingKeys": [
"tenant/t001/*"
]
}
},
"Action": "dynamodb:Query",
"Resource": "arn:aws:dynamodb:<REGION>:<ACCOUNT-NUMBER>:table/<TABLE-NAME>/index/<INDEX-NAME>",
"Effect": "Allow"
}
]
}
With this change, I was denied access (as expected) when I tried to query the GSI with a value that doesn't follow the pattern tenant/t001/*
, for example, tenant/t002/product
.
I couldn't think of any reason why would AWS allow the use of dynamodb:LeadingKeys
(for a GSI) in conditions when it is dynamodb:Query
but not with dynamodb:PutItem
. Because why would we go into trouble of isolating tenant data in Query time, when we cannot isolate them during the insertion?
Am I missing something here?
AWS blog articles, documentations:
Upvotes: 1
Views: 679
Reputation: 23793
You can't PutItem
to GSI (or LSI) ...
So in your original policy
"Action": "dynamodb:PutItem",
"Resource": "arn:aws:dynamodb:<REGION>:<ACCOUNT-NUMBER>:table/<TABLE-NAME>/index/<INDEX-NAME>",
"Effect": "Allow"
Has zero effect...
Upvotes: 1