0
votes

I am attempting to follow the "API Gateway resource policy only" flow on this doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-authorization-flow.html#apigateway-authorization-flow-resource-policy-only

When attempting to access a protected route using the authorization signature, I am getting a response that reads as if API Gateway believes the request is being made by an anonymous user instead of a credentialed user.

I have a public API Gateway deployment with the below resource policy.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": "arn:aws:execute-api:*:*:*/api/GET/server"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<account-id>:user/api-auth"
      },
      "Action": "execute-api:Invoke",
      "Resource": "arn:aws:execute-api:*:*:*/api/POST/server"
    }
  ]
}

What is not expected is that when I attempt to access the POST route using the aws4_request Auth signature using api-auth user's access/secret key, I get:

User: anonymous is not authorized to perform: execute-api:Invoke on resource:

>>> import boto3
>>> import requests
>>> from requests_aws4auth import AWS4Auth
>>> 
>>> auth = AWS4Auth("<access-key>", "<secret-key>", "us-east-1", "execute-api")
>>> response = requests.request("POST", "https://<endpoint>.execute-api.us-east-1.amazonaws.com/api/server", auth=auth, data='', headers={})
>>> print(response.text)
{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:<account-id>:<endpoint>/api/POST/server"}

The user has the below policy

{
   "Effect": "Allow",
   "Action": "execute-api:Invoke",
   "Resource": "*"
}

From what I can tell on the troubleshooting doc, I should be configured correctly: https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-troubleshoot-403-forbidden/

Edit 1

My example uses requests_aws4auth, which should be creating correct headers. As another example, the below generated from Postman results in the same problem:

curl --location --request POST '<endpoint>.execute-api.us-east-1.amazonaws.com/api/server' \
--header 'X-Amz-Content-Sha256: <data>' \
--header 'X-Amz-Date: <date-data>' \
--header 'Authorization: AWS4-HMAC-SHA256 Credential=<access-key>/<date>/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=<signature>' \
--header 'Content-Type: application/json' \
--data-raw '<request>"}'

For what it is worth...

  1. Accessing the GET route without Authorization works fine. This is expected.

  2. When trying to access the POST route without an Authorization signature in the header, I receive the same User: anonymous message. This is also expected.

1
User: anonymous tells you that your authentication attempt in the auth object isn't being recognised. Your request seems to be signed differently to this example in the docs e.g. you have no x-amz-date header, and the docs say > "Host" and "x-amz-date" are always required. - rowanu
Thanks for the comment @rowanu - the python package I'm using in my example (requests-aws4auth) inserts those headers for me. As another example, I have included a curl request that produces the same outcome. - getglad

1 Answers

0
votes

For the resource policy to allow access to a particular method, you need to set the "Authorization" settings under "Method execution" to "AWS_IAM"