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...
Accessing the
GET
route withoutAuthorization
works fine. This is expected.When trying to access the
POST
route without anAuthorization
signature in the header, I receive the sameUser: anonymous
message. This is also expected.
User: anonymous
tells you that your authentication attempt in theauth
object isn't being recognised. Your request seems to be signed differently to this example in the docs e.g. you have nox-amz-date
header, and the docs say > "Host" and "x-amz-date" are always required. - rowanurequests-aws4auth
) inserts those headers for me. As another example, I have included acurl
request that produces the same outcome. - getglad