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.
Related
I have API gateway deployed in Account A, and want to authenticate/allow other Account B,C,D. In actual use case, I want to authenticate more than 50 AWS account. Scale in and scale out as required.
Tried the below approach, andimplementation is working:
Resource based policy:
To authenticate within various AWS account. But the problem is I have to redeploy my API to reflect the changes.
Cognito
It can be use if the users need to sign-up and sign-in
Not suitable in the given scenario, we validating authentication between accounts
REST API Private
Again, in the resource policy I have to provide the endpoint details. But the problem is I have to redeploy my API to reflect the changes.
Lambda authorizer on cross account
We can deploy authorizer in individual AWS accounts, but authentication should be centralized in source account.
I probably think answer revolves around Lambda authorizer, but not sure how can I go forward from here.
Do we have any approach to authenticate, If you guide me some with documentation I can refer, it will be great help.
AWS cognito's documentation suggest all the roles around IAM. How to make meaningful role that my application (resource-server) understands?
I have used AWS Cognito extensively in my applications and I can try helping you here.
Whatever you are saying is possible using Cognito. I believe you are trying to figure one pattern to map your application roles to Cognito/AWS IAM roles.
All Cognito users in the pool can be segregated under different Cognito Groups. documentation is here -> https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-user-groups.html
Each Cognito user group has to be mapped with corresponding IAM Role (permissions you can customize).
Now, these groups need to have one to one mapping with the user role/group in the application.
These groups can be leveraged in 2 different ways. We are considering the design pattern with UI layer (eg:AngularJS) -> AWS APi Gateway -> RestAPI (Lambda/hosted as an application in Beanstalk/container/Ec2/etc.)
The UI controls need to be displayed according to the user group. For example, a super admin will see all the links and menus, full privilege. But for normal end-user, limited links and menus will be visible. In order to achieve this, you can use some of the plugins for AngularJS (may be different in your case) to control the rendering of UI based on group information.
The API layer can be protected by introducing an authorization layer by setting the Authorizer configuration of API Gateway as IAM/Cognito. So before a request hits the API hosted in back-end, API gateway will check whether the requested user group has permission to access the API.
I hope this helps.
Not sure what you mean too much, but roles are for accessing AWS resources. Cognito can be used with an Identity Pool to grant temporary credentials to AWS resources. This means you can put your server/ec2 instance behind an API gateway configured with IAM authentication, and create an authenticated role in your Identity Pool which allows HTTP calls to your API GW.
I have an existing Web API that I migrated to AWS using API Gateway and Lambda functions. However, I'm wondering how I can make use of AWS API Gateway's custom authorizer feature. My existing authorization framework is OAuth and I used ASP.Net Identity for user management. I generate bearer tokens and used the 'Authorized' attribute in my API Controllers for security. How can I do the same in AWS API gateway since I cannot change my framework cause I already have existing users. Thank you.
If you haven't already, check out the docs for custom authorizers: http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html
You should be able to write the Lambda function to replicate the authorization logic used in your existing service. Then think about how you want to model permissions in terms of an IAM policy (which is the output of the authorizer). If you want simple allow|deny then you can return an IAM policy from the authorizer that says Allow * or Deny *. Or you can add fine grained permissions if you want.
Is it possible for the Execution role in the API Gateway AWS Service integration config to inherit policy permissions from the running user.
Currently we are using a custom authorizer for API auth which as its output returns a policy document with statementOne.Action = 'execute-api:Invoke'. Is it possible to restrict or increase the permissions a API has when integrating API Gateway with other AWS services such as S3.
For example is it possible to have a custom authorizer with an API Gateway S3 proxy and set conditional IAM policy to only allow the userId (set via the principalId) to get S3 objects that are prefixed with their userId???
See execution role in this image from the AWS docs taken from here;
Yes, it is possible to pass through the IAM identity from the invoking user. You can do this by filling in arn:aws:iam::*:user/* as execution role.
More details can be found in the AWS docs
I have a serverless backend that operates with APIGateway and Lambda. Here is my architecture:
Currently, anyone with my APIGateway's URL can query or mutate the data. How do I protect the URL, so that only the client(react app) can access it. So, here is my concern, anyone can open the network tab in chrome console and get my APIGateway's URL and can use it using curl or postman. I want to prevent that.
Solutions I had in my mind:
Set up a CORS, so that only the origin can access it. But, I have a different lambda that invokes this URL. So, CORS wont work out.
I am sure there are some methods with the APIGateway itself. I am not getting right search term to get it from AWS documentation. I would also like to know what are the best practices to prevent accessing the backend URL apart from the Client(React App)
Update after #Ashan answer:
Thank you #Ashan for the answer. In my case, I use Auth0, so custom authoriser should work for me. I just came across this https://www.youtube.com/watch?v=n4hsWVXCuVI, which pretty much explains all the authorization and authentication possible with APIGateway. I am aware that authentication is possible either by Cognito/Auth0, but I have some simple websites, that has form, whose backend is handled by APIGateway. I can prevent the abuse from scraping bots using captcha, but once the attacker has got the URL, header and request parameters, he can invoke that million times. One thing, we can do is having an API-Key, but it is a static string with no expiration. Once the headers are with him, he can abuse it. So, any idea, how to prevent this in APIGateway. If not any other service apart from AWS that I can look for? Would be glad, If I get an answer for this.
Currently API Gateway does not support private urls, so it will be publicly available.
To restrict access you need to use a authorizer to authenticate and authorize the request using IAM policies. There are two options available at the moment.
IAM authorizer
Custom authorizer
If your authentication flow can directly (AWS STS, IAM user access keys or roles) or indirectly(Using AWS Cognito Userpools or any other SSO provider) can get temporary security credentials, then you can use IAM authorizer. From API Gateway side no code involved and its a matter of selecting the IAM check box for each API Gateway resource. You can use the API Gateway SDKs to invoke API Gateway requests where the SDK will handle the heavy liftings in setting up authentication headers.
If you use your own authentication mechanism, then you can write a seperate Lambda function to validate the tokens. This Lambda function name can be specified at API Gateway with the http hearder name to access the custom token to verify the requests.
To control API usage by authorized consumers, using API Key is the only way native to AWS at the moment.
Since you are using S3 for the react app hosting, you can further reduce the attack surface by using AWS WAF and CloudFront infront your application stack. The API Key can be added to CloudFront headers to forward to your APIGateway origin and since CloudFront and APIGateway communication happens using SSL, its nearly impossible for someone to find the API key. Using AWS WAF you can limit malicious access for common attacks. This includes rate based blocking to limit someone from repeatedly invoking the API.