This pattern creates an AWS CDK Python application to access Bedrock via API Gateway with Cognito user management, domain restriction, API request throttling, and quota limits.
Learn more about this pattern at Serverless Land Patterns: << Add the live URL here >>
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the AWS Pricing page for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
- Create an AWS account if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
- Install and Configure AWS CLI
- Install Git
- Install Node and NPM
- Install AWS Cloud Development Kit (AWS CDK)
- Install Python 3
- Install Docker
- Grant Bedrock Model Access
- Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
git clone https://github.com/aws-samples/serverless-patterns
- Change directory to the pattern directory:
cd apigw-bedrock-cognito-cdk
- Create a virtual environment for Python:
python3 -m venv .venv
- Activate the virtual environment:
For a Windows platform, activate the virtualenv like this:
source .venv/bin/activate
.venv\Scripts\activate.bat
- Install the required Python dependencies:
pip install -r requirements.txt
- Bootstrap the AWS environment, if you haven't already done so:
cdk bootstrap
- Review the CloudFormation template AWS CDK generates for the stack:
cdk synth
- Deploy the AWS resources:
Optionally you can add the optional variables using the
cdk deploy
--context
, see API Gateway Configuration and Cognito Integration and Configuration.cdk deploy --context API_THROTTLE_RATE_LIMIT=1 --context API_THROTTLE_BURST_LIMIT=2 --context API_QUOTA_LIMIT=25 --context API_QUOTA_PERIOD=DAY --context ORGANIZATION_DOMAIN=@example.com
- Note the outputs from the CDK deployment process. These contain the resource names and/or ARNs which are used for testing.
This pattern deploys an Amazon API Gateway REST API with the following routes: POST /register
, POST /login
, GET
and POST /bedrock
. It includes a Amazon Cognito User Pool and Lambdas to handle requests from the API Gateway. The API Gateway allows CORS for all origins and methods, incorporates an Usage Plan, and has throttle and quota limits for the /bedrock
endpoint. The /bedrock
endpoint allows access to Amazon Bedrock Foundation models.
-
/register
endpoint: Acceptsemail
,password
, andfullname
in the body, interacts with a proxy lambda integration to register users to the Cognito User Pool. Returns an API Key which will be associated with the API Gateway's usage plan and stored within the Cognito user's customapi_key
field . If an organization domain is specified in theORGANIZATION_DOMAIN
context variable, a pre signup lambda is provisioned to reject users not belonging to the specified domain. -
/login
endpoint: Acceptsemail
andpassword
in the body, interacts with a proxy lambda integration to authenticate the user. Returns an bearer token, containingIdToken
,AccessToken
,RefreshToken
and other metadata. If the user loses their API key, they can decrypt theIdToken
using jwt.io or other libraries to retrieve the API key from thecustom:api_key
field. -
/bedrock
endpoint: Protected with a Cognito authorizer to ensure only requests with validAuthorization
andx-api-key
tokens in headers can access the endpoint, interacts with a proxy lambda integration. AGET
request lists all foundation models, and aPOST
request takesmodelId
andinferenceParameters
in the body, to invoke and return response from the foundation model.
- CORS: Enabled for all origins and methods.
- Usage Plan: Configured to manage API access.
- Throttle Limits: Rate limit of 1 request per second with a burst limit of 2 requests.
- Quota Limits: Set to 25 requests per day for the
/bedrock
endpoint. - These limits can be modified during deployment using context variables (
API_THROTTLE_RATE_LIMIT
,API_THROTTLE_BURST_LIMIT
,API_QUOTA_LIMIT
,API_QUOTA_PERIOD
) - Logging: Enabled for all Error and Info request logs.
- User Pool: Manages user registration and login.
- Organization Domain Restriction: The organization domain restriction can be adjusted during deployment using the context variable
ORGANIZATION_DOMAIN
. A Pre SignUp Lambda trigger will be added to enforce specific domain restrictions.
bedrock.py
:- Uses the
boto3
library to make API calls to Amazon Bedrock APIs. - Utilizes the
jsonpath_ng
library to dynamically map and retrieve responses from foundation models provided by Anthropic, AI21 Labs, Amazon, and Meta.
- Uses the
auth.py
:- Uses the
boto3
library to make API calls to Amazon Cognito and Amazon API Gateway. - Manages user creation, login, and the creation and association of API keys.
- Uses the
pre_signup.py
(if valid):- Validates user email domain during registration.
- All Lambda Configuration:
- Timeout: Set to 29 second due to maximum integration timeout limit - Amazon API Gateway Limits.
- Logging: All events are logged to Amazon CloudWatch, with a custom redaction function to remove passwords from the
auth.py
Lambda prior to logging.
-
Register User
- Request Body:
{ "email": "user@example.com", "password": "securePassword123", "fullname": "John Doe" }
- Response Body:
{ "status": 200, "message": "User user@example.com created successfully.", "data": {"API Key": "generatedApiKey"}, "success": true, }
- Request Body:
-
Login User
- Request Body:
{ "email": "user@example.com", "password": "securePassword123" }
- Response Body:
{ "status": 200, "IdToken": "generatedIdToken", "AccessToken": "generatedAccessToken", "RefreshToken": "generatedRefreshToken", "ExpiresIn": 3600, "TokenType": "Bearer", "sucess": true }
- Request Body:
-
Make Bedrock Request
- Request Headers:
- Authorization: Bearer [IdToken]
- x-api-key: [APIKey]
- GET /bedrock Response Body:
{ "status": 200, "foundationModels": [...], "message": "Successfully retrieved foundation models list." }
- POST /bedrock Request Body:
{ "modelId": "exampleModelId", "inferenceParameters": {...} }
- POST /bedrock Response Body:
{ "status": 200, "message": "Successfully retrieved response from foundation model.", "data": "..." }
- Request Headers:
Prior to running the tests, ensure that your account has the necessary access to the following Bedrock models: ai21.j2-mid-v1
, anthropic.claude-instant-v1
, amazon.titan-text-express-v1
, and meta.llama2-13b-chat-v1
. Follow the guide provided in the Requirements - Bedrock model access granted to grant access to these models. Without access, the tests will fail due to insufficient permissions to interact with the foundation models.
- Activate the virtual environment, if you haven't already done so from the deployment instructions:
For a Windows platform, activate the virtualenv like this:
source .venv/bin/activate
.venv\Scripts\activate.bat
- Install the Python required dependencies:
pip install -r requirements-dev.txt
- From the CDK output during the deployment process, obtain the values for Cognito User Pool ID and Rest API Endpoint:
ApigwBedrockCognitoCdkStack.CognitoUserPoolID = us-east-1_XXXXXXXXX ApigwBedrockCognitoCdkStack.RestAPIEndpoint = https://XXXXXXXXX.execute-api.us-east-1.amazonaws.com/prod/
- Update the
API_ENDPOINT
andUSER_POOL_ID
variables intests/e2e/test_apigw_bedrock_cognito_cdk_stack.py
with the obtained values:If organization domain restriction is enabled, modify theAPI_ENDPOINT = "https://XXXXXXXXX.execute-api.us-east-1.amazonaws.com/prod/" USER_POOL_ID = "us-east-1_XXXXXXXXX"
TEST_EMAIL
to be an email with your domain, andNON_ORG_TEST_EMAIL
to an email without your domain:TEST_EMAIL = "johndoe@org.com" NON_ORG_TEST_EMAIL = "johndoe@example.com"
- Execute Pytest:
pytest -v
- Delete the stack:
cdk destroy
- Delete all API Keys:
Before executing the following command, be aware that it will delete all API keys in the account. Ensure you have the necessary backups or are certain of the consequences.
sh utils/delete_all_api_keys.sh
Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0