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.
Before we dive in, let's quickly remind ourselves how API Gateway and Lambda work together.
API Gatewayacts as the front door for your application. It receives HTTP requests from users.Lambda functionsare 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.
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:
- A user sends a request to your API Gateway endpoint.
- API Gateway calls your Lambda authorizer function first.
- The authorizer checks for a valid token (like a password).
- If the token is valid, the request is allowed to reach your protected Lambda function.
- 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:
Let's build the Lambda authorizer function together, step by step.
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:
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
effectto"Allow"and mark the user as valid. - Otherwise, we set
effectto"Deny"and mark the user as anonymous.
Example Output:
or
Finally, we need to return a policy document that tells API Gateway what to do.
- The
policyDocumenttells API Gateway to allow or deny the request. - The
principalIdis just an identifier for the user.
Example Output:
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-Typeheaders 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:
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 theAWS SAM CLIto 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-apito test your functions locally. -
Testing Different Scenarios:
After deployment, you can test your API endpoint with different tokens:- No
Authorizationheader: 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).
- No
Example Test Results:
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!
