getting message: forbidden reply from AWS API gateway

Amazon Web-ServicesAws Api-Gateway

Amazon Web-Services Problem Overview


I am trying to create a lambda service on AWS and have it accessed from outside via the API gateway with no authentication or restriction required.

To make things easy I set the gateway for now to be a Mock.

On the Get method of the API, the Authorization is set to None and the API Key is not required.

When I try this, I get {"message":"Forbidden"} (same message if I connect it to the actual lambda service).

Any advice on how to make it accessible?

Amazon Web-Services Solutions


Solution 1 - Amazon Web-Services

If you set 'API Key Required' option to true, please check below.

  1. you have to pass 'x-api-key' HTTP Header Parameter to API Gateway.
  2. The API Key had to be created.
  3. In addition, you need to check a Usage Plan for the API Key on API Gateway Console.

Solution 2 - Amazon Web-Services

On the API Gateway dashboard choose Resources, click Actions and choose Deploy API. Before your first deployment the only response you'll get is the {"message":"Forbidden"}.

Solution 3 - Amazon Web-Services

If you use a custom domain name and forget to select destination staging, you'll get the Forbidden message.

Simply go to Custom Domain Names and click Edit under your domain, and then select the stage under Base Path Mappings.

Solution 4 - Amazon Web-Services

You need to deploy your api on stage and use stage url go to Resources, click Actions and choose Deploy API

Now if you are getting error

> {"message":"Forbidden"}.

Please check following steps

1 ) If you enable api key copy and pass your key in postman

enter image description here

  1. Now you still getting same error means you will need to create usage plan

enter image description here

  1. set limit and assign plan to your api

enter image description here

Solution 5 - Amazon Web-Services

I might be too late but one of the reasons API Gateway would give "forbidden" message is when you pass data in request Body on a GET operation. To solve the problem either make your resource POST or you do not pass data in request Body.

Solution 6 - Amazon Web-Services

I had a similar problem, and I had the following:

  1. A Custom Domain (Edge Optimized)
  2. Multiple Stages (dev, staging, prod)

I also didn't set any Authorization nor restrictions to make things simple.

I was able to fix the problem by adding Base Path Mappings for each of my stages (dev, staging, prod).

Solution 7 - Amazon Web-Services

This may be far from obvious, but another reason of seeing "Forbidden" error when using AWS API Gateway may be calling incorrect URL that does not correspond to any deployed API method. It can occur if you're actually hitting wrong URL (e.g. instead of calling https://9999xx9x99.execute-api.us-east-1.amazonaws.com/dev/users (note dev stage before users) you called https://9999xx9x99.execute-api.us-east-1.amazonaws.com/users (no stage). You'd expect to get 404, but you'll get 403.

BTW: after you make a deployement to https://9999xx9x99.execute-api.us-east-1.amazonaws.com/dev/users calling https://9999xx9x99.execute-api.us-east-1.amazonaws.com/user (note singular noun form here) you'll get… 403 as well, but with "Missing Authentication Token" message!

Solution 8 - Amazon Web-Services

If you set 'API' key required to true, you need to pass the api key as header.

API Key is passed as header field 'x-api-key'. Even after adding this field in header, this issue may occur. In that case, please validate below points

  • Do you have a Usage Plan? if not need to create one.
  • Link you API with Usage Plan. For that add a stage, it will link your API.
  • Do you have API Key? if not you need to create an API Key and enable it.
  • Add the Usage Plan which is linked with your API to this API Key. For that add Usage Plan.

Solution 9 - Amazon Web-Services

The only other reason that I've experienced which I don't see mentioned here is literally that you tried to reach the API too quickly after being published. I hit publish and see the "your API is reachable at" domain name, and immediately copy and pasted that into Postman to check it.

I get the forbidden message. Change nothing. Check all settings to ensure that I haven't done anything - everything is correct. Kinda tearing my hair out.

Return a few minutes later to try because I'm quite sure I'm doing it all correct - it works.

DNS man. No matter how fast the Internet is - it ain't instant :)

Solution 10 - Amazon Web-Services

If Authorization and API KEY Required both are set to true for the method, then make sure you have the following Headers while sending the request:

  1. Content-Type (usually application/x-www-form-urlencoded if GET call)
  2. HOST
  3. X-Amz-Date
  4. Authorization
  5. x-api-key

I use POSTMAN for API testing which is quite reliable and then it's preety straight forward.

Note: Do not add x-api key header if you have set API KEY REQUIRED as FALSE. And if you have set AUTHORIZATION as FALSE then do not add Authorization header.

