AnomalyInnovations / serverless-stack-demo-api

Source for the demo app API in the Serverless Stack Guide
https://demo.serverless-stack.com
MIT License
518 stars 197 forks source link

Assume Cognito Identity Auth role with DynamoDB with client/AWS_IAM auth? #38

Open fostahgix opened 4 years ago

fostahgix commented 4 years ago

Hello,

I am trying to assume my identity pool user auth role when invoking my AWS REST API requests. I followed the same code setup for declaring my authentication pools/identity pools. The only change is I modified the Cognito Authenticated role to include permissions to access DynamoDB resources.

My cognito authenticated identity role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "cognito-identity:*",
                "dynamodb:PutItem",
                "dynamodb:DeleteItem",
                "dynamodb:GetItem",
                "mobileanalytics:PutEvents",
                "dynamodb:Scan",
                "dynamodb:Query",
                "dynamodb:UpdateItem",
                "cognito-sync:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:xxxx:xxxx/*"
        }
    ]
}

Using the serverless-stack-demo-client, I log in and I see it obtained the identity id and credentials.

My request.context.identity:

identity: {
      cognitoIdentityPoolId: 'us-east-1:xxxx',
      accountId: 'xxxx',
      cognitoIdentityId: 'us-east-xxx',
      caller: 'xxx:CognitoIdentityCredentials',
      sourceIp: 'xxx.x.xx.x.',
      principalOrgId: 'o-xxxx',
      accessKey: 'xxxxxxx',
      cognitoAuthenticationType: 'authenticated',
      cognitoAuthenticationProvider: 'cognito-idp.us-east-1.amazonaws.com/xxxxx,cognito-idp.us-east-1.amazonaws.com/us-east-xxx:CognitoSignIn:xxx-xxx-xx',
      userArn: 'arn:aws:sts::xxxx:assumed-role/CognitoAuthRole-xxx/CognitoIdentityCredentials',
      userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
      user: 'xxxx:CognitoIdentityCredentials'
    },

Using the API from aws-amplify, I make a request, much like the notes list example. It sets the auth header as:

authorization: AWS4-HMAC-SHA256 Credential=xxxxx/20200729/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=xxxxxxxxx

In my cloudwatch response, I see the following error:

error: "User: arn:aws:sts::xxxx:assumed-role/example-us-east-1-lambdaRole/example-rest-api-dev-getProducts is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:xxxx:table/products-table"

My assumption is that it should be using the assumed role from the userArn specified above in the identity payload to make the request. However, it appears it is still using the lambda execution role instead still.

Am I missing a step here? Do I need to manually set it to assume the role in the requestContext.identity.userArn? I have tried just about everything to get this to work properly, but keep running into issues. Any help is appreciated!

WingedEmil commented 4 years ago

Did you find a solution to this? I've ran into a similair issue.

EDIT: Disregard. If I recall correctly, I had set the wrong region in my serverless.yml in relation to the region my DyanmoDB was on. Although it may not be helpful to this situation, it could be to someone who arrives here with a similair error message.

jayair commented 4 years ago

@fostahgix I might not be totally getting your setup but the flow here is that users are given permissions to access your API Gateway/Lambda functions. Once it hits that spot, the permissions are the ones that are given to that Lambda function. It's not based on the user anymore.