I have hosted a static site in an S3 bucket with links to a REST API that I have deployed using Amazon API Gateway. Now I would like that the methods of the REST API can only be invoked from the static site.
In order to write the Resource Policy I can't allow for a static IP, because AWS is very clear that the IP of an S3 site is dynamic. The only option I can think of is enabling CORS in the API Gateway and configuring the Access-Control-Allow-Origin to be the domain of the static site. But that doesn't seem very convincing to me..
Is there a better alternative?
You couldn't do that anyway, as the API Gateway request comes from the browser of the visitor, not from server-side of the S3 hosting service.
CORS will restrict other websites calling your API using regular browsers, but a REST API client can call it without restrictions.
If you want to restrict access, either use an API Key (more obscurity than security) or implement a Custom Authorizor in API Gateway to authorise your clients. See here: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html
Related
I have a static website hosted in a public S3 bucket with a little bit of javascript code in it. Basically what this bit of code does is sending a POST request to an API Gateway to retrieve some data from the backend. The URL of the API Gateway is hardcoded into the website.
I'm concerned about the security implications of this. In theory anyone could look into it, get the URL and run a DDoS attack or something leading to a lot of costs for me. Is there a way to restrict access of to the API Gateway to only the requests coming from the website in the Bucket? I know there are ways to restrict access to API Gateways with IAM or Cognito but that's not what I'm looking for.
Yes the issue is valid, but there is a solution, what I would suggest:
Create a CloudFront distribution
Create 2 origin, on for the S3 and one for the API Gateway
configure an additional header in the API Gateway origin (which will be send between the CloudFront distribution and the API Gateway (no external will be able to see it)
Set up a AWS WAF, and configure a RULE to reject all traffic which does not have the appropriate "header" that you have configured in the CloudFront Distribution API Gateway origin.
Associate WAF with the API Gateway
Something like this:
I've been wasting about 12 hours going in circles in what seems like this:
I am trying to just make a simple static landing page in lambda and hook the root of a domain to it.
The landing page works, but api gateway didn't because AWS doesn't seem to set permissions properly by default ("internal server error" with API gateway and lambda on AWS) but now the gateway link works.
So the next steps were the following:
add a custom domain name in the api gateway
add the api mapping in the custom domain name
in route 53, create a wildcard certificate with *.domain.com and domain.com
create an A record that points to the api gateway with domain.com
create a CNAME record that points to the A record
and I get an error 403 with absolutely nothing in the log. I log both 'default' and '$default' stages in the api gateway.
I read https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-403-error-lambda-authorizer/ which is all about looking at what's in the logs...
and I find the doc is both everywhere and nowhere because it's built as chunks of 'do this' and 'do that' without ever painting a whole picture of how each piece is connected to the other, or any graph with the hierarchy of services, etc. Reminds me of code that works only when you follow the example documented and breaks otherwise.
I'm sure I'm doing something wrong, but given the lack of logs and lack of cohesive documentation, I have no idea about the problem.
Not to mention that http doesn't even connect, just https.
Can anyone outline the steps needed to achieve this? essentially: [http|https]://(www).domain.com -> one lambda function
You cannot use API Gateway for an HTTP request; it only supports HTTPS.
From the Amazon API Gateway FAQs (emphasis mine):
Q: Can I create HTTPS endpoints?
Yes, all of the APIs created with Amazon API Gateway expose HTTPS endpoints only. Amazon API Gateway does not support unencrypted (HTTP) endpoints. By default, Amazon API Gateway assigns an internal domain to the API that automatically uses the Amazon API Gateway certificate. When configuring your APIs to run under a custom domain name, you can provide your own certificate for the domain.
You can use CloudFront to automatically redirect HTTP to HTTPS. How do I set up API Gateway with my own CloudFront distribution? provides a pretty simple walkthrough of connecting an API Gateway to CloudFront (you can skip the API Gateway portion and use the one you created). The important thing you'll need to do that is not in that document is to select Redirect HTTP to HTTPS.
If you truly need HTTP traffic you're probably going to need to go with an ALB.
I need to make a secure HTTP callout from Salesforce (using Apex) to AWS Lambda and I build my first version using AWS API Gateway. I realized I can get a client certificate from API Gateway (.crt) but this looks like it is only for AWS backend and is not meant to be for the HTTP request sent to API Gateway. What are my alternatives to establish a secure connection from outside AWS (Salesforce) to a Lambda function?
So far I've found this, which is a disappointing dead-end for now.
Like the link you posted says, API Gateway does not currently support MTLS. Other options for you to add security to the calls at the moment are:
IAM permissions, and here.
API Gateway custom authorizers.
Cognito User Pools.
If you need a custom domain associated with the API Gateway:
Go to Route53 and add your domain (new Hosted Zone), if you haven't done it already.
On AWS Certificate Manager, import or request a certificat for the custom domain you intend to use in your API Gateway endpoints.
Open the API Gateway dashboard and go to "Custom Domain Names". Click "Create a custom domain name" and, in the option "ACM Certificate (region)", select the certificate you generated/imported in item 2 above.
That's it, now you should be able to trigger your Lambda functions using API Gateway from a secure connection (HTTPS). Please note that, if you do this, API Gateway will refuse connections over insecure HTTP protocol.
I'm currently extensively using the API Gateway as a source for CloudFront. My CloudFront serves other things as well, such as plain files from S3.
I've recently been looking into improving the current setup, and noticed the "Custom Domain Names" option in API Gateway.
From what I've understood, using it creates an unconfigurable CloudFront instance. I've not been able to find much information beyond that.
Are there any advantages to using API Gateway's Custom Domain Names over using a self-managed CloudFront instance?
When you use AWS CloudFront you can configure different Origins such as S3, API Gateway & etc to the distribution which allows to serve different services through same domain. e.g you can serve mydomain.com points to index.html in S3 and mydomain.com/api/* points to API Gateway. This allows for the frontend JavaScripts to access the API without the need for Cross Origin Request support at API Gateway which avoids sending Options preflight(If you have headers like Cookie, Authorization & etc.) request by the browser.
On the other hand you can configure Custom Domain Names to API Gateway. This allows to define a Custom Domain as well as a Custom SSL Certificate using AWS Certificate Manager. The main difference is, if you have a frontend application, you need to define two domains(or different subdomains) for the frontend served from S3 and API. When accessing the API from different domain it will require to have CORS configured at the API Gateway and can affect performance based on the latency.
I am new to AWS API Gateway.
I am trying to expose an endpoint to a static page I have hosted on S3.
I am trying to restrict access to the endpoint so that it can only be called by my domain example.com
In API Gateway I click enable CORS and by Access-Control-Allow-Origin* I am entering 'example.com'
The endpoint is not restricted to my domain as expected, I can call it from my dev machine locally
I can't see what I'm doing wrong? I have Googled but can't find anything similar....