Skip to main content

Lambda Authorizer Deployment

Deploy the ASCEND Lambda Authorizer to your AWS account using SAM or CloudFormation.

Prerequisites

  • AWS CLI configured with appropriate permissions
  • AWS SAM CLI installed (for SAM deployment)
  • ASCEND API key from the Console

Quick Start with SAM

Step 1: Store API Key in Secrets Manager

aws secretsmanager create-secret \
--name ascend/api-key \
--description "ASCEND Platform API key" \
--secret-string '{"api_key":"owkai_prod_xxxxxxxxxxxx"}'

Note the ARN returned:

arn:aws:secretsmanager:us-east-1:123456789012:secret:ascend/api-key-AbCdEf

Step 2: Deploy with SAM

# Clone the repository
git clone https://github.com/owkai/ascend-lambda-authorizer.git
cd ascend-lambda-authorizer

# Build
sam build

# Deploy (interactive)
sam deploy --guided

Follow the prompts:

Setting default arguments for 'sam deploy'
=========================================
Stack Name [ascend-authorizer]: ascend-authorizer-prod
AWS Region [us-east-1]: us-east-1
Parameter AscendApiUrl [https://api.ascend.owkai.app]:
Parameter AscendApiKeySecret: arn:aws:secretsmanager:us-east-1:123456789012:secret:ascend/api-key-AbCdEf
Parameter Environment [production]: production
Parameter CacheTtlSeconds [60]: 60

Step 3: Attach to API Gateway

After deployment, attach the authorizer to your API Gateway:

# Get the authorizer ARN from stack outputs
AUTHORIZER_ARN=$(aws cloudformation describe-stacks \
--stack-name ascend-authorizer-prod \
--query 'Stacks[0].Outputs[?OutputKey==`AuthorizerFunctionArn`].OutputValue' \
--output text)

# Create authorizer on API Gateway
aws apigateway create-authorizer \
--rest-api-id YOUR_API_ID \
--name AscendAuthorizer \
--type REQUEST \
--authorizer-uri "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/${AUTHORIZER_ARN}/invocations" \
--identity-source "method.request.header.X-Ascend-Agent-Id" \
--authorizer-result-ttl-in-seconds 60

CloudFormation Deployment

Full Template

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: ASCEND Lambda Authorizer for AI Agent Governance

Parameters:
AscendApiUrl:
Type: String
Description: ASCEND Platform API URL
Default: https://api.ascend.owkai.app

AscendApiKeySecret:
Type: String
Description: ARN of Secrets Manager secret containing ASCEND API key
NoEcho: true

Environment:
Type: String
Description: Deployment environment
Default: production
AllowedValues:
- production
- staging
- development

CacheTtlSeconds:
Type: Number
Description: Cache TTL for approved decisions (seconds)
Default: 60
MinValue: 0
MaxValue: 300

TimeoutSeconds:
Type: Number
Description: API timeout in seconds
Default: 4
MinValue: 1
MaxValue: 4

LogLevel:
Type: String
Description: Logging level
Default: INFO
AllowedValues:
- DEBUG
- INFO
- WARNING
- ERROR

Globals:
Function:
Timeout: 5
Runtime: python3.11
Architectures:
- arm64
Environment:
Variables:
ASCEND_API_URL: !Ref AscendApiUrl
ASCEND_API_KEY_SECRET_ARN: !Ref AscendApiKeySecret
ASCEND_ENVIRONMENT: !Ref Environment
ASCEND_CACHE_TTL: !Ref CacheTtlSeconds
ASCEND_TIMEOUT: !Ref TimeoutSeconds
LOG_LEVEL: !Ref LogLevel

Resources:
AscendAuthorizerFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub 'ascend-authorizer-${Environment}'
Description: ASCEND Platform Lambda Authorizer
CodeUri: src/
Handler: handler.lambda_handler
MemorySize: 256
ReservedConcurrentExecutions: 100
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Ref AscendApiKeySecret
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
- Effect: Allow
Action:
- cloudwatch:PutMetricData
Resource: '*'
Condition:
StringEquals:
cloudwatch:namespace: AscendAuthorizer

AuthorizerLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '/aws/lambda/ascend-authorizer-${Environment}'
RetentionInDays: 90

Outputs:
AuthorizerFunctionArn:
Description: Lambda Authorizer function ARN
Value: !GetAtt AscendAuthorizerFunction.Arn
Export:
Name: !Sub '${AWS::StackName}-AuthorizerArn'

AuthorizerInvokeUri:
Description: Invoke URI for API Gateway
Value: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AscendAuthorizerFunction.Arn}/invocations'

Deploy with CloudFormation

# Package (if using local code)
aws cloudformation package \
--template-file template.yaml \
--s3-bucket your-deployment-bucket \
--output-template-file packaged.yaml

# Deploy
aws cloudformation deploy \
--template-file packaged.yaml \
--stack-name ascend-authorizer-prod \
--parameter-overrides \
AscendApiKeySecret=arn:aws:secretsmanager:us-east-1:123456789012:secret:ascend/api-key-AbCdEf \
Environment=production \
--capabilities CAPABILITY_IAM

API Gateway Integration

REST API (V1)

Console

  1. Open API Gateway console
  2. Select your REST API
  3. Go to Authorizers > Create New Authorizer
  4. Configure:
    • Name: AscendAuthorizer
    • Type: Lambda
    • Lambda Function: ascend-authorizer-production
    • Lambda Invoke Role: Leave blank (auto-create)
    • Identity Source: method.request.header.X-Ascend-Agent-Id
    • Authorization Caching: Enabled, 60 seconds

