- Newest
- Most votes
- Most comments
I have been digging for a while about this too.
There were 2 prerequisites that I hadn't fulfilled which were:
- Enabling default mappings in the identity provider of the identity pool. This maps the Tag key of 'username' to 'sub'
- The trust relationship of the role you are assuming must have the action 'sts:TagSession'. I believe this allows the attributes we are checking to be passed through. I still have more to understand about this part and why it is essential.
This left my policy with a statement like:
{
"Action": [
"dynamodb:UpdateItem",
"dynamodb:Query",
"dynamodb:PutItem",
"dynamodb:GetItem",
"dynamodb:DeleteItem"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": "${aws:PrincipalTag/username}"
}
},
"Effect": "Allow",
"Resource": "*"
}
With my trust policy like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": ['sts:AssumeRoleWithWebIdentity', 'sts:TagSession'],
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:my-identity-pool"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
If you are using CDKTF like I am, you need to create a CognitoIdentityPoolProviderPrincipalTag, which is where attribute mapping can be done. In console, got to your Identity Pool -> User Access -> Identity Providers and ensure you have the default mappings enabled. This lets you use the aws:PrincipalTag/username
to match on the users sub
Hopefully this helps! Good luck.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html https://stackoverflow.com/questions/56801845/iam-policy-cognito-variables-for-dynamodb-leadingkeys-restriction
To implement fine-grained access control for DynamoDB using Amazon Cognito, you need to understand a few key concepts:
-
LeadingKeys: This refers to the partition key of your DynamoDB table. It's called "leading" because it's the primary key that DynamoDB uses to partition data.
-
Cognito Identity ID vs. User Pool sub: While you can use either, the Cognito Identity ID is generally preferred for fine-grained access control because it can handle both authenticated and unauthenticated users.
To set up fine-grained access:
-
Structure your DynamoDB table: Ensure your table uses the Cognito Identity ID as the partition key.
-
Set up IAM policy: Create a policy that allows actions on the DynamoDB table, but only when the LeadingKeys match the user's Cognito Identity ID.
Here's an example policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:DeleteItem", "dynamodb:Query" ], "Resource": "arn:aws:dynamodb:REGION:ACCOUNT_ID:table/TABLE_NAME", "Condition": { "ForAllValues:StringEquals": { "dynamodb:LeadingKeys": [ "${cognito-identity.amazonaws.com:sub}" ] } } } ] }
This policy allows the specified DynamoDB actions, but only on items where the partition key matches the user's Cognito Identity ID.
- Attach the policy: Attach this policy to the IAM role associated with your Cognito Identity Pool.
When using this setup:
- Each user can only access their own data in the table.
- The condition ensures that a user can't write data with someone else's ID as the partition key.
- Queries and GetItem operations will only return results for the user's own data.
Remember, this approach requires your application to use the Cognito Identity ID as the partition key when writing to DynamoDB. Your application will need to retrieve this ID after user authentication and use it in DynamoDB operations.
This setup provides a secure way to implement per-user data isolation in DynamoDB using Cognito, addressing your need for fine-grained access control.
Sources
IAM roles - Amazon Cognito
Amazon DynamoDB: Allows item-level access to DynamoDB based on an Amazon Cognito ID - AWS Identity and Access Management
Enable fine-grained access control and observability for API operations in Amazon DynamoDB | AWS Database Blog
Using IAM policy conditions for fine-grained access control - Amazon DynamoDB
Relevant content
- asked 3 years ago
Ok, so leadingkeys (plural) means only one key and that's the partitionkey (which makes sense in hindsight, but not at all clear in the documentation... I was expecting to be able to use an index... i.e. any of the keys, but that's not the case). It also doesn't seem to have to be named anything specific except for the fact that its the partitionkey.
Now if I have a complex partitionkey like [RECORDID][USERID][someotherthing], can I map the leadingkeys into that, or does the partitionkey have to be exactly and only whatever the leadingkeys field points to?
For Queries, do I have to explicitly specify the userid (leadingkeys/primarykey)? That's more of a performance question.
Also, did AI just produce an actual and helpful answer? I'm sold!