This repository provides a set of reusable Lambda Authorizer implementations for securing APIs on AWS using API Gateway, JWTs, and optional third-party identity providers like Google. It serves as a knowledge base and a proof of concept (PoC) starter kit for developers building stateless, serverless APIs with access control.
The repository includes the following key Lambda Authorizer implementations:
jwt_auth_token.py– Validates custom JWTs using a shared secret (HS256).jwt_auth_token_websocket.py– Adapts JWT validation for WebSocket connections.jwt_auth_token_google.py– Validates Google-issued ID tokens (OAuth 2.0).
Supporting functions:
restricted_access_lambda.py– A basic protected endpoint returning a timestamp.jwt_create_token.py– Authenticates users and generates signed JWTs.create_password.py– A utility script to hash plaintext passwords for DynamoDB.
Additionally, a Dockerfile is included for generating Lambda Layers with external dependencies.
| Feature | jwt_auth_token.py |
jwt_auth_token_websocket.py |
jwt_auth_token_google.py |
|---|---|---|---|
| Use case | REST API with custom JWTs | WebSocket $connect authorizer |
REST API using Google Identity Services |
| Token format | HS256-signed JWT | HS256-signed JWT | Google ID token (OAuth 2.0) |
| Token validation method | jwt.decode() |
jwt.decode() |
google.oauth2.id_token.verify_oauth2_token() |
| Token source | authorizationToken |
headers['Authorization'] |
authorizationToken |
| Env variable(s) | JWT_SECRET |
JWT_SECRET |
GOOGLE_CLIENT_ID |
| Resource ARN filtering | Yes | No (always allows $connect) |
Yes, using fnmatch pattern matching |
| Context values | user_id, authorized |
userId |
email, authorized |
- Name:
user_credentials - Primary key:
user_id(String)
- Returns HTTP 200 with current timestamp.
-
Environment variables:
USER_CREDENTIALS_TABLE_NAME = user_credentialsJWT_SECRET = <your_secret>
-
Permissions:
- DynamoDB read access
- CloudWatch logging
-
Environment variable:
JWT_SECRET = <your_secret>
-
Environment variable:
GOOGLE_CLIENT_ID = <your_client_id>
-
Environment variable:
JWT_SECRET = <your_secret>
- Local utility for generating bcrypt hashes
- /auth (POST):
jwt_create_token - /api (GET):
restricted_access_lambda(protected by one of the Lambda Authorizers)
- Name: e.g.,
protect_lambda - Token source:
Authorizationheader - Attached to
/apiendpoint
- Set
$connectroute to usejwt_auth_token_websocketas an authorizer
This repository includes two separate requirements files depending on the type of Lambda Authorizer you're using:
requirements_basic_auth.txt: Use forjwt_auth_token.py,jwt_auth_token_websocket.py, andjwt_create_token.pyrequirements_google_auth.txt: Use forjwt_auth_token_google.py
To avoid editing the Dockerfile, rename the desired requirements file to requirements.txt:
cp requirements_basic_auth.txt requirements.txt # For basic/custom JWT
# OR
cp requirements_google_auth.txt requirements.txt # For Google ID token validationdocker --version
docker psdocker build -t lambda_layer .docker run --name my_lambda_layer_container lambda_layer
docker cp my_lambda_layer_container:/home/python_dependencies.zip .docker stop my_lambda_layer_container
docker rm my_lambda_layer_container
docker rmi lambda_layerUpload python_dependencies.zip to Lambda as a layer.
curl -X POST <invoke_url>/auth -d '{"user_id": "testuser", "password": "password123"}'curl -H "Authorization: Bearer <jwt_token>" <invoke_url>/api- Use strong secrets (
JWT_SECRET,GOOGLE_CLIENT_ID) and store them securely - Restrict IAM permissions to minimum required
- Avoid wildcard ARNs in production unless scoped appropriately
- Always validate JWT claims such as
aud,exp,iss, andemail_verified