Amazon Cognito M2M Token Management - Cost Optimization Through Caching
Optimizing authentication costs when third-party partners can't implement token caching best practices
1. The Challenge
Third-party partners repeatedly request new Cognito M2M tokens for every API call, instead of reusing existing valid tokens. This practice leads to excessive authentication costs. We requested that they cache the tokens, but we lack the authority to influence their development.
Current Third-Party Integration Pattern
The Integration Challenge: Partners request new tokens for every API call instead of implementing token reuse, resulting in excessive authentication costs.
Business Impact Analysis
Scenario: 3 third-party integrations, 10,000 API calls each/day
Current Cost: 3 partners × 10,000 token requests × 30 days × $0.00225 = $2,025/month
The Cost Problem: Partners request new tokens for every API call instead of reusing valid tokens (which last 1 hour), resulting in unnecessary authentication costs that could be reduced by 99.9% through proper token caching.
With Caching Solution:
- Token requests needed: ~720/month (1 token per hour per partner)
- Cognito cost: 720 × $0.00225 = $1.62/month
- Monthly savings: $2,023.38 (99.9% reduction)
2. Solution Architecture & Implementation
Flow Diagram
Detailed Architecture Components
Architecture Components
The solution uses serverless architecture with four main components. API Gateway receives partner requests and handles authentication before routing to Lambda. Lambda Token Service manages the complete caching flow by checking DynamoDB cache first, then retrieving credentials and requesting new tokens from Cognito only when needed. DynamoDB provides both partner configuration storage and token caching with automatic TTL cleanup after 1 hour. Amazon Cognito User Pool issues JWT tokens using client credentials grant flow.
Key Benefits: Fully managed caching with automatic cleanup, pay-per-request pricing, single-digit millisecond cache response times, and centralized authentication control.
Example Data in DynamoDB Tables
TokenCache Table Sample Data:
{ "cache_key": "partner-abc_token", "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "partner_id": "partner-abc", "created_at": "2024-07-20T10:30:00Z", "ttl": 1721473800 }
PartnerConfig Table Sample Data:
{ "partner_id": "partner-abc", "partner_name": "ABC Corporation", "cognito_client_id": "7a8b9c0d1e2f3g4h5i6j7k8l9m0n1o2p", "cognito_client_secret": "AbCdEfGhIjKlMnOpQrStUvWxYz0123456789...", "user_pool_id": "us-east-1_AbCdEfGhI", "token_endpoint": "https://your-domain.auth.us-east-1.amazoncognito.com/oauth2/token", "scopes": ["read:api", "write:api"], "status": "active", "rate_limit": 1000 }
Sequence Diagram
First Request (Cache Miss)
Subsequent Requests (Cache Hit)
3. Deployment Process
This solution can be deployed in under 30 minutes using the complete CloudFormation template provided in the Appendix. The template creates all necessary AWS resources with proper IAM permissions and configurations.
Prerequisites
- AWS CLI configured with appropriate permissions
Quick Deployment Steps
-
Download the CloudFormation template:
cognito-m2m-cache-template.yaml -
Deploy the stack using AWS CLI:
aws cloudformation create-stack \ --stack-name cognito-m2m-token-cache \ --template-body file://cognito-m2m-cache-template.yaml \ --capabilities CAPABILITY_IAM \ --region us-east-1
- Wait for stack creation (approximately 5-10 minutes):
aws cloudformation wait stack-create-complete \ --stack-name cognito-m2m-token-cache \ --region us-east-1
- Get the stack outputs for configuration:
aws cloudformation describe-stacks \ --stack-name cognito-m2m-token-cache \ --query 'Stacks[0].Outputs' \ --region us-east-1
- Create Cognito domain for OAuth endpoints (required for client credentials grant):
# Get User Pool ID from step 4 outputs USER_POOL_ID=$(aws cloudformation describe-stacks \ --stack-name cognito-m2m-token-cache \ --query 'Stacks[0].Outputs[?OutputKey==`CognitoUserPoolId`].OutputValue' \ --output text \ --region us-east-1) # Create domain with unique name aws cognito-idp create-user-pool-domain \ --user-pool-id $USER_POOL_ID \ --domain "m2m-token-$(date +%Y%m%d%H%M)" \ --region us-east-1
- Get Cognito client secret (needed for partner configuration):
# Get Client ID from step 4 outputs CLIENT_ID=$(aws cloudformation describe-stacks \ --stack-name cognito-m2m-token-cache \ --query 'Stacks[0].Outputs[?OutputKey==`CognitoClientId`].OutputValue' \ --output text \ --region us-east-1) # Get client secret aws cognito-idp describe-user-pool-client \ --user-pool-id $USER_POOL_ID \ --client-id $CLIENT_ID \ --query 'UserPoolClient.ClientSecret' \ --output text \ --region us-east-1
- Add partner configuration to DynamoDB:
# Set variables from previous steps CLIENT_SECRET="your-client-secret-from-step-6" DOMAIN_NAME="your-domain-from-step-5" # Add partner configuration aws dynamodb put-item \ --table-name PartnerConfig \ --item '{ "partner_id": {"S": "test-partner-001"}, "partner_name": {"S": "Test Partner Organization"}, "cognito_client_id": {"S": "'$CLIENT_ID'"}, "cognito_client_secret": {"S": "'$CLIENT_SECRET'"}, "cognito_domain": {"S": "'$DOMAIN_NAME'"}, "scopes": {"SS": ["token-service-api/read", "token-service-api/write", "token-service-api/cache"]}, "status": {"S": "active"}, "created_at": {"S": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"} }' \ --region us-east-1
Stack Outputs
After successful deployment, the CloudFormation stack provides these outputs:
- TokenServiceUrl: API Gateway endpoint for token requests
- CognitoUserPoolId: Created Cognito User Pool ID
- CognitoClientId: Created Cognito Client ID
- PartnerConfigTableName: DynamoDB table name for partner configuration
4. Testing and Validation
This section provides step-by-step validation to prove the token caching solution works correctly and delivers the expected cost optimization.
Test Setup
Before testing, ensure you have:
- Deployed CloudFormation stack successfully
- Created Cognito domain for OAuth endpoints
- Added partner configuration to DynamoDB with real client credentials
- Token Service URL from stack outputs
Test 1: Cache Miss (First Request)
Purpose: Validate that the first token request fetches from Cognito and stores in cache.
- Make the first token request:
# Use the Token Service URL from your stack outputs curl -X GET "https://your-api-gateway-url/token?partner_id=test-partner-001" \ -H "Content-Type: application/json"
- Expected Response (Real JWT Token):
{ "access_token": "eyJraWQiOiJjcFBNXC9cLzQ1dEI0SThPVWxxNVByUlRUTllkSEJnU09vWUpCcXZCYkgxN1k9IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI3MHFrbTNmY3ExcHVpN204c2F1YzhvNGdmNCIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoidG9rZW4tc2VydmljZS1hcGlcL3JlYWQgdG9rZW4tc2VydmljZS1hcGlcL3dyaXRlIHRva2VuLXNlcnZpY2UtYXBpXC9jYWNoZSIsImF1dGhfdGltZSI6MTc1MzAzMzQ4MiwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfR0RSNHVCWFJiIiwiZXhwIjoxNzUzMDM3MDgyLCJpYXQiOjE3NTMwMzM0ODIsInZlcnNpb24iOjIsImp0aSI6IjIxY2EzMTQwLTUzN2QtNDYyZS1hN2JmLWRiZjNmZjQwNzQ5ZSIsImNsaWVudF9pZCI6IjcwcWttM2ZjcTFwdWk3bThzYXVjOG80Z2Y0In0.WyZCA8L7cwZJ-bBDNBw9NYsczerX_sniXAtCnMmzYYEVoQ-6VX0gAIHe2oqpHefG0fOx9nYyaLcnyhTuEnJW00WMS03gHRhcCUH0gF1QcOzpsPYoYCiqSj3Mz9JXjEfZit4Agk1D9BBLsCj4Ke6wRygzdl8J0Ub6fdKB6z1tkaImPbee-houHGa0SRQm8sY3XUc29EwBDEzsUkfGLYjbCLvlc8cBZvifnN4ifhtCSzRdWxCVB07hsRHQs559G0gfaqz1p_Bxwg9upuYB9LCtAbBMebRXSfT3pByao8DY14pOwU6C1N3l_URDYqQ9gI--YTTo_9iU4dbx5-qUbe0L4w", "source": "cognito", "timestamp": "2025-07-20T17:44:42.770467" }
- Success Criteria**: Response shows
"source": "cognito"and a real JWT token is returned and stored in DynamoDB cache.
JWT Token Structure
The returned access token is a valid JWT with the following structure when decoded:
{ "sub": "70qkm3fcq1pui7m8sauc8o4gf4", "token_use": "access", "scope": "token-service-api/read token-service-api/write token-service-api/cache", "auth_time": 1753033482, "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_GDR4uBXRb", "exp": 1753037082, "iat": 1753033482, "version": 2, "jti": "21ca3140-537d-462e-a7bf-dbf3ff40749e", "client_id": "70qkm3fcq1pui7m8sauc8o4gf4" }
Key JWT Claims:
scope: Contains the authorized scopes for the tokenexp: Token expiration time (1 hour from issuance)iss: Cognito User Pool issuer URLclient_id: The M2M client identifier
Test 2: Cache Hit (Subsequent Requests)
Purpose: Validate that subsequent requests return cached tokens without calling Cognito.
- Make the same token request immediately:
curl -X GET "https://your-api-gateway-url/token?partner_id=test-partner-001" \ -H "Content-Type: application/json"
- Expected Response (Same JWT Token from Cache):
{ "access_token": "[example-token]", "source": "cache", "timestamp": "2025-07-20T17:45:00.690223" }
- Success Criteria**: Response shows
"source": "cache"and the exact same JWT token value as Test 1, proving the token was retrieved from DynamoDB cache instead of making a new Cognito request.
Test 3: Direct OAuth 2.0 Verification
Purpose: Verify that the OAuth 2.0 client credentials flow works directly with Cognito.
- Test direct Cognito authentication:
# Get credentials from your DynamoDB PartnerConfig table CLIENT_ID="your-client-id" CLIENT_SECRET="your-client-secret" DOMAIN="your-cognito-domain" curl -X POST \ "https://$DOMAIN.auth.us-east-1.amazoncognito.com/oauth2/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -d "grant_type=client_credentials&scope=token-service-api/read token-service-api/write token-service-api/cache"
- Expected Response:
{ "access_token": "[example-token]...", "expires_in": 3600, "token_type": "Bearer" }
- Success Criteria**: Valid JWT token returned with 1-hour expiration.
Test 4: Performance Validation
Purpose: Measure response time improvement with caching.
Steps: Measure cache miss vs cache hit response times using the time command with curl requests to the same endpoint.
# Measure cache miss (first request) time curl -X GET "https://your-api-gateway-url/token?partner_id=test-partner-001" # Measure cache hit (subsequent request) time curl -X GET "https://your-api-gateway-url/token?partner_id=test-partner-001"
- Success Criteria**: Cache hit should be significantly faster (typically 50-80% reduction in response time).
Expected Results Summary
| Test Scenario | Expected Outcome | Performance Impact | Example Response Time |
|---|---|---|---|
| First Request (Cache Miss) | "source": "cognito" | Full Cognito authentication | ~1-2 seconds |
| Subsequent Requests (Cache Hit) | "source": "cache" | DynamoDB cache retrieval | ~200-500ms |
| Direct OAuth Test | Valid JWT with scopes | Baseline Cognito performance | ~800ms-1.5s |
| Cost per 1000 API calls | 1 Cognito call + 999 cache hits | 99.9% cost reduction | N/A |
5. Conclusion
This centralized token caching solution addresses the cost optimization challenge when third-party partners don't implement proper token reuse practices.
Cost Impact Summary:
- Before: 3 partners × 10,000 API calls/day × 30 days × $0.00225 = $2,025/month
- After: Complete solution cost breakdown:
- Cognito M2M tokens: 720 requests × $0.00225 = $1.62/month
- API Gateway requests: 900,000 × $0.0000035 = $3.15/month
- Lambda executions: 900,000 × $0.0000002 = $0.18/month
- DynamoDB operations: ~1,800 reads × $0.00000025 = $0.0005/month
- Total monthly cost: ~$5.00
Key Achievements:
- $2,020/month savings (99.75% cost reduction)
- Eliminates dependency on partner development teams
- Provides centralized authentication control and monitoring
- Maintains security best practices with 1-hour token expiration
- Scales automatically with serverless architecture
6. Appendix: CloudFormation Template
The complete CloudFormation (US-EAST-1):
AWSTemplateFormatVersion: '2010-09-09' Description: 'Cognito M2M Token Caching Service - Fixed Configuration for Client Credentials Grant' Resources: # Cognito User Pool for M2M authentication TestUserPool: Type: AWS::Cognito::UserPool Properties: UserPoolName: 'cognito-m2m-test-pool' Policies: PasswordPolicy: MinimumLength: 8 # Resource Server - Required for client credentials grant TokenServiceResourceServer: Type: AWS::Cognito::UserPoolResourceServer Properties: UserPoolId: !Ref TestUserPool Identifier: 'token-service-api' Name: 'Token Service API' Scopes: - ScopeName: 'read' ScopeDescription: 'Read access to token service' - ScopeName: 'write' ScopeDescription: 'Write access to token service' - ScopeName: 'cache' ScopeDescription: 'Access to token cache operations' # User Pool Client configured for M2M with client credentials grant TestUserPoolClient: Type: AWS::Cognito::UserPoolClient DependsOn: TokenServiceResourceServer Properties: UserPoolId: !Ref TestUserPool ClientName: 'test-m2m-client' GenerateSecret: true # Remove ExplicitAuthFlows - not needed for M2M # Use AllowedOAuthFlows for client credentials grant AllowedOAuthFlows: - client_credentials AllowedOAuthFlowsUserPoolClient: true AllowedOAuthScopes: - token-service-api/read - token-service-api/write - token-service-api/cache # Token validity settings AccessTokenValidity: 1 TokenValidityUnits: AccessToken: hours # DynamoDB Tables with encryption TokenCacheTable: Type: AWS::DynamoDB::Table Properties: TableName: 'TokenCache' BillingMode: PAY_PER_REQUEST AttributeDefinitions: - AttributeName: cache_key AttributeType: S KeySchema: - AttributeName: cache_key KeyType: HASH TimeToLiveSpecification: AttributeName: ttl Enabled: true SSESpecification: SSEEnabled: true SSEType: KMS KMSMasterKeyId: alias/aws/dynamodb PointInTimeRecoverySpecification: PointInTimeRecoveryEnabled: true Tags: - Key: Purpose Value: TokenCaching - Key: Environment Value: Test PartnerConfigTable: Type: AWS::DynamoDB::Table Properties: TableName: 'PartnerConfig' BillingMode: PAY_PER_REQUEST AttributeDefinitions: - AttributeName: partner_id AttributeType: S KeySchema: - AttributeName: partner_id KeyType: HASH SSESpecification: SSEEnabled: true SSEType: KMS KMSMasterKeyId: alias/aws/dynamodb PointInTimeRecoverySpecification: PointInTimeRecoveryEnabled: true Tags: - Key: Purpose Value: PartnerConfiguration - Key: Environment Value: Test # Lambda Execution Role with least privilege TokenServiceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: DynamoDBAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - dynamodb:GetItem - dynamodb:PutItem - dynamodb:UpdateItem Resource: - !GetAtt TokenCacheTable.Arn - !GetAtt PartnerConfigTable.Arn - PolicyName: CognitoAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - cognito-idp:InitiateAuth Resource: !GetAtt TestUserPool.Arn - PolicyName: CloudWatchLogs PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/TokenService:*' # Lambda Function with updated runtime TokenServiceFunction: Type: AWS::Lambda::Function Properties: FunctionName: 'TokenService' Runtime: python3.12 Handler: index.lambda_handler Role: !GetAtt TokenServiceRole.Arn Timeout: 30 Environment: Variables: TOKEN_CACHE_TABLE: !Ref TokenCacheTable PARTNER_CONFIG_TABLE: !Ref PartnerConfigTable COGNITO_USER_POOL_ID: !Ref TestUserPool COGNITO_CLIENT_ID: !Ref TestUserPoolClient COGNITO_DOMAIN: !Sub '${TestUserPool}.auth.${AWS::Region}.amazoncognito.com' Code: ZipFile: | import json import boto3 import os import logging from datetime import datetime, timedelta import base64 import urllib.request import urllib.error import urllib.parse # Configure logging logger = logging.getLogger() logger.setLevel(logging.INFO) dynamodb = boto3.resource('dynamodb') def lambda_handler(event, context): try: logger.info(f"Received event: {json.dumps(event)}") # Extract partner_id from query parameters query_params = event.get('queryStringParameters') or {} partner_id = query_params.get('partner_id') if not partner_id: return error_response(400, 'Missing partner_id parameter') cache_key = f"{partner_id}_token" # Check cache first cached_token = get_cached_token(cache_key) if cached_token: logger.info(f"Token found in cache for partner: {partner_id}") return success_response(cached_token, 'cache') # Cache miss - get partner configuration partner_config = get_partner_config(partner_id) if not partner_config: logger.warning(f"Partner configuration not found: {partner_id}") return error_response(404, 'Partner configuration not found') # Get new token using client credentials grant token = get_cognito_token_client_credentials() if not token: return error_response(500, 'Failed to obtain token from Cognito') # Store in cache store_token_cache(cache_key, token, partner_id) logger.info(f"New token obtained and cached for partner: {partner_id}") return success_response(token, 'cognito') except Exception as e: logger.error(f"Error processing request: {str(e)}") return error_response(500, 'Internal server error') def get_cached_token(cache_key): table = dynamodb.Table(os.environ['TOKEN_CACHE_TABLE']) try: response = table.get_item(Key={'cache_key': cache_key}) if 'Item' in response: # Check if token is still valid (not expired) ttl = response['Item'].get('ttl', 0) if ttl > int(datetime.now().timestamp()): return response['Item']['token'] else: logger.info(f"Cached token expired for key: {cache_key}") except Exception as e: logger.error(f"Error retrieving cached token: {str(e)}") return None def get_partner_config(partner_id): table = dynamodb.Table(os.environ['PARTNER_CONFIG_TABLE']) try: response = table.get_item(Key={'partner_id': partner_id}) return response.get('Item') except Exception as e: logger.error(f"Error retrieving partner config: {str(e)}") return None def get_cognito_token_client_credentials(): try: # Get partner configuration to retrieve client credentials partner_config = get_partner_config("test-partner-001") # In production, this would be dynamic if not partner_config: logger.error("Partner configuration not found for token request") return None # Prepare OAuth 2.0 client credentials request client_id = partner_config['cognito_client_id'] client_secret = partner_config['cognito_client_secret'] domain = partner_config.get('cognito_domain', 'default-domain') token_url = f"https://{domain}.auth.us-east-1.amazoncognito.com/oauth2/token" # Prepare request data data = "grant_type=client_credentials&scope=token-service-api/read token-service-api/write token-service-api/cache" # Create Basic Auth header import base64 credentials = f"{client_id}:{client_secret}" encoded_credentials = base64.b64encode(credentials.encode()).decode() # Make the OAuth request req = urllib.request.Request( token_url, data=data.encode(), headers={ 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': f'Basic {encoded_credentials}' } ) with urllib.request.urlopen(req) as response: response_data = json.loads(response.read().decode()) access_token = response_data.get('access_token') if access_token: logger.info("Successfully obtained access token from Cognito") return access_token else: logger.error("No access token in Cognito response") return None except urllib.error.HTTPError as e: logger.error(f"HTTP error obtaining Cognito token: {e.code} - {e.read().decode()}") return None except Exception as e: logger.error(f"Error obtaining Cognito token: {str(e)}") return None def store_token_cache(cache_key, token, partner_id): table = dynamodb.Table(os.environ['TOKEN_CACHE_TABLE']) # Set TTL to 50 minutes (token expires in 1 hour) ttl = int((datetime.now() + timedelta(minutes=50)).timestamp()) try: table.put_item( Item={ 'cache_key': cache_key, 'token': token, 'partner_id': partner_id, 'ttl': ttl, 'created_at': datetime.now().isoformat() } ) logger.info(f"Token cached successfully for partner: {partner_id}") except Exception as e: logger.error(f"Error storing token in cache: {str(e)}") def success_response(token, source): return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, 'body': json.dumps({ 'access_token': token, 'source': source, 'timestamp': datetime.now().isoformat() }) } def error_response(status_code, message): return { 'statusCode': status_code, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, 'body': json.dumps({ 'error': message, 'timestamp': datetime.now().isoformat() }) } # API Gateway with throttling TokenServiceApi: Type: AWS::ApiGateway::RestApi Properties: Name: 'TokenService' Description: 'M2M Token Caching Service API' EndpointConfiguration: Types: - REGIONAL TokenResource: Type: AWS::ApiGateway::Resource Properties: RestApiId: !Ref TokenServiceApi ParentId: !GetAtt TokenServiceApi.RootResourceId PathPart: token TokenMethod: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref TokenServiceApi ResourceId: !Ref TokenResource HttpMethod: GET AuthorizationType: NONE Integration: Type: AWS_PROXY IntegrationHttpMethod: POST Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TokenServiceFunction.Arn}/invocations' MethodResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Origin: true # CORS Options method TokenOptionsMethod: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref TokenServiceApi ResourceId: !Ref TokenResource HttpMethod: OPTIONS AuthorizationType: NONE Integration: Type: MOCK IntegrationResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'" method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" RequestTemplates: application/json: '{"statusCode": 200}' MethodResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true method.response.header.Access-Control-Allow-Origin: true ApiDeployment: Type: AWS::ApiGateway::Deployment DependsOn: - TokenMethod - TokenOptionsMethod Properties: RestApiId: !Ref TokenServiceApi StageName: 'dev' # API Gateway throttling ApiUsagePlan: Type: AWS::ApiGateway::UsagePlan DependsOn: ApiDeployment Properties: UsagePlanName: 'TokenServiceUsagePlan' Description: 'Usage plan for Token Service API' ApiStages: - ApiId: !Ref TokenServiceApi Stage: 'dev' Throttle: BurstLimit: 100 RateLimit: 50 Quota: Limit: 10000 Period: DAY # Lambda Permission for API Gateway LambdaApiPermission: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref TokenServiceFunction Action: lambda:InvokeFunction Principal: apigateway.amazonaws.com SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${TokenServiceApi}/*/*' Outputs: TokenServiceUrl: Description: 'Token Service API Gateway URL' Value: !Sub 'https://${TokenServiceApi}.execute-api.${AWS::Region}.amazonaws.com/dev/token' Export: Name: !Sub '${AWS::StackName}-TokenServiceUrl' CognitoUserPoolId: Description: 'Created Cognito User Pool ID' Value: !Ref TestUserPool Export: Name: !Sub '${AWS::StackName}-UserPoolId' CognitoClientId: Description: 'Created Cognito Client ID' Value: !Ref TestUserPoolClient Export: Name: !Sub '${AWS::StackName}-ClientId' ResourceServerId: Description: 'Created Resource Server ID' Value: !Ref TokenServiceResourceServer Export: Name: !Sub '${AWS::StackName}-ResourceServerId' PartnerConfigTableName: Description: 'DynamoDB table name for partner configuration' Value: !Ref PartnerConfigTable Export: Name: !Sub '${AWS::StackName}-PartnerConfigTable' TokenCacheTableName: Description: 'DynamoDB table name for token cache' Value: !Ref TokenCacheTable Export: Name: !Sub '${AWS::StackName}-TokenCacheTable'
⚠️ Remember to clean up test resources after validation to avoid ongoing costs!
- Language
- English
Would it be feasible to implement API Gateway caching to reduce repeated calls to Lambda functions or DynamoDB tables, thereby improving performance and lowering costs?”
replied 7 months ago
Relevant content
- Accepted Answer
asked 3 years ago
AWS OFFICIALUpdated 2 years ago