AWS Custom Authorization lambda to approve Api Gateway service proxy action? - amazon-web-services

I want to create an Api Gateway route which is connected via service proxy to s3.
Only authenticated and authorized users (from Cognito Userpool) which have a specific permission (which is stored in a DynamoDb table) should be able to upload the file.
Since I'm not using S3 as the service proxy and not lambda, is it ok to put the code checking against the Dynamodb in the Custom Authorizer lambda? (After the token has been verified and before sending the success callback).
The query is simple, based on the Cognito user unique Id, I check in a table that user if user is authorized to upload.
I wouldn't want the upload to be done via a lambda function since some files are big.
Thanks

You can also consider
Setup CloudFront infront of S3 bucket.
Using IAM authorization at API Gateway.
Write a Lambda endpoint which checks Cognito ID in request context against Dynamodb.
Return Signed URL from Lambda for authorized users to directly upload files to S3 from browser client.

Related

Amazon Cognito and Application specific authorization logic to access Amazon CloudFront content

I'd like to protect Amazon CloudFront content with my custom application specific authorization logic.
For example, for authentication purpose I may use Amazon Cognito and Amazon CloudFront with AWS Lambda#Edge approach which will inspect every incoming request to CloudFront and ensure that request has a valid JWT token.
But how about the authorization part?
According to the application business logic, every single authenticated user should not have the access to the same resources.
How and where to check that a user with a valid JWT token has the access (according to the application business logic) to the requested Amazon CloudFront content?
Should such authorization logic be included in the Lambda#Edge handler also?
Yeah, the Lambda#Edge can be used to authorize the user to access a resource behind CloudFront.
And the authorization can be done with the Amazon Cognito User Pool service.
You flow will be similar the following one:
Here is a example of how to this: Secure Your Static Website with AWS CloudFront and Lambda
Check this blogpost to understand more about this process: Authorization#Edge Protect your Amazon CloudFront content from being downloaded by unauthenticated users.

Integrating AWS Lambda and HTTP endpoint together in API Gateway?

Let's say I have a service to allow people to upload photos. I store these photos in S3, and to make it efficient, I use Cloudfront. In order to upload these photos to S3, I was recommended to use Lambdas with API Gateway. However, I'd also like to send this request to a custom HTTP endpoint as well, and return that in the response from the Gateway. So my ideal process is:
User submits upload photo
Photo gets sent to API Gateway
API Gateway calls Lambda to store photo in S3 and also forwards the request to custom backend API
Backend sends back some info
API Gateway sends back this info to client
Is this possible? From the integrations doc, it seems like I can only do Lambdas or HTTP custom endpoint. Not sure how to do both.
Your flow should be like this
Create a lambda endpoint to create signedUrl and return to frontend for s3 upload
Once you have the signed URL upload the pic to the signed URL from the frontend
Once the operation is successful either you can send a request to the lambda from the frontend or a event on the s3 bucket to do further processing

AWS REST Api as S3 proxy and accessing client specific bucket

I have created AWS API Gateway as S3 proxy as per guidelines here. So final url looks something like
http://api.exmaple.com/v1/{clientbucketname}/{key}
client will use their pre-assigned bucket name in the url. I understand that if API is authenticated using IAM user then API will have access to the bucket belongs to authenticated IAM user and can perform actions only on a particular client's bucket.
However my API is authenticated using API-KEY. Each client has their own API-KEY how do i tie API-KEY to S3 bucket so client A cannot access client B's bucket simply by changing the bucket name in the URL.
It is not possible without AWS_IAM authorization.
API Gateway uses the result of that authorization to locate the account, role and bucket.

Generate temporary AWS creds that could be used by any client

I have a use case where I need arbitrary clients to receive AWS credentials (key and secret) that I generate and pass to it. The credentials should expire after a few minutes. The clients need to post to an s3 bucket.
The clients will not be a part of any AWS account and cannot use any multi factor auth. This seems to prevent me from using IAM roles.
It seems that the Security Token Service is what Amazon provides for similar use cases, but I can't massage it to get what I need out of it. I either need a role ARN, or to pass the session token on to the clients to use in their requests. The clients can have no concept of a session token- only AWS key/secret.
In short, I want to be able to generate a temporary AWS key/secret pair that needs no multifactor auth or session token.
Is this possible? Thanks!
This is exactly the use-case for Uploading Objects Using Pre-Signed URLs - Amazon Simple Storage Service.
Basically:
Your application determines whether the user is authorized to upload/download a file
It generates a Pre-signed URL that includes an expiration time
The clients use the URL to upload/download to S3
After the expiry time, the URL no longer works

AWS API Gateway Security with a Custom Authoriser & AWS Service Integrations

When using API Gateway to proxy AWS services such as S3 works great.
However it would seem that security is an afterthought. The execution role that is used for AWS Service integration seems to leave open the integrated service when using a customer authorizer.
The Custom Authorizer in API Gateway returns a principalId (e.g. a userId) and an IAM policy document. How could one build an IAM policy for the execution role of the service integration which would require for example the userId/principalId to be in the path of an S3 object.
I.e. using a custom authorizer + S3 integration how do you secure object access to only a particular key space where the principalId is part of an object tag or path?
http://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html or http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/policy-keys-cwe.html
I was having the same problem. Here is how I solved it with the path.
Assume user1 need to access their data and their space is
domain/user1/object1
domain/user1/object2
In the custom Authorizer you can return policy that the user can access only domain/user1/*. You can use any pattern you want and organize the storage to whatever namespace you want. If you want to expand namespace for multiple users you can do access to
domain/user1/*
domain/managers/*
And APIGateway will take care of the rest. If the user tries to access anything other than the above URL paths, the user will get 403 forbidden.
Followed the documentation from AWS and works perfectly,
http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html
In Addition, if you want authentication I would recommend CloudFront signed URL and Cognito.