I'm trying to create a admin API using api gateway, lambda and dynamoDB. I want only the logged in users in certain group be able to access lambda.
I see that the lambda would not assume role of the cognito user and access the dynamoDB. API only works if I attach the dynamoDB policy to the LambdaRole.
Is there a way for this to work dynamically based on user groups. Do I need to add this assumeRole logic in the lambda handler itself ? Please help
This is the ERROR I get when I git my API from postman with Authorization tokens
{
"message": "User: arn:aws:sts::09723XXXXX357:assumed-role/tango-admin-lambda-role/tango-admin-service-dev-getActiveOrders is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:09723XXXXX357:table/dev-tango-service-tango-order-db",
"code": "AccessDeniedException",
"time": "2022-05-23T18:42:39.241Z",
"requestId": "DDK7AS6SBO8D0U3KXXXXXXXX",
"statusCode": 400,
"retryable": false,
"retryDelay": 46.2351059972586
}
Here is my serverless.yml file
service: tango-admin-service
provider:
name: aws
runtime: nodejs14.x
region: us-east-1
environment:
DYNAMODB_TABLE: ${opt:stage, self:provider.stage}-tango-service-tango-order-db
# functions
functions:
hello:
handler: src/handlers/hello.handler
events:
- http:
path: hello
method: get
getActiveOrders:
handler: src/handlers/getActiveOrders.handler
role: TangoAdminLambdaRole # How can this role be assume from Congito ? It only works if I directly pass the Role with DynamoDB Policy
events: # The events that trigger this function
- http:
path: get-active-orders
method: post
cors: true
authorizer:
type: COGNITO_USER_POOLS
authorizerId:
Ref: TangoAdminApiAuthorizer
# Serverless plugins
plugins:
- serverless-plugin-typescript
- serverless-offline
resources:
Resources:
TangoAdminCognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: TangoAdmin
TangoAdminCognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: TangoAdminWebApp
GenerateSecret: false
UserPoolId:
Ref: "TangoAdminCognitoUserPool"
TangoAdminGroup:
Type: AWS::Cognito::UserPoolGroup
Properties:
GroupName: "TangoAdmin"
Description: "Admin group for Tango"
Precedence: 0
RoleArn: !GetAtt CognitoAdminIAMRole.Arn
UserPoolId:
Ref: "TangoAdminCognitoUserPool"
CognitoAdminIAMRole:
Type: AWS::IAM::Role
Properties:
RoleName: "tango-admin-role"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Federated:
- "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Policies:
- PolicyName: "tango-admin-group-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "dynamodb:*"
Resource:
- "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
TangoAdminApiAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: TangoAdmin
RestApiId:
Ref: ApiGatewayRestApi
Type: COGNITO_USER_POOLS
ProviderARNs:
- Fn::GetAtt: [ TangoAdminCognitoUserPool, Arn ]
IdentitySource: method.request.header.Authorization
TangoAdminLambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: "tango-admin-lambda-role"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action:
- "sts:AssumeRole"
Outputs:
TangoAdminCognitoUserPoolId:
Description: "Tango Admin Cognito User Pool ID"
Value:
Ref: "TangoAdminCognitoUserPool"
TangoAdminCognitoUserPoolClientId:
Description: "Tango Admin Cognito User Pool Client ID"
Value:
Ref: "TangoAdminCognitoUserPoolClient"