Introduction: Securing Your API Endpoints

Welcome back! In the previous lesson, you learned how to keep your application's secrets safe using AWS Secrets Manager and IAM roles. Now, we are moving forward to another critical part of application security: protecting your API endpoints.

APIs are the doors to your application's data and features. If you leave them unprotected, anyone can access or misuse your resources. In this lesson, you will learn how to use a Lambda authorizer to control who can access your API Gateway endpoints. By the end, you will have built a real token-based authorization system and seen it in action.

Quick Recall: API Gateway and Lambda Integration

Before we dive in, let's quickly remind ourselves how API Gateway and Lambda work together.

  • API Gateway acts as the front door for your application. It receives HTTP requests from users.
  • Lambda functions are small pieces of code that run in the cloud. API Gateway can send requests to Lambda functions, which then process the request and return a response.

For example, when someone visits your API endpoint, API Gateway forwards the request to your Lambda function, which handles the logic and sends back a result.

This flow is important to remember because we will be adding a security check (the Lambda authorizer) right in the middle of this process.

What Is a Lambda Authorizer?

A Lambda authorizer is a special type of Lambda function that helps API Gateway decide if a request should be allowed or denied. It checks the incoming request for some kind of proof — usually a token — and then tells API Gateway if the request is authorized.

Here's how it works in simple terms:

  1. A user sends a request to your API Gateway endpoint.
  2. API Gateway calls your Lambda authorizer function first.
  3. The authorizer checks for a valid token (like a password).
  4. If the token is valid, the request is allowed to reach your protected Lambda function.
  5. If the token is missing or incorrect, the request is denied.

A common way to send a token is in the Authorization header, like this:

In this lesson, you will build a Lambda authorizer that only accepts the token letmein and denies all other requests.

Here's a visual representation of this authorization flow:

Building the Lambda Authorizer Step-by-Step

Let's build the Lambda authorizer function together, step by step.

1. Extracting the Authorization Header

First, we need to get the Authorization header from the incoming event. The event is a Python dictionary that contains all the request details.

Here's how you can safely extract the header, handling both uppercase and lowercase keys:

  • event.get("headers", {}) gets the headers dictionary from the event. If it's missing, it returns an empty dictionary.
  • We check both "Authorization" and "authorization" to handle different clients.
  • Important: We only log the presence and format (e.g., "Bearer") of the header, never the actual token value. Logging tokens is a security risk.

Example Output:

2. Validating the Bearer Token

Now, let's check if the token is correct. We expect the header to be exactly Bearer letmein.

⚠️ Important Note About Hardcoding:
You might notice we're using a hardcoded token here (EXPECTED_TOKEN = "letmein"). In the previous lesson, you learned that hardcoding secrets is a security risk. You're right to question this! In a real production application, you would absolutely retrieve this token from AWS Secrets Manager using the techniques you learned in Lesson 1. However, for this lesson, we're keeping it simple to focus on understanding how Lambda authorizers work. In the upcoming practices, you'll combine both concepts — using Secrets Manager to retrieve tokens inside your authorizer function. Think of this as learning one concept at a time before putting them together.

  • If the header matches, we set effect to "Allow" and mark the user as valid.
  • Otherwise, we set effect to "Deny" and mark the user as anonymous.

Example Output:

or

3. Returning the IAM Policy

Finally, we need to return a policy document that tells API Gateway what to do.

  • The policyDocument tells API Gateway to allow or deny the request.
  • The principalId is just an identifier for the user.

Example Output:

Protecting and Responding from Your API Handler

Once your Lambda authorizer is set up, you can protect your API endpoint. API Gateway will only forward requests to your protected Lambda function if the authorizer allows it.

Here's a production-ready protected API handler that returns proper JSON:

  • If the request is authorized, this function returns a JSON response with proper Content-Type headers and status code 200.
  • If the request is not authorized, API Gateway will block the request before it reaches this function.
  • Always return JSON and set appropriate headers to follow production best practices.

Example Output:

Deploying and Testing Your Solution

Now that you have both the authorizer and the protected handler, it's time to deploy and test your solution.

  • Deploying with AWS SAM:
    Use the AWS SAM CLI to build and deploy your application. On CodeSignal, the required tools are already installed and configured, so you don't need to worry about setup here.

    Note: When deploying to real AWS accounts, deployments create actual AWS resources (API Gateway, Lambda functions, IAM roles), typically take 2-5 minutes, and may incur small costs (usually under $1 for testing). Always clean up resources after testing to avoid ongoing charges. For local testing without AWS costs, you can use sam local start-api to test your functions locally.

  • Testing Different Scenarios:
    After deployment, you can test your API endpoint with different tokens:

    • No Authorization header: Access should be denied (401 or 403).
    • Wrong token: Access should be denied (401 or 403).
    • Correct token (Bearer letmein): Access should be allowed (200).

Example Test Results:

Summary And What's Next

In this lesson, you learned how to secure your API Gateway endpoints using a Lambda authorizer. You built a function to check for a valid Bearer token, returned the correct IAM policy, and protected your API handler so only authorized requests get through. You also learned important security practices like never logging token values and returning properly formatted JSON responses with correct headers. Finally, you saw how to deploy and test your solution using AWS SAM.

Next, you'll get hands-on practice by completing the code and testing your own Lambda authorizer. This will help you reinforce what you've learned and prepare you for building more secure and robust APIs in the future. Good luck!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal