Securing gateways with Lambda Authorizers

Kumar Harshit
5 min readDec 28, 2020

Building a Lambda Authorizer:

A lambda authorizer is a lambda which we write to validate the request based on our authz requirement so we are free to write anything. It gives us the flexibility to validate anything we want to,

we can verify the JWT token, check SAML assertion or even hit an internal server for authentication.

The two types of authorizers:

There are two types of Lambda authorizers, TOKEN and REQUEST

  • TOKEN : A token-based Lambda authorizer (also called a TOKEN authorizer) receives the caller’s identity in a bearer token, such as a JSON Web Token (JWT) or an OAuth token. Token authorizers are the simple ones. You specify the name of a header, usually Authorization, that is used to authenticate your request. The value of this header is passed into your lambda in an event object to validate. The TOKEN type differs from the REQUEST type in terms of the structure of the event object. The event object is a compressed version of the REQUEST type here. Example of the event object of a TOKEN type authorizer:
  • REQUEST : A request parameter-based Lambda authorizer (also called a REQUEST authorizer) receives the caller’s identity in a combination of headers, query string parameters, stageVariables, and $context variables. Request authorizers are more complex. Rather than simply passing along a header value to your authorizers, the request type will pass along most of the information about the request. This includes all header values, query string parameters, and other information. Example of an event object to a REQUEST type authorizer:

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html

Response from a custom authorizer:

In your lambda authorizer you need to take either of the following decision and pass it back to the api gateway: ALLOW or DENY

1) Deny: If you wanna Deny the request you can throw back an error with an unauthorized response.

2) Allow: If you wanna allow the request you have to return a valid IAM policy along with the principalId back with an action of “execute-api: Invoke” and action as “Allow” back and the Resource as the arn of the requested api.

The policyDocument looks something like :

Principal Id

The principalId is a required property on your authorizer response. It represents the principal identifier for the caller.

Policy Document

The policyDocument is another required property and the core of the authorizer response. You must return a valid IAM policy that allows access to the underlying API Gateway resource that the user is trying to access.

Essentially, you need to produce an object that allows the caller to perform a specific action (execute-api:Invoke). Finally, you need to specify the resource on which they are allowed to perform this action.

Context:

context is an optional property and might contain any extra information required by the request after the authorization is done.

How to get up and running fast

Setting up an api gateway to use a lambda authorizer :

We can have the lambda authorizer running in the same account as that of the API gateway or use a cross-account lambda authorizer.

1) We need to first create the lambda and return back a valid policy.

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

2) Go to the API gateway service under the Authorizers and create a new authorizer.

We can now create either a TOKEN or REQUEST type authorizer and point this to the lambda we have just created. now click on create, this would throw a prompt to allow the gateway to invoke the lambda if it’s in the same account, clicking yes would create a resource policy in the authz lambda for the gateway to invoke.

This can be achieved from the console as well :

If it’s a cross platform lambda we can achieve the same by adding a resource policy on the lambda.

suppose the lambda is in account A and the gateway in account B, we’d want resources from account B to be able to call lambda in account A.

We’ve completed creating the authorizer for the gateway now we can go to the resources and enable them to use this authorizer.

To configure this go under the resources option and click on the resource you’d want the validator to run on. Under the method request click the Authorization option and select the authorizer we’ve just created.

This would enable the lambda authorizer on this endpoint.

  • CDK stack with gateway and lambda and setup the lambda as an authz and deploy the stack.

Lambda-based token authorizer provides support for token-based Lambda authorizers. A token-based Lambda authorizer (also called a token authorizer) receives the caller’s identity in a bearer token, such as a JSON Web Token (JWT) or an OAuth token and returns and IAM policy as output.

CDK stack can be created by initializing a cdk project and adding the gateway and the lambda on the stack and attaching the lambda to the endpoint required.

This would initialize the cdk project with typescript as the language.

This would also initialize the entry point of the project.

Now open up lib/CdkWorkshopStack which contains the stack and edit it to add the gateway and the lambda.

The following code attaches a token-based Lambda authorizer to the ‘GET’ Method of the Book resource:

and now run and build and deploy

Congratulations!! you now have an API deployed with the authz lambda. You can view the newly created resources under cloudformation.

--

--

Kumar Harshit
0 Followers

Developer at Poppulo and a part-time music producer @Undertow