Solution 11 - Amazon Web-Services

There are a few things to do when we receive the {message: forbidden} in the API Gateway:

CORS enabled?

  1. Check if CORS is Enabled within the API ( to start with, allow the origin '*', to make sure we can test safely )
  2. Deploy the API to make sure all settings are as expected

API Key enabled?

  1. Check if we have the API Key enabled in the API Gateway
  2. Check if there is an API Key configured.
  3. Check if your API Key is assigned to the correct usageplan and add an API Stage, without the API Stage you will always receive an {message: forbidden}

If you are still facing issues, let me know so me or one of our cloud gurus @levarne can help.

Solution 12 - Amazon Web-Services

I got this error from an nginx fargate service trying to access a private API in API Gateway. I needed to add a policy under resource policies in my api like this

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:<AccountID>:<RestApiID>/*",
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpce": "<VPC Endpoint ID for execute-api>"
                }
            }
        }
    ]
}

Solution 13 - Amazon Web-Services

I might have come across a solution to this problem. I had the same issue right now on MacOS. I tried to flush my DNS and then it worked!

Try this in the terminal:

Mac OS X Yosemite and later

sudo killall -HUP mDNSResponder

Mac OS X Yosemite v10.10 through v10.10.3

sudo discoveryutil mdnsflushcache

Mac OS X Mavericks, Mountain Lion and Lion

sudo killall -HUP mDNSResponder

Mac OS X Snow Leopard

sudo dscacheutil -flushcache

Solution 14 - Amazon Web-Services

Just a note on the similar case I ran into with Swagger Editor:

  • I exported the OpenAPI 3.0 YAML from API Gateway → Stages → select "Prod" → select "Export" tab → switch radiobutton to "OpenAPI 3" → "Export as OpenAPI 3 + API Gateway Extensions"
  • Paste the received YAML to https://editor.swagger.io/
  • Execute a trivial GET method.
  • It returns 403 Forbidden with {"message":"Forbidden"} body.

curl command from Swagger Editor looked like this:

curl -X GET "https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com//Prod/users" -H "accept: application/json"

(note the double // before Prod).

And the same curl command without // worked via the command line!

The trick that worked is to replace this server structure returned in the API Gateway-generated:

servers:
  - url: "https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com/{basePath}"
    variables:
      basePath:
        default: "/Prod"

With the full url without variables:

servers:
  - url: "https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com/Prod"

Notably, removing the leading slash from default: "/Prod" didn't help.

Solution 15 - Amazon Web-Services

In my case, it was because I used the

> Managed-AllViewer

origin request policy. Switching to

> Managed-UserAgentRefererHeaders

solved the problem.

My client sent an Accept-Encoding header, which CloudFront did not like. You can verify this by creating a custom origin request policy of type "Whitelist", and although Accept-Encoding is selectable from the list, you receive an error when creating the policy: "The parameter Headers contains Accept-Encoding that is not allowed."

I did not find the relevant documentation unfortunately. Also no clue why such an inconspicuous header is disallowed.

Solution 16 - Amazon Web-Services

Local Firewall / antivirus or NGIPS (Cisco Bluecoat). The latter was my case, where I wouldn't even get logs in CloudWatch from my API. It was allowing my top level domain hosted website, but was blocking with 403 the api subdomain, with no body in the browser's network dev-tools tab.

Solution 17 - Amazon Web-Services

I got {"message":"Forbidden"} on an API with EndpointConfiguration set to PRIVATE, and a VpcEndpoint created for it in the Vpc's private subnets (this is an inter-service API)

The reason I got {"message":"Forbidden"} was that I was under the impression I should use one of the VpcEndpoint's urls. The URL to use is still the one associated with the stage (in ApiGateway console). It is:

https://${RestApiId}.execute-api.${Region}.amazonaws.com/${StageName}

Solution 18 - Amazon Web-Services

I had a similar problem. Turned out that my certificate in Certificate Manager was not created in North Virginia region (us-east-1), therefore I could not mark Custom Domain as Edge-optimized. I had to choose Regional instead.

When I re-imported the certificate using N. Virginia region and created a Custom Domain again, but this time with Edge-optimized endpoint configuration, it worked flawlessly.

Solution 19 - Amazon Web-Services

I received this error today because the aws_host in the signing header was incorrect (using Boto3 and AWSRequestAuth).

While refactoring I started to loop through multiple requests, but this introduced request was on a different API that required a different aws_host.

auth = AWSRequestsAuth(aws_access_key=credentials.access_key,
                       aws_secret_access_key=credentials.secret_key,
                       aws_token=credentials.token,
                       aws_host=f'api.{env}.XXX.dk',
                       aws_region=region,
                       aws_service='execute-api')

Solution 20 - Amazon Web-Services

We had faced this issue in our production when we used Kong as our api gateway. Our requests passed thro when initiated from Postman but failed with 403 when initiated via Code. The Bot plugin in Kong was enabled which only allowed requests initiated from Browser or Mobile App based on the user agent header value.Our requests initiated via Http Client failed. Once we disabled the bot plugin then the error didnt occur. It now allows request if the user-agent is Apache-HttpClient/4.5.2 (Java/1.8.0_91).

Solution 21 - Amazon Web-Services

Putting my experience over here as well. I tried all those things above and it turned out that putting the domain with a wildcard solved my {"message":"Forbidden"} issue: *.mydomain.com

Custom domain

Solution 22 - Amazon Web-Services

> As @gary69 and @Adriaan Pelzer mentions > > https://stackoverflow.com/a/52727654/809043 > > https://stackoverflow.com/a/55136675/809043 > > You can get the message {"message":"Forbidden"} when requesting a > Private API.

So if you have a setup where all traffic should go thorough a API Endpoint which than directs the traffic to the API Gateway then the following parameters may be used.

APIGatewayVPCEndpoint:
  Type: 'AWS::EC2::VPCEndpoint'
  Properties:
    PolicyDocument: '{
        "Version":"2012-10-17",
        "Statement":[{
          "Effect":"Allow",
          "Principal": "*",
          "Action":["execute-api:Invoke"],
          "Resource":["arn:aws:execute-api:eu-north-1:000000000000:*/*"]
        }]
      }'
  ...
  VpcEndpointType: Interface
  PrivateDnsEnabled: true

