AWS API Gateway Authorizers & Default Responses

AWS, API Gateway

A coworker of mine recently was having issues with calling an AWS API Gateway he had deployed. He was getting responses but no Lambda functions were being executed. Not his Lambda Authorizer or the Lambda integrated to the endpoint. All that was happening was he got an HTTP 401 status code back and the HTTP body was {"message":"Unauthorized"}. No matter what he tried, he couldn’t get his Lambda functions to execute, and due to an issue with IAM Roles in the account, he couldn’t get any API Gateway execution logs. So what was the problem?

If you have a Lambda authorizer, a Token Authorizer in this case but this likely also applies to a Request Authorizer, you need to include the Authorization header or your Lambdas will never get executed.

When you define an API Gateway Lambda Authorizer you specify the header or other sources that you will use to authorize the request. API Gateway will look for these values, and if they aren’t present it assumes that the request is invalid. At least, that is how I interpret the behavior. And it makes sense too, you’re paying for API Gateway and the intelligence built into it. If it thinks a request is invalid why would it trigger a Lambda execution to charge you even more if it knows the outcome? It can be faster and save you money all in one move.

The problem is, I have not seen this behavior spelled out in the API Gateway documentation. If you look at the page for Lambda Authorizer you’ll see that there is a numbered list showing the workflow of what happens.

  1. The client calls a method on an API Gateway API method, passing a bearer token or request parameters.
  2. API Gateway checks whether a Lambda authorizer is configured for the method. If it is, API Gateway calls the Lambda function.

This behavior is alluded to in number one, “passing a bearer token or request parameters”. If the client doesn’t pass a bearer token or request parameters then that condition is not satisfied and it isn’t what happens.

What happens instead is the defined Gateway responses take over. There is a list of all the different Gateway responses. Only one of them returns a 401 status code, the Unauthorized response.

This situation exactly matches the definition of the HTTP 401 Status Code from RFC7235

The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource.

This entire situation seems to indicate to me that:

  • Using non-default Gateway responses, especially in a development or testing situation, is a very good idea
  • Developers need to take the time to build up an understanding of the different IETF RFCs