57

Trying to post to an API I've created in API gateway:

{
    "Message": "User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-west-2:***********:jrr7u1ekrr/v0/POST/user"
}

How can I update the policy in CloudFormation to make publicly available the POST endpoint? I'm declaring the API with the AWS::ApiGateway::RestApi resource type.

the API policy property is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*/POST/user"
        }
    ]
} 
tgk
  • 3,857
  • 2
  • 27
  • 42
  • 9
    FYI if you're seeing this you need to update the Resource Policy on your API Gateway – tgk Feb 12 '19 at 20:01
  • thank you! this was my problem. fixed now. thanks again – idig Mar 07 '20 at 12:48
  • For CORS people: Also note even if you only have Allows in your resource policy, it will deny everything else. So if you have anything in your resource policy you need to add an Allow for the OPTIONS endpoint, even if auth is disabled on the endpoint. – JacksonHaenchen May 05 '23 at 18:32

8 Answers8

57

Something that tripped me up: "If the API has been deployed previously in the API Gateway console, you'll need to redeploy it for the resource policy to take effect."

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-create-attach.html

Travis Bear
  • 13,039
  • 7
  • 42
  • 51
  • 5
    After redeploying it, my API became available. This solution works for me. This answer should be marked as the correct answer. – Ryan Lyu Jan 08 '20 at 02:23
  • 2
    Also, it seem that it might take a few seconds after the deploy button has been pressed before it takes effect. – Tim Ludwinski Dec 10 '20 at 20:56
  • 5
    aws should provide deploy button wherever there is option to change configuration so that user don't spend hours figuring out why something is not working – VGupta Apr 16 '21 at 20:54
19

Even if the Authorization is set to NONE for your OPTIONS method, it will check the resource policy if you have one.

You can make your OPTIONS method public available by setting the following API gateway resource policy.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:{REGION}:{AWS_ACCOUNT}:{YOUR_API_ID}/{YOUR_API_STAGE}/OPTIONS/*"
        }
    ]
}

Ckeck How API Gateway Resource Policies Affect Authorization Workflow

pavan Kumar
  • 191
  • 1
  • 3
6

After the policy changes you need to redeploy the application for changes to propagate. To re-deploy -

  1. Go API Gateway.
  2. Go to resource.
  3. Click on the "Actions" drop down. click on Deploy API.
pdoherty926
  • 9,895
  • 4
  • 37
  • 68
3

As others have pointed out this issue is most likely caused by not having a correct Resource Policy on the API. I suggest you use the example from the AWS Docs here Example: Allow private API traffic based on source VPC or VPC endpoint policy from AWS docs.

Use the VPC Endpoint version and set the SourceVpce to be the id of your API Gateway VPC Endpoint. Once saved API Gateway will automatically populate the endpoint details, refresh the page to see the updated policy.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-1a2b3c4d"
                }
            }
        }
    ]
}

As others have noted any changes to the Resource Policy requires you to Redeploy your API. Wait at least 30 seconds after you've deployed before you test again.

Iain Hunter
  • 4,319
  • 1
  • 27
  • 13
2

The issue is probably on the method declaration part. You will need to have authorizationType set to NONE in your AWS::ApiGateway::Method declaration.

roxxypoxxy
  • 2,973
  • 1
  • 21
  • 28
  • thanks roxxypoxxy, I do have the method auth set to none: ``` "Type": "AWS::ApiGateway::Method", "Properties": { ... "AuthorizationType": "NONE", ``` – tgk Oct 26 '18 at 21:07
  • Now that I see your edited post, can you try tweaking the resource as documented here https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-examples.html. The resource declaration you have does not seem to follow the pattern referred in the doc – roxxypoxxy Oct 26 '18 at 23:17
  • 2
    You're wrong. This error message is not about method authorization. – Akim Kelar Jul 09 '19 at 15:27
1

In

"Resource": "execute-api:/*/POST/user"

Set your Account ID instead of *

And then re-deploy.

Kr,

Rshad Zhran
  • 496
  • 4
  • 17
  • another team at my job has it setup similarly with the wildcard *, and it works for them. Like this - "Resource": !Join ["", ["execute-api:/", !Ref EnvironmentSuffix, "/*"]], – ennth Jan 06 '20 at 18:16
1

This is not an answer to the question, but for those who come up with the same error message.

I was using a resource policy to try to whitelist requests to an AWS API Gateway by IP, but I was getting the error mentioned by the OP:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:eu-west-1:{ACCCOUNT_ID}:{API_GW_ID}/{STAGE}/{METHOD}/{PATH}",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "{SOME_IP_ADDRESS}/32"
                }
            }
        },
        {
            "Sid": "",
            "Effect": "Deny",
            "Principal": {
                "AWS": "*"
            },
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:eu-west-1:{ACCCOUNT_ID}:{API_GW_ID}/{STAGE}/{METHOD}/{PATH}"
        }
    ]
}

What I've learnt:

  • On the one hand, no resource policy means allow all requests.

  • On the other hand, Deny statements take precedence over Allow statements. (Meaning all requests were denied)

  • Lastly, if a resource policy exists, any request that does not match a statement gets denied.

Hence, to allow requests to API GW only from a certain IP, I ended up using the following policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:eu-west-1:{ACCCOUNT_ID}:{API_GW_ID}/{STAGE}/{METHOD}/{PATH}",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "{SOME_IP_ADDRESS}/32"
                }
            }
        }
    ]
}
Miguel Alorda
  • 623
  • 5
  • 13
0

Please check the following

Step - 1: Ensure that the IAM User has policy AmazonAPIGatewayInvokeFullAccess attached.

Step - 2: Ensure that the API Gateway has whitelisted the AWS Account in the Resource Policy.

Step - 3: If the IAM User has been created recently it will take around 5 - 10 mins for the policy to reflect, please be patient.

Roshan Halwai
  • 552
  • 4
  • 5