If PrivateDnsEnabled is enabled, than the endpoint in the API Gateway needs to be of Type Private, and a policy needs to added.

  ApiGatewayRest:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Description: A mocked API
      Name: Mocked API
      EndpointConfiguration:
        Types:
          - PRIVATE
      Policy: '{
        "Version": "2012-10-17",
        "Statement": [{
          "Effect": "Allow",
          "Principal": "*",
          "Action": "execute-api:Invoke",
          "Resource": "arn:aws:execute-api:eu-north-1:000000000000:*/*/*/*"
        }]
      }'

This forum thread helped clear out some of the details for me

https://forums.aws.amazon.com/thread.jspa?threadID=286760

Solution 23 - Amazon Web-Services

This usually comes when we try to access the Private API endpoint with incorrect policy & without passing the 'HOST' header in the invoke request. Let's say I have an API that is deployed as a private endpoint with the below resource policy.

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Principal": "*",
        "Action": "execute-api:Invoke",
        "Resource": "arn:aws:execute-api:us-west-2:12345678:2ucqasdfasdfryc/*"
    },
    {
        "Effect": "Deny",
        "Principal": "*",
        "Action": "execute-api:Invoke",
        "Resource": "arn:aws:execute-api:us-west-2:12345678:2dgaucqt6dfgdyc/*",
        "Condition": {
            "StringNotEquals": {
                "aws:SourceVpce": "vpce-87878kjlkj8787k"
            }
        }
    }
]
}

Accessing Private API endpoint when private-DNS-hostnames disabled.

curl -v -H 'Host: 01234567ab.execute-api.us-west-2.amazonaws.com' https://vpce-01234567abcdef012-01234567.execute-api.us-east-1.vpce.amazonaws.com/test/pets

                          

[OR] use the API ID instead of the Host header.

curl -v -H 'x-apigw-api-id: 01234567' https://vpce-01234567abcdef012-01234567.execute-api.us-east-1.vpce.amazonaws.com/test/pets

Solution 24 - Amazon Web-Services

I was also facing the same issue a week back and spent sometime to identify the issue. Our api gateway endpoint has been configured to work only through public network and we have a WAF & resource policy to filter the incoming requests to the endpoint. I was able to access the endpoint from a different vpc and not from a particular vpc. I was getting Forbidden error.

At last, found that the vpc that i was trying from, have the VPC Endpoint for the execute api service with private DNS enabled. API Gateway endpoint was resolving to a private IP inside the VPC.

There are two ways to resolve it. One, we can disable the private DNS, which is what I did. It started working very fine after the change. But we have to make sure it doesn't affect others who are using the vpc endpoint.

Two, we can use a custom domain name & we can use that to call from the vpc.

Solution 25 - Amazon Web-Services