CloudFormation

AscendApiAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: AscendAuthorizer
Type: REQUEST
RestApiId: !Ref MyRestApi
AuthorizerUri: !Sub
- 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerArn}/invocations'
- AuthorizerArn: !ImportValue ascend-authorizer-prod-AuthorizerArn
AuthorizerResultTtlInSeconds: 60
IdentitySource: method.request.header.X-Ascend-Agent-Id

# Apply to methods
MyMethod:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref MyRestApi
ResourceId: !Ref MyResource
HttpMethod: POST
AuthorizationType: CUSTOM
AuthorizerId: !Ref AscendApiAuthorizer

HTTP API (V2)

Console

  1. Open API Gateway console
  2. Select your HTTP API
  3. Go to Authorization
  4. Add authorizer:
    • Type: Lambda
    • Function: ascend-authorizer-production
    • Response mode: Simple
    • Identity sources: $request.header.X-Ascend-Agent-Id

CloudFormation

AscendHttpAuthorizer:
Type: AWS::ApiGatewayV2::Authorizer
Properties:
ApiId: !Ref MyHttpApi
AuthorizerType: REQUEST
AuthorizerUri: !Sub
- 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerArn}/invocations'
- AuthorizerArn: !ImportValue ascend-authorizer-prod-AuthorizerArn
IdentitySource:
- $request.header.X-Ascend-Agent-Id
Name: AscendAuthorizer
AuthorizerPayloadFormatVersion: '2.0'
EnableSimpleResponses: true

Lambda Permission

Grant API Gateway permission to invoke the authorizer:

AuthorizerInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref AscendAuthorizerFunction
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceArn: !Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${MyRestApi}/authorizers/*'

Production Deployment

High Availability

# Provisioned concurrency for consistent latency
AscendAuthorizerAlias:
Type: AWS::Lambda::Alias
Properties:
FunctionName: !Ref AscendAuthorizerFunction
FunctionVersion: !GetAtt AscendAuthorizerVersion.Version
Name: live
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 5

# Auto-scaling for provisioned concurrency
AutoScalingTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: 50
MinCapacity: 5
ResourceId: !Sub function:${AscendAuthorizerFunction}:live
ScalableDimension: lambda:function:ProvisionedConcurrency
ServiceNamespace: lambda

Multi-Region Deployment

For global applications, deploy in multiple regions:

# Deploy to us-east-1
sam deploy --region us-east-1 --stack-name ascend-authorizer-prod-use1

# Deploy to eu-west-1
sam deploy --region eu-west-1 --stack-name ascend-authorizer-prod-euw1

# Deploy to ap-southeast-1
sam deploy --region ap-southeast-1 --stack-name ascend-authorizer-prod-apse1

VPC Deployment

For private APIs:

AscendAuthorizerFunction:
Type: AWS::Serverless::Function
Properties:
# ... other properties
VpcConfig:
SecurityGroupIds:
- !Ref AuthorizerSecurityGroup
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2

AuthorizerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ASCEND Lambda Authorizer
VpcId: !Ref VpcId
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0

Monitoring

CloudWatch Dashboard

The deployment creates a dashboard. Access it:

DASHBOARD_URL=$(aws cloudformation describe-stacks \
--stack-name ascend-authorizer-prod \
--query 'Stacks[0].Outputs[?OutputKey==`DashboardUrl`].OutputValue' \
--output text)

echo "Dashboard: $DASHBOARD_URL"

Alarms

Set up alarms for critical metrics:

HighErrorRateAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: AscendAuthorizer-HighErrorRate
AlarmDescription: High error rate in ASCEND authorizer
MetricName: Errors
Namespace: AscendAuthorizer
Statistic: Sum
Period: 300
EvaluationPeriods: 2
Threshold: 10
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref OpsAlarmTopic

Testing

Test the Authorizer

# Get function name
FUNCTION_NAME=ascend-authorizer-production

# Test with sample event
aws lambda invoke \
--function-name $FUNCTION_NAME \
--payload file://test-event.json \
--cli-binary-format raw-in-base64-out \
response.json

cat response.json

Sample test event (test-event.json):

{
"type": "REQUEST",
"methodArn": "arn:aws:execute-api:us-east-1:123456789012:abc123/prod/POST/data",
"resource": "/data",
"path": "/data",
"httpMethod": "POST",
"headers": {
"X-Ascend-Agent-Id": "test-agent",
"X-Ascend-Environment": "production"
},
"requestContext": {
"resourcePath": "/data",
"httpMethod": "POST",
"stage": "prod"
}
}

Integration Test

# Test actual API endpoint
curl -v -X POST https://api.example.com/data \
-H "X-Ascend-Agent-Id: test-agent" \
-H "X-Ascend-Environment: production" \
-H "Content-Type: application/json" \
-d '{"test": true}'

Updating

Update Lambda Code

# Rebuild and deploy
sam build
sam deploy --no-confirm-changeset

Update Configuration

# Update parameters
aws cloudformation update-stack \
--stack-name ascend-authorizer-prod \
--use-previous-template \
--parameters \
ParameterKey=CacheTtlSeconds,ParameterValue=120 \
ParameterKey=LogLevel,ParameterValue=DEBUG

Cleanup

Remove the deployment:

# Delete CloudFormation stack
aws cloudformation delete-stack --stack-name ascend-authorizer-prod

# Wait for deletion
aws cloudformation wait stack-delete-complete --stack-name ascend-authorizer-prod

# Delete secrets (optional)
aws secretsmanager delete-secret --secret-id ascend/api-key --force-delete-without-recovery

Next Steps

Support