IAM Policy Cognito Variables for DynamoDB LeadingKeys Restriction

1

My setup:

  • Mobile App
  • Cognito User Pool
  • Api Gateway
  • DynamoDB

What I got working so far:
The User can sign up/in with the Cognito User Pool and get an Id and AccessToken.
The IdToken is used with the Api Gateway Cognito Authorizer to access the Api Gateway.
The Mapping of the user sub into the integration message to DynamoDb works.

"userId": {
    "S": "$context.authorizer.claims.sub"
}

Restricting the access to non user rows in a DynamoDb Table does not work.
The DynamoDb tables were created using Mobile Hubs Protected Table feature, which creates the following policy:

            "Condition": {
                "ForAllValues:StringEquals": {
                    "dynamodb:LeadingKeys": [
                        "${cognito-identity.amazonaws.com:sub}"
                    ]
                }
            }

But thats not working, because this expression returns the Identity User Id and NOT the User Pool Sub. At first I'm not using Identity Pools and second I want to use the User Sub here.

I found out

${cognito-idp.<REGION>.amazonaws.com/<POOL-ID>:sub}

should do the trick, but thats not working too.

If I hardcode the Condition to use the Sub of my test user, everything works as expected, so the Policy itself is okay, it's only the expression to get the sub of the current user is not working correctly.

Any Ideas, hints, suggestions?

Thanks in advance.

Edited by: TheCutter on Jun 27, 2019 11:23 PM

BTW: Is there any way to debug a IAM Policy to see what the value of an expression/variable is like?

Edited by: TheCutter on Jun 27, 2019 11:25 PM

asked 5 years ago910 views
5 Answers
1

First, for you to be able to limit access to a leading key in a Dynamo table, you need AWS credentials for a specific end user. The easiest way is to get credentials for your user pools end user is to integrate your Cognito User Pool with Cognito Identity Pools https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-integrating-user-pools-with-identity-pools.html If you do this, you will be able to use ${cognito-identity.amazonaws.com:sub} in your role policy. Note that the sub will not be the sub of the user in Cognito User Pools, but the identity id of the identity the end user is associated with in Cognito Identity Pools.

However, you are asking about the sub for the Cognito User Pool user. Let us send you a private message to see if we can find an alternative that works. Will post back if we have a general solution.

AWS
answered 4 years ago
  • hello, have you found a solution to access the sub attribute of the user in the user pool? I need this variable to update my IoT resource policy.

0

Looks like it's not an easy topic...

answered 5 years ago
0

I got the answer now. You are only able to use the
${cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXXXXX:sub}
variable if you configure the Cognito User Pool as an open ID Connect provider directly against IAM.

But there is a big problem, because you need to update the SSL Thumbprint of the service endpoint if the certificate changes in the Open ID Connector configuration. But you are not able to tell when the aws certificate has changed.

answered 4 years ago
0

Its been 3 years since this question was asked...do we have a good clean solution for this yet?

kevlar
answered 2 years ago
0

If you want to use the user pool sub value as a partition key, you can map it to a principal tag in the identity pool. In the identity pool, go to User access -> Identity providers. In the Mappings section, choose Custom mapping. Enter a name for the tag key, e.g., userId, and enter sub for the claim. Then you can use it in the role's policy like this:

"Condition": {
  "ForAllValues:StringEquals": {
    "dynamodb:LeadingKeys": [
      "${aws:PrincipalTag/userId}"
     ]
   }
}

Alternatively, you can use the policy in the question with "${cognito-identity.amazonaws.com:sub}". As written above it's the user's ID in the identity pool. You can get this ID by calling the GetId endpoint in Identity Pools. The payload will contain the identity pool ID and, if the user is authenticated, the Logins property, which consists of the user pool id and the ID token the user receives after signing in. You'll get an IdentityId in the response, and this value should be the partition key in the table.

arpadt
answered 8 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions