Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use DynamoDB fine grained access control with Cognito User Pools?

I'm having trouble understanding how to use fine-grained access control on DynamoDB when logged in using Cognito User Pools. I've followed the docs and googled around, but for some reason I can't seem to get it working.

My AWS setup is listed below. If I remove the condition in the role policy, I can get and put items no problem, so it seems likely that the condition is the problem. But I can't figure out how or where to debug policies that depend on authenticated identities - what variables are available, what are their values, etc etc.

Any help would be greatly appreciated!

DynamoDB table

  • Table name: documents
  • Primary partition key: userID (String)
  • Primary sort key: docID (String)

DynamoDB example row

{
  "attributes": {},
  "docID": "0f332745-f749-4b1a-b26d-4593959e9847",
  "lastModifiedNumeric": 1470175027561,
  "lastModifiedText": "Wed Aug 03 2016 07:57:07 GMT+1000 (AEST)",
  "type": "documents",
  "userID": "4fbf0c06-03a9-4cbe-b45c-ca4cd0f5f3cb"
}

Cognito User Pool User

  • User Status: Enabled / Confirmed
  • MFA Status: Disabled
  • sub: 4fbf0c06-03a9-4cbe-b45c-ca4cd0f5f3cb
  • email_verified: true

Role policy for "RoleName"

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:PutItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:ap-southeast-2:NUMBER:table/documents"
            ],
            "Condition": {
                "ForAllValues:StringEquals": {
                    "dynamodb:LeadingKeys": [
                        "${cognito-identity.amazonaws.com:sub}"
                    ]
                }
            }
        }
    ]
}

Login information returned from cognitoUser.getUserAttributes()

attribute sub has value 4fbf0c06-03a9-4cbe-b45c-ca4cd0f5f3cb
attribute email_verified has value true
attribute email has value ****@****com

Error message

Code: "AccessDeniedException"
Message: User: arn:aws:sts::NUMBER:assumed-role/ROLE_NAME/CognitoIdentityCredentials is not authorized to perform: dynamodb:GetItem on resource: arn:aws:dynamodb:ap-southeast-2:NUMBER:table/documents
like image 320
abbm Avatar asked Aug 02 '16 22:08

abbm


1 Answers

The policy variable "${cognito-identity.amazonaws.com:sub}" is not the user sub which you get from Cognito user pools. It is in fact the identity id of a user which is generated by the Cognito Federated Identity service when you federate a user from Cognito User Pools with Federated identity service.

Since, the value in "${cognito-identity.amazonaws.com:sub}" never matches what you have in your DynamoDB row, it fails with AccessDenied. For this to work, the userId in your Dynamo entry should actually be the identity id, not sub. Currently, there is no direct link between IAM policy variables and Cognito User Pools service.

Here are some doc links which might help.
1. IAM roles with Cognito Federated Identity Service
2. Integrating User Pools with Cognito Federated Identity Service

like image 56
Chetan Mehta Avatar answered Oct 16 '22 18:10

Chetan Mehta