DEV Community

Cover image for Securing Your API with a Lambda Authorizer (JWT Validation) in AWS SAM
Márcio Coelho
Márcio Coelho

Posted on

Securing Your API with a Lambda Authorizer (JWT Validation) in AWS SAM

When building serverless APIs, security is critical. One common way to secure APIs is by requiring clients to present a JWT token.
AWS API Gateway supports Lambda Authorizers, allowing you to write custom authorization logic using a Lambda function.

In today's post, we’ll cover:

  • What is a Lambda Authorizer?
  • How to build a simple Lambda Authorizer with Node.js
  • How to connect it to your API Gateway with AWS SAM

🧠 What Is a Lambda Authorizer?

A Lambda Authorizer is a Lambda function that AWS API Gateway calls before forwarding the request to your main Lambda handler.

It can:

  • Validate a JWT token
  • Verify user roles/permissions
  • Allow or deny access based on custom logic

You can write the logic yourself, giving you maximum flexibility compared to built-in IAM or Cognito authorizers.

🛠 Step 1: Create the Authorizer Lambda

Here’s a simple authorizer.ts example:

import { APIGatewayTokenAuthorizerEvent, APIGatewayAuthorizerResult } from "aws-lambda"; import { Logger } from "@aws-lambda-powertools/logger"; import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import jwt from "jsonwebtoken"; const ssmClient = new SSMClient(); const logger = new Logger(); const secretName = process.env.SECRET_NAME! const generatePolicy = (principalId, effect, resource) => ({ principalId, policyDocument: { Version: '2012-10-17', Statement: [ { Action: 'execute-api:Invoke', Effect: effect, Resource: resource, }, ], }, }); export const handler = async (event: APIGatewayTokenAuthorizerEvent): Promise<APIGatewayAuthorizerResult> => { const token = event.authorizationToken if (!token) { throw new Error("Unauthorized"); } const command = new GetParameterCommand({ Name: secretName, WithDecryption: true }); const response = await ssmClient.send(command); const secret = response.Parameter!.Value!; try { const decoded = jwt.verify(token, secret); return generatePolicy('user', 'Allow', event.methodArn); } catch (error) { logger.error("JWT verification failed", err); throw new Error("Unauthorized"); } }; 
Enter fullscreen mode Exit fullscreen mode

📜 Step 2: Define the Authorizer in template.yml

Resources: AuthorizerFunction: Type: AWS::Serverless::Function Properties: Handler: authorizer.handler Runtime: nodejs22.x Environment: Variables: JWT_SECRET: "your-secret-here" Policies: - Statement: Effect: Allow Action: - ssm:GetParameter Resource: "[path-to-resource]" HelloWorldFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs22.x Events: HelloWorldApi: Type: Api Properties: Path: /hello Method: get RestApiId: !Ref MyApi MyApi: Type: AWS::Serverless::Api Properties: StageName: prod Auth: DefaultAuthorizer: LambdaAuthorizer Authorizers: LambdaAuthorizer: FunctionArn: !GetAtt AuthorizerFunction.Arn 
Enter fullscreen mode Exit fullscreen mode

⚡️ Bonus Tip: HTTP API + JWT Authorizers

If you're using HTTP API instead of REST API, you can configure a JWT Authorizer without needing a custom Lambda Authorizer — built-in, easier, and faster!

Resources: MyHttpApi: Type: AWS::Serverless::HttpApi Properties: Auth: Authorizers: MyJwtAuthorizer: JwtConfiguration: issuer: https://your-issuer.com audience: - your-audience IdentitySource: "$request.header.Authorization" DefaultAuthorizer: MyJwtAuthorizer 
Enter fullscreen mode Exit fullscreen mode

✅ Benefits:

  • No Lambda function to maintain
  • Faster authentication (native integration)
  • Lower cost

Conclusion

Using Lambda Authorizers with JWT gives you powerful, flexible API security.

✅ Now your API is secured with a custom Lambda Authorizer that verifies JWT tokens.
✅ Full control over authentication and authorization.
✅ For simple cases, prefer HTTP API + Native JWT authorizers for speed and simplicity

Top comments (0)