Skip to content

Why do I get an HTTP "403 Forbidden" error when I try to connect to my API Gateway public APIs from a VPC?

5 minute read
0

I get an HTTP "403 Forbidden" error when I call my Amazon API Gateway public API from my Amazon Virtual Private Cloud (Amazon VPC).

Short description

Because Amazon VPC interface endpoints route traffic only to private APIs, you can get an HTTP  "403 Forbidden" error when you try to access API Gateway public APIs.

The HTTP "403 Forbidden" error occurs when you try to access an API Gateway public API from a VPC that has private DNS names turned on. If you turn on private DNS names, then all requests from the Amazon VPC to API Gateway APIs resolve to the interface VPC endpoint.

However, you can't use an interface VPC endpoint to connect to public APIs because the endpoint's private DNS name is in the format *.execute-api.{region}.amazonaws.com. The * character is a placeholder for the API ID. This format matches the API Gateway default invoke URL for both public and private APIs.

When you turn on Private DNS names, calls to API Gateway API URLs in the format *.execute-api.{region}.amazonaws.com resolve to the interface VPC endpoint's private IP addresses. This setting routes all traffic to the API Gateway through the interface VPC endpoint for public and private APIs.

You also get a "403 Forbidden" error when you use AWS Direct Connect to invoke the default execute-api URL to connect to private APIs from an on-premises network.

Resolution

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.

Check whether your Amazon VPC uses private DNS settings

To resolve the HTTP "403 Forbidden" error, first determine whether your Amazon VPC uses private or public DNS settings. You can use either the AWS CLI or the Amazon VPC console.

AWS CLI

Run the following describe-vpc-endpoints command:

export VPC_ID=YOUR_VPC_ID  
export REGION=YOUR_REGION  
aws ec2 describe-vpc-endpoints \  
  --filters "Name=vpc-id,Values=${VPC_ID}" \  
            "Name=service-name,Values=com.amazonaws.${REGION}.execute-api" \  
  --query 'Amazon VPC endpointndpoints[].{Name:Tags[?Key==`Name`].Value|[0],Amazon VPC endpointndpointId:Amazon VPC endpointndpointId,PrivateDnsEnabled:PrivateDnsEnabled}' \  
  --output table

Note: Replace YOUR_VPC_ID with your VPC ID and YOUR_REGION with your AWS Region.

Amazon VPC console

Check whether you turned on the private DNS name in your interface VPC endpoint configuration. Also, check whether there's an interface VPC endpoint to access a private REST API in your VPC. If there's an interface VPC endpoint, then check whether you turned on the DNS attributes

Connect to public APIs with Private DNS names turned on

If you turned on private DNS, then set up an edge-optimized custom domain names or Regional custom domain names to connect to your public APIs. You can then invoke the API Gateway public API with the custom domain name, such as api.example.com. Connectivity to your private REST APIs continue to work through the private REST API endpoint.

If clients connect from an on-premises network, then set up an Amazon Route 53 Resolver inbound endpoint. To use the execute-api invoke URL, forward all the private DNS queries from your on-premises network to the inbound endpoint.

Note: Your VPC resources must have internet connectivity to connect to your public APIs.

Connect to public APIs with Private DNS names turned off

To allow outbound traffic to your public APIs, use security groups for your VPC. Also, modify the resource policy that's attached to your API to allow access from the VPC.

If your VPC has permission to access your public REST APIs, then use the default execute-api command to connect to your public REST APIs. You can also use the custom domain name to connect to your public REST API. For more information, see Control and manage access to REST APIs in API Gateway.

If you turn off Private DNS names for the interface VPC endpoint, then the default execute-api invoke URL no longer connects to private REST APIs.

To invoke private REST APIs, take one of the following actions:

  • Use host headers with your Amazon VPC endpoint as the DNS, such as in the following example:

    curl -H "Host: {your-api-id}.execute-api.{region}.amazonaws.com" \  
         https://Amazon VPC endpoint-xxxxx-xxxxx.execute-api.{region}.Amazon VPC endpoint.amazonaws.com/stage/path
  • Create a private hosted zone for execute-api.{region}.amazonaws.com. In the private hosted zone, add an A record for your API identifier. Point the A record to the interface VPC endpoint's IP addresses so that you can use the default execute-api invoke URL of the private REST API.

Change the private DNS attributes for an interface VPC endpoint

You can change the private DNS attributes for an interface endpoint. The changes affect how an API stage URL resolves to the private IP address of the interface VPC endpoint. Also, the changes affect how you can connect to private APIs and public APIs from a VPC. For more information, see DNS attributes for your VPC.

Related information

Access an AWS service using an interface VPC endpoint