My issue was that I was connected to my office's VPN which routes into my company's VPC in AWS. My company had private DNS setup which resulted in the request to the public endpoint being routed to a private IP address belonging to the VPC's interface endpoint for API Gateway.

This article explains it all.

There are 2 solutions:

  1. Turn off VPN when hitting the invoke URL.
  2. Use API Gateway custom domain.

I ended up using solution 1 because I needed to setup a cloudfront in front of API Gateway and the custom domain I want to use was already setup as Edge type with other api gateways associated with it.

For additional reference, Edge type custom domains cannot be set as the origin of another cloudfront because it uses CloudFront to speed up connections across all geographic locations. See this AWS support article for more details.

Solution 26 - Amazon Web-Services

To add to the options to look into:

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

If you have "private dns" enabled, and you use a VPCEndpoint, you might very well run into this issue. See: https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-vpc-connections/

In my case, I had two API Gateways in the same account:

  • a public HTTP API Gateway fronting a Lambda function,
  • a private REST API Gateway fronting a lambda function (with a VPCEndpoint so that my ECS/Fargate containers could talk to the private API)

The problem was that once I set up the private API+VPCEndpoint, it started to siphon all traffic FROM WITHIN AWS to API Gateways (so, both to my public and to my private API Gateways). And that broke the PUBLIC HTTP API.

I banged my head for some time because, from my laptop, I could reach the public API Gateway but NOT from my docker container inside AWS Fargate!

The possible solutions are:

  • Option 1: add a Route53 to the public API if you need to call it from your docker container (that way, your container makes an outbound "internet request" and back into the public gateway [~from outside])
  • Option 2: for the public API, I ended up going for a simpler option: I got rid of the public API and, instead, exposed my Lambda function through an Application Load Balancer: just need to configure the TargetGroup to point to Lambda.

I now have:

  • my Private REST API Gateway (and VPCEndpoint) that fronts the Lambda function for my docker containers (those run in AWS/Fargate in private subnets)
  • my Publicly available ALB to reach the Lambda function (not using HTTP API Gateway anymore for this).

Solution 27 - Amazon Web-Services

In my case the api key was not enable. Make sure the API is set as Enabled. enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFabView Question on Stackoverflow
Solution 1 - Amazon Web-ServicesDaniel Jihoon OhView Answer on Stackoverflow
Solution 2 - Amazon Web-ServicesjnevesView Answer on Stackoverflow
Solution 3 - Amazon Web-ServiceskontrollantenView Answer on Stackoverflow
Solution 4 - Amazon Web-Servicesvaquar khanView Answer on Stackoverflow
Solution 5 - Amazon Web-ServicesIgnitious NkwinikaView Answer on Stackoverflow
Solution 6 - Amazon Web-ServicesJoben R. IlaganView Answer on Stackoverflow
Solution 7 - Amazon Web-ServicesmadheadView Answer on Stackoverflow
Solution 8 - Amazon Web-ServicesbiswView Answer on Stackoverflow
Solution 9 - Amazon Web-ServicestgmerrittView Answer on Stackoverflow
Solution 10 - Amazon Web-ServicesillusionxView Answer on Stackoverflow
Solution 11 - Amazon Web-ServicesMax LansView Answer on Stackoverflow
Solution 12 - Amazon Web-Servicesgary69View Answer on Stackoverflow
Solution 13 - Amazon Web-ServiceshaynzzView Answer on Stackoverflow
Solution 14 - Amazon Web-ServicesDmitriy PopovView Answer on Stackoverflow
Solution 15 - Amazon Web-Servicesuser3002097View Answer on Stackoverflow
Solution 16 - Amazon Web-ServicesRaduView Answer on Stackoverflow
Solution 17 - Amazon Web-ServicesAdriaan PelzerView Answer on Stackoverflow
Solution 18 - Amazon Web-ServicesJakubFView Answer on Stackoverflow
Solution 19 - Amazon Web-ServicesShane RichView Answer on Stackoverflow
Solution 20 - Amazon Web-ServicesCshahView Answer on Stackoverflow
Solution 21 - Amazon Web-ServicesJoelView Answer on Stackoverflow
Solution 22 - Amazon Web-ServicesLeonard SaersView Answer on Stackoverflow
Solution 23 - Amazon Web-ServicesVeluView Answer on Stackoverflow
Solution 24 - Amazon Web-ServicesdeviView Answer on Stackoverflow
Solution 25 - Amazon Web-ServicesAlexView Answer on Stackoverflow
Solution 26 - Amazon Web-ServicesPierreView Answer on Stackoverflow
Solution 27 - Amazon Web-ServicesQuentin DelView Answer on Stackoverflow