Reputation: 14596
Im building a serverless application using the following AWS technologies:
All requests from the client (programmed in Angular2) go through API gateway.
I have created a IAM role for signed in users: Cognito_MyApp_Auth
.
I use a Cognito User Pool Authorizer
to make sure all calls to my API are from valid signed-in users.
Question: How can I grant the Lambda function the same permission as the signed in user?
Use case: A signed in user may only create, edit or delete in his own S3 bucket, so granting Lambda full permission to S3 is not an option.
Upvotes: 2
Views: 1166
Reputation: 3745
There is no direct way to grant the Lambda function the same permissions as the signed in user; however, you should be able to implement your use case using Cognito identity pools and policy using the cognito-identity context variable.
For this approach, you won't use Cognito user pools nor the Cognito user pool authorizer. Instead, you use a Cognito identity pool for federated identity. Set the authorization on you API methods as AWS_IAM. Don't use Lambda as the integration, but instead use the AWS proxy to integrate directly to S3. Set the integration request to use the caller's identity.
To cal the API you'll need to use Cognito to get temporary credentials and then sign your API request with them.
With this approach, the S3 call is made with Cognito identity context, so you can attach policy which uses cognito-identity variables to the IAM role associated with authenticated users in your Cognito identity pool.
For example:
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
]
"Resource": [
"arn:aws:s3:::BUCKET_FOR_USER_${cognito-identity.amazonaws.com:sub}/*"
]
}
See this post for a similar use case.
Upvotes: 0
Reputation: 7246
Cognito_MyApp_Auth
does not set different permissions from user to user. It only defines the permissions for any signed user. So you should allow access to all buckets in this role's policy. (However, I'd limit this access to buckets starting with a specific prefix.)
Fortunately, when Lambda is invoked via Cognito SDK, using Cognito provided credentials, context object passed to handler carries Cognito identity used to invoke the Lambda.
For Node.js you can see how to get this information:
if (typeof context.identity !== 'undefined') {
console.log('Cognito
identity ID =', context.identity.cognitoIdentityId);
}
Once you have the identity id, you can set up your own logic to limit the user's access to her own bucket.
This was the case when you call the Lambda directly from the application using Cognito SDK. If you use API Gateway, there is a good post from an AWS employee: https://forums.aws.amazon.com/thread.jspa?messageID=717379
Upvotes: 1