Architecture Diagram
Core AWS Resources
Cognito User Pool
Purpose: User authentication and authorization- Authentication: Email-based login with AWS Cognito User Pool
- Password Policy:
- Minimum 12 characters
- Requires uppercase, lowercase, numbers, and symbols
- Temporary password valid for 7 days
- User Groups:
admingroup for platform administrators - Token Validity:
- Access token: 60 minutes
- ID token: 60 minutes
- Refresh token: 30 days (43,200 minutes)
- Auth Flows:
USER_PASSWORD_AUTH,ADMIN_USER_PASSWORD_AUTH,USER_SRP_AUTH,REFRESH_TOKEN_AUTH - Self-signup: Disabled (admin-only user creation)
UserPool, UserPoolClient, AdminGroup
RDS PostgreSQL 15
Purpose: Primary relational database for all application data- Instance Type:
db.t3.micro(2 vCPUs, 1 GiB RAM) - Storage: 20 GB General Purpose SSD (gp3)
- Engine: PostgreSQL 15
- Database Name:
alliance_risk - High Availability: Single-AZ (MVP configuration)
- Backup Retention: 7 days
- Encryption: Storage encrypted at rest
- Network: Private VPC, no public access
- Deletion Protection: Enabled (production)
- Deletion Policy: Snapshot (production)
alliance-risk/db-credentials
Schema Management: Prisma ORM with migrations in packages/api/prisma/migrations/
Stack Resource: Database, DbSecret, DbSecurityGroup, DbSubnetGroup
Lambda Functions
Both Lambda functions run on ARM64 architecture for cost optimization (20% cheaper than x86_64).API Lambda
Purpose: REST API server (NestJS)- Function Name:
alliance-risk-api - Runtime: Node.js 20.x (ARM64)
- Handler:
dist/src/lambda.handler - Memory: 1024 MB
- Timeout: 29 seconds (< API Gateway 30s limit)
- VPC: Attached to private subnets for RDS access
- Trigger: API Gateway HTTP API
- Environment Variables:
ENVIRONMENT— Deployment environment (dev/staging/production)COGNITO_USER_POOL_ID— Cognito User Pool IDCOGNITO_CLIENT_ID— Cognito App Client IDS3_BUCKET_NAME— File storage bucket nameAWS_ACCOUNT_ID— AWS Account IDWORKER_FUNCTION_NAME— Worker Lambda function nameCORS_ORIGIN— Allowed CORS originDATABASE_URL— PostgreSQL connection string (constructed from Secrets Manager)
ApiLambda, ApiLambdaRole
Worker Lambda
Purpose: Background job processor for long-running AI operations- Function Name:
alliance-risk-worker - Runtime: Node.js 20.x (ARM64)
- Handler:
dist/src/worker.handler - Memory: 1024 MB
- Timeout: 900 seconds (15 minutes)
- VPC: Attached to private subnets for RDS access
- Invocation: Asynchronous (fire-and-forget from API Lambda)
- Environment Variables:
ENVIRONMENT— Deployment environmentAWS_ACCOUNT_ID— AWS Account IDS3_BUCKET_NAME— File storage bucket nameDATABASE_URL— PostgreSQL connection string
WorkerLambda, WorkerLambdaRole
Special Action: run-sql — Executes raw SQL on RDS for database migrations (RDS is in private VPC, unreachable from local machines)
S3 Buckets
File Storage Bucket
Purpose: Business plan document uploads (PDF/DOCX)- Bucket Name:
alliance-risk-files-{AWS::AccountId} - Public Access: Blocked (all)
- Encryption: S3-managed (AES256)
- Versioning: Disabled
- Deletion Policy: Retain (production)
- CORS: Enabled for presigned upload URLs
- Allowed origins:
* - Allowed methods: GET, PUT
- Exposed headers: ETag
- Allowed origins:
FileBucket
Web Hosting Bucket
Purpose: Next.js static site hosting- Bucket Name:
alliance-risk-web-{AWS::AccountId} - Public Access: Blocked (CloudFront OAI used)
- Encryption: S3-managed (AES256)
- Versioning: Disabled
- Deletion Policy: Delete (auto-cleanup on stack deletion)
WebBucket, WebBucketPolicy
CloudFront Distribution
Purpose: Global CDN for static web application- Origin: S3 Web Bucket via Origin Access Identity (OAI)
- Protocol: HTTPS only (redirect HTTP → HTTPS)
- Price Class: 100 (North America + Europe)
- HTTP Version: HTTP/2
- Default Root Object:
index.html - Error Responses: 403/404 → 200 with
/index.html(SPA routing) - Cache Policy: CachingOptimized (
658327ea-f89d-4fab-a63d-7e88639e58f6) - Compression: Gzip enabled
.html files for Next.js static export:
/login→/login.html/dashboard/→/dashboard.html- Blocks direct browser navigation to
.txtfiles (RSC payloads)
WebDistribution, WebOAI, UrlRewriteFunction
API Gateway HTTP API
Purpose: HTTP API endpoint for REST API- Name:
alliance-risk-api - Protocol: HTTP (not REST — simpler, cheaper)
- Integration: Lambda Proxy (payload format 2.0)
- CORS:
- Allowed origins:
* - Allowed methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
- Allowed headers:
* - Max age: 86400 seconds (24 hours)
- Allowed origins:
- Authorization: None (handled by NestJS JWT guards)
- Default Route: All requests route to API Lambda
HttpApi, HttpApiIntegration, HttpApiDefaultRoute, HttpApiStage
IAM Roles and Policies
API Lambda Role
Permissions:- CloudWatch Logs: Basic Lambda execution (log creation)
- VPC Access: ENI creation for VPC attachment
- Cognito: All admin user/group operations
- Bedrock: Model invocation and knowledge base retrieval
anthropic.claude-3-5-sonnet-*anthropic.claude-3-haiku-*
- Textract: Document analysis
- S3: GetObject, PutObject, DeleteObject on FileBucket
- Lambda: InvokeFunction on Worker Lambda
ApiLambdaRole
Worker Lambda Role
Permissions (identical to API Lambda except no Worker invocation):- CloudWatch Logs: Basic Lambda execution
- VPC Access: ENI creation for VPC attachment
- Cognito: All admin user/group operations
- Bedrock: Model invocation and knowledge base retrieval
- Textract: Document analysis
- S3: GetObject, PutObject, DeleteObject on FileBucket
WorkerLambdaRole
VPC Networking
The RDS database resides in a private VPC with no public internet access. Both Lambda functions are deployed inside the same VPC to communicate with the database.VPC Configuration
- VPC: Default VPC (specified via
VpcIdparameter) - Subnets: Public subnets (specified via
SubnetIdsparameter) - Security Groups:
LambdaSecurityGroup— Allows all outbound trafficDbSecurityGroup— Allows inbound PostgreSQL (5432) from LambdaSecurityGroup onlyVpcEndpointSecurityGroup— Allows HTTPS (443) from LambdaSecurityGroup
VPC Endpoints
Lambdas in a VPC cannot reach public AWS services (Cognito, Bedrock, S3) without VPC Endpoints or a NAT Gateway. The stack provisions the following VPC endpoints:| Service | Type | Purpose |
|---|---|---|
| Cognito IDP | Interface | Token verification, user management |
| Lambda | Interface | Worker Lambda invocation from API Lambda |
| Textract | Interface | Document parsing |
| S3 | Gateway | File storage access (cheaper than interface endpoint) |
EndpointSubnetIds parameter must specify subnets in supported AZs (e.g., us-east-1a/b/c for Cognito).
Missing Endpoint: Bedrock does not have a VPC endpoint yet. The current implementation uses a NAT Gateway (not in this template) or direct internet access. This will be addressed in a future update.
Security Group Rules
Stack Outputs
The CloudFormation stack exports these outputs for deployment scripts:| Output Key | Description | Used By |
|---|---|---|
ApiUrl | API Gateway endpoint URL | Web build (NEXT_PUBLIC_API_URL) |
CloudFrontUrl | CloudFront distribution URL | Web deployment verification |
CloudFrontDistributionId | CloudFront distribution ID | Web deployment (cache invalidation) |
CognitoUserPoolId | Cognito User Pool ID | Web build (NEXT_PUBLIC_COGNITO_USER_POOL_ID) |
CognitoClientId | Cognito App Client ID | Web build (NEXT_PUBLIC_COGNITO_CLIENT_ID) |
FileBucketName | S3 file storage bucket name | API deployment |
WebBucketName | S3 web hosting bucket name | Web deployment |
DatabaseEndpoint | RDS endpoint address | Database migrations |
DeployBucketName | S3 deployment bucket name | API deployment |
WorkerLambdaName | Worker Lambda function name | API deployment |
Infrastructure Deployment
See Deploying the API and Deploying the Web App for application deployment. For infrastructure deployment:infra/CLAUDE.md for CDK vs CloudFormation deployment options.
Cost Optimization
- ARM64 Architecture: 20% cost reduction on Lambda
- HTTP API: Cheaper than REST API Gateway (~70% savings)
- Gateway VPC Endpoint for S3: No data transfer charges (vs interface endpoint)
- CloudFront Price Class 100: Cheaper edge locations (North America + Europe)
- Single-AZ RDS: No multi-AZ replication charges (acceptable for MVP)
- gp3 Storage: Better price/performance than gp2
Security Best Practices
- Secrets Manager: Database credentials never hardcoded
- VPC Isolation: RDS has no public internet access
- S3 Block Public Access: All buckets private by default
- Encryption at Rest: RDS and S3 encrypted
- Encryption in Transit: HTTPS only for all services
- Least Privilege IAM: Lambda roles grant only required permissions
- CloudFront OAI: S3 bucket accessible only via CloudFront
- Security Groups: Database accessible only from Lambda functions
Disaster Recovery
- RDS Automated Backups: 7-day retention
- RDS Deletion Policy: Snapshot on stack deletion (production)
- S3 Versioning: Disabled (not required for MVP)
- CloudFormation Drift Detection: Run
aws cloudformation detect-stack-driftperiodically
Monitoring and Logging
- CloudWatch Logs:
/aws/lambda/alliance-risk-api— API Lambda logs/aws/lambda/alliance-risk-worker— Worker Lambda logs
- CloudWatch Metrics:
- Lambda invocations, errors, duration, throttles
- API Gateway 4xx/5xx errors, latency
- RDS CPU, storage, connections
- X-Ray Tracing: Not enabled (optional enhancement)