If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our vulnerability reporting page. Please do not create a public GitHub issue.
| Threat | Mitigation | Status |
|---|---|---|
| Unauthorized agent invocation | IAM: 5 specific invoke actions scoped to project runtime ARN pattern | ✅ |
| Forged webhook requests | Twilio RequestValidator validates X-Twilio-Signature on /webhook, /twiml, /conversation-relay-callback; URL built from TWILIO_VOICE_PUBLIC_DOMAIN (avoids proxy header issues behind CloudFront); SigV4 presigned URLs for Bedrock AgentCore connections |
✅ |
| Direct ALB access bypassing CloudFront | Security groups restrict ingress to ALB SG only; CloudFront enforces HTTPS | ✅ |
| Container escape | Non-root user (appuser); AWS Fargate managed host; ECR scan-on-push |
✅ |
| Cross-site scripting (dashboard) | escapeHtml() on all dynamic content from database and API responses |
✅ |
| Data exfiltration | No real PII in AWS; all customer data managed by Twilio; synthetic demo data only | ✅ |
| Session hijacking | Twilio-generated unique profile IDs; Bedrock AgentCore microVM per conversation; SigV4-signed WebSocket headers (time-bound); 15-minute idle timeout | ✅ |
| PII exposure in logs | User inputs, agent responses, and credentials excluded from logging; 1-week retention auto-expire | ✅ |
| Prompt injection via voice input | _sanitize_prompt() on all inputs; STT handled by Twilio; system prompt constraints |
|
| Credential exposure | .env gitignored; no secrets in code or git history |
|
| DDoS / resource exhaustion | Amazon CloudFront edge caching and DDoS protection; AWS WAF rate limiting (200 req/5min per IP) on CloudFront and ALB | ✅ |
| Tool | Scope | Findings |
|---|---|---|
| Semgrep OSS | 464 rules, 47 files (Python, TypeScript, shell, Dockerfiles) | ✅ 0 vulnerabilities |
| npm audit | CDK infrastructure dependencies (Node.js) | ✅ 0 vulnerabilities |
| pip-audit | Python dependencies — root project (93 packages) | ✅ 0 vulnerabilities |
| pip-audit | Python dependencies — agent (98 packages) | ✅ 0 vulnerabilities |
| Checkov (IaC) | CDK stacks (via Holmes CSR) | ✅ 0 vulnerabilities |
| cfn-guard | CloudFormation templates (via Holmes CSR) | ✅ 0 vulnerabilities |
| Amazon GuardDuty (malware) | All files (via Holmes CSR) | ✅ 0 vulnerabilities |
| Bandit (Python SAST) | All .py files (via Holmes CSR) |
✅ 0 vulnerabilities 2 false positive findings: B104 ( host="0.0.0.0" — required for ECS Fargate, # nosec B104) and B608 (HTML f-string — not SQL, # nosec B608) |
| ACAT | All files (via Holmes CSR) | ✅ 0 vulnerabilities 1 informational finding: external uv package manager install — standard for reference architectures |
This reference architecture stores only synthetic demo data and ephemeral runtime state in AWS. No real customer PII is stored in AWS.
| Data | Location | Content | Retention |
|---|---|---|---|
| Amazon DynamoDB tables | {PROJECT}Reservations, {PROJECT}Flights |
100% synthetic demo data generated by seed_data.py (fictional names, @example.com emails, 555 phone numbers) |
Until stack deletion |
| Amazon CloudWatch Logs | /ecs/{PROJECT}-tac-server, /aws/bedrock-agentcore/runtimes/* |
Application logs with session metadata and timing. User inputs excluded from logs. | 1 week (auto-expire) |
| Amazon Bedrock AgentCore Runtime | Stateless microVMs | No persistent storage. Session data is ephemeral with a 15-minute idle timeout. | None |
| Amazon S3 (access logs) | {project}-access-logs-{account}-{suffix} |
ALB and CloudFront access logs | Until stack deletion |
All customer personally identifiable information (PII) — phone numbers, customer profiles, conversation transcripts, sentiment analysis, memory observations, and summaries — is stored and managed by Twilio under their platform and data policies. Users of this reference architecture require a Twilio account, and Twilio's data agreements govern all PII handling.
- Customer profiles and traits (Conversation Memory)
- Full conversation transcripts and message history (Conversation Orchestrator)
- Sentiment analysis and post-call summaries (Conversation Intelligence)
- Voice recordings (if enabled via Conversation Relay)
| AWS Service | AWS Responsibility | Customer Responsibility |
|---|---|---|
| Amazon Bedrock AgentCore | Runtime infrastructure, microVM isolation, presigned URL generation and validation | IAM policy scoping to specific runtime ARN patterns, application code security, input validation and sanitization, prompt injection prevention, session ID management, data handling and classification |
| Amazon ECS on AWS Fargate | Container orchestration, host patching, network isolation, kernel security | Container image security (non-root user, vulnerability scanning via ECR), application code, base image updates |
| Amazon DynamoDB | Infrastructure encryption, availability, durability, replication | Table encryption configuration (AWS_MANAGED or customer-managed KMS), IAM access policies, data classification, backup strategy |
| Amazon CloudFront | Edge infrastructure, TLS termination, DDoS protection | Origin access configuration, cache policies, access logging configuration |
| Elastic Load Balancing | Load balancer infrastructure, health checks, TLS offloading | Security group rules, listener configuration, access logging |
| Amazon CloudWatch | Log infrastructure, storage encryption, log delivery | Log group encryption keys, retention policies, access controls, sensitive data redaction in application logs |
| Amazon S3 | Storage infrastructure, durability, availability | Bucket policies, versioning, encryption configuration, lifecycle rules |
| Amazon ECR | Container registry infrastructure, image storage | Image scanning (scan-on-push), lifecycle policies, access controls |
| AWS Certificate Manager | Certificate provisioning, automatic renewal | Certificate request validation, domain ownership verification |
| Amazon Route 53 | DNS infrastructure, availability | Hosted zone configuration, domain ownership, DNSSEC (recommended for production) |
| AWS IAM | Identity infrastructure, policy evaluation engine | Least privilege policies, regular access reviews, condition statements |
- IAM least privilege: Task roles scoped to specific Amazon DynamoDB table ARNs, Amazon Bedrock AgentCore runtime ARN patterns (5 specific invoke actions:
InvokeAgentRuntime,InvokeAgentRuntimeCommand,InvokeAgentRuntimeForUser,InvokeAgentRuntimeWithWebSocketStream,InvokeAgentRuntimeWithWebSocketStreamForUser), and Amazon CloudWatch log group patterns. Seeinfra/platform/lib/CDK stacks. - IAM conditions:
aws:SecureTransportcondition enforces TLS on all Amazon DynamoDB operations. - Security groups: Dashboard Amazon ECS service accepts traffic only from the Application Load Balancer security group on port 8899. See
server-cloudfront-stack.tsandserver-custom-domain-stack.ts. - Encryption in transit: HTTPS/TLS via Amazon CloudFront (viewer policy) and AWS Certificate Manager. WebSocket connections to Amazon Bedrock AgentCore use presigned URLs over WSS.
- Encryption at rest: Amazon DynamoDB tables use AWS managed encryption (SSE). Amazon S3 access log buckets use S3-managed encryption (SSE-S3).
- Access logging: Application Load Balancer access logs stored in Amazon S3 with versioning. Amazon CloudFront access logs stored in Amazon S3 with versioning (CloudFront stack). Amazon CloudWatch Logs for Amazon ECS containers with 1-week retention.
- Container hardening: Non-root user (
appuser) in both Dockerfiles. Minimal base images (python:3.13-slim). Amazon ECR image scanning enabled on push (scanOnPush=true). - No hardcoded credentials: All secrets loaded from environment variables (
.envis gitignored). For production, migrate to AWS Secrets Manager with automatic rotation. - Input validation and prompt sanitization:
_sanitize_prompt()validates message length (10,000 characters), type, and whitespace on all WebSocket and HTTP payloads intac_server/main.pyandagents/support_agent/main.py. Profile ID format validation (alphanumeric, max 100 characters) on dashboard endpoints indashboard/app.py. For production, configure Amazon Bedrock Guardrails for content filtering and prompt attack prevention. - XSS protection:
escapeHtml()applied to all database and API values rendered in the dashboard HTML templates indashboard/templates.py. - Point-in-time recovery: Enabled on both Amazon DynamoDB tables for backup and recovery.
- Webhook signature validation: Twilio
RequestValidatorvalidatesX-Twilio-SignatureHMAC on all inbound Twilio webhooks (/webhook,/twiml,/conversation-relay-callback). URL built fromTWILIO_VOICE_PUBLIC_DOMAINenvironment variable to avoid proxy header reconstruction issues behind CloudFront. Server exits on startup ifTWILIO_AUTH_TOKENorTWILIO_VOICE_PUBLIC_DOMAINis not set. Seetac_server/main.py. - Dashboard basic auth: HTTP Basic Authentication middleware on all
/dashboard*endpoints (except/dashboard/healthfor ALB health checks). Password fromDASHBOARD_PASSWORDenvironment variable, falls back toTWILIO_API_KEY. Seedashboard/app.py. - AWS WAF rate limiting: Rate-based rules (200 requests per 5 minutes per IP) on both deployment flows. CloudFront stack:
CLOUDFRONTscope WebACL attached viawebAclId. Custom Domain stack:REGIONALscope WebACL attached viaCfnWebACLAssociationon ALB. Seeserver-cloudfront-stack.tsandserver-custom-domain-stack.ts.
- Scan-on-push enabled for vulnerability detection (
scanOnPush=truein Makefile) - Lifecycle policy retains latest 5 images (implemented in Makefile)
- For production: use immutable image tags, implement container image signing with AWS Signer
- DNS-validated certificates for custom domain deployment (implemented in
server-custom-domain-stack.ts) - Automatic certificate renewal managed by AWS
- For production: enable Certificate Transparency logging, monitor certificate expiration with Amazon CloudWatch alarms
- DNS-validated ACM certificates ensure domain ownership (implemented in
server-custom-domain-stack.ts) - A-record alias to Application Load Balancer for custom domain routing
- For production: enable DNSSEC for hosted zones to prevent DNS spoofing
- Amazon ECS task roles follow least privilege with scoped resource ARNs (implemented in CDK stacks)
aws:SecureTransportcondition enforces TLS on Amazon DynamoDB operations (implemented indata-stack.ts)- 5 specific Amazon Bedrock AgentCore invoke actions instead of wildcard (implemented in server stacks)
- For production: quarterly review using AWS IAM Access Analyzer, enable AWS CloudTrail for all IAM API auditing
- Amazon DynamoDB: AWS managed encryption keys (SSE with automatic rotation by AWS). For production workloads with sensitive data, consider customer-managed AWS KMS keys with automatic annual rotation.
- Amazon S3 (access logs): S3-managed encryption (SSE-S3). Appropriate for access log data.
- No BYOK: This reference architecture does not use Bring Your Own Key. All encryption uses AWS-managed or S3-managed keys.
- Key access: Encryption keys are managed entirely by AWS. No customer key policies to configure.
- For production: Create customer-managed AWS KMS keys for Amazon DynamoDB tables containing real customer data. Enable automatic annual rotation. Restrict key policies to specific Amazon ECS task roles.
- Application Load Balancer: Access logs stored in Amazon S3 bucket with versioning, encryption (SSE-S3), and
enforceSSL. Implemented in both server CDK stacks. - Amazon CloudFront: Access logs stored in the same Amazon S3 bucket under
cloudfront/prefix with versioning. Implemented inserver-cloudfront-stack.ts. - Amazon CloudWatch Logs: Amazon ECS container logs for TAC server and dashboard with 1-week retention and automatic expiration. Implemented in both server CDK stacks.
- For production: Enable AWS CloudTrail data events for Amazon DynamoDB tables to log all
GetItem,PutItem,UpdateItem, andScanoperations. This provides a complete audit trail of data access.
| Level | Data | Location | Handling |
|---|---|---|---|
| Public | Demo seed data (fictional names, @example.com, 555 phones) |
Amazon DynamoDB | No restrictions. Generated by scripts/seed_data.py. |
| Internal | Application logs (session metadata, timing, message lengths). User inputs excluded. | Amazon CloudWatch Logs | 1-week auto-expire. No PII in logs. Scoped IAM access. |
| Internal | ALB and CloudFront access logs (request metadata) | Amazon S3 | Versioned, encrypted, enforce-SSL. No PII in access logs. |
| Confidential | Customer PII (real phone numbers, profiles, transcripts) | Twilio platform (NOT in AWS) | Governed by Twilio data policies. Requires Twilio account. Not stored or processed by AWS infrastructure in this architecture. |
| N/A | Voice recordings | Twilio platform (if enabled) | Not stored or processed by this application. |
- Amazon CloudWatch Logs wildcard pattern (
/ecs/${projectName}*,/aws/bedrock-agentcore/*): Required because Amazon Bedrock AgentCore Runtime creates log groups dynamically with deployment-specific suffixes. Exact log group names are not known at CDK synthesis time. The pattern is scoped to the project name prefix. - Amazon DynamoDB
PutItem/UpdateItempermissions: Required for thechange_seatagent tool which updates reservation records in the Reservations table. The agent modifies seat assignments as part of the customer service workflow. - Amazon Bedrock AgentCore
runtime/${projectName}*resource pattern: Required because the runtime ARN includes a deployment-specific suffix that changes on eachagentcore deploy. The wildcard covers both the runtime and its sub-resources (endpoints). Scoped to the project name prefix. - For production: Enable AWS IAM Access Analyzer to identify unused permissions. Review Amazon ECS task role policies quarterly against actual AWS CloudTrail API usage. Remove any permissions not exercised in the prior 90 days.
Trust boundaries:
Caller (PSTN) <-> Twilio Conversation Relay <-> TAC Server (ECS) <-> Bedrock AgentCore Runtime (microVM)
|
DynamoDB (synthetic data only)
See Threat Overview above for the complete threat/mitigation/status table.
- CloudFront flow: Twilio → Amazon CloudFront (HTTPS/WSS) → Application Load Balancer (HTTP:80) → Amazon ECS on Fargate
- Custom domain flow: Twilio → Application Load Balancer (HTTPS:443 via ACM) → Amazon ECS on Fargate
- Container binding: Servers bind to
0.0.0.0inside Amazon ECS Fargate containers. This is required for Application Load Balancer health checks and traffic forwarding. Containers are not directly exposed to the internet — all inbound traffic routes through the Application Load Balancer with security group restrictions.
| Priority | Control | Status | Verification |
|---|---|---|---|
| 1 | IAM least privilege | ✅ Implemented | aws iam get-role-policy on Amazon ECS task roles |
| 2 | Encryption at rest | ✅ Implemented | aws dynamodb describe-table --query 'Table.SSEDescription' |
| 3 | Encryption in transit | ✅ Implemented | Amazon CloudFront viewer policy + aws:SecureTransport IAM conditions |
| 4 | Container hardening | ✅ Implemented | docker exec <container> whoami returns appuser |
| 5 | Access logging | ✅ Implemented | Amazon S3 buckets with versioning for ALB/CloudFront logs |
| 6 | Input validation | ✅ Implemented | _sanitize_prompt() in tac_server/main.py and agents/support_agent/main.py |
| 7 | XSS protection | ✅ Implemented | escapeHtml() on all dynamic content in dashboard/templates.py |
| 8 | Point-in-time recovery | ✅ Implemented | aws dynamodb describe-continuous-backups |
This is a reference architecture for developer education and demonstration. For production deployments, implement the following additional controls:
| Priority | Control | Demo Status | Production Recommendation |
|---|---|---|---|
| 1 | Amazon Bedrock Guardrails | Not configured | Must be configured before production deployment. Configure content filters for harmful content, PII detection to prevent data leakage, and prompt attack filters to mitigate injection attempts. |
| 2 | Authentication | Basic auth on dashboard (DASHBOARD_PASSWORD) |
For production, implement Amazon Cognito or Application Load Balancer OIDC authentication for stronger identity verification and session management. |
| 3 | Secrets management | .env files |
Migrate all credentials to AWS Secrets Manager with automatic rotation: aws secretsmanager create-secret --name ${PROJECT}/twilio-credentials --secret-string '{"sid":"...","token":"..."}' |
| 4 | AWS CloudTrail data events | Not enabled | Enable for Amazon DynamoDB and Amazon S3 to log all data operations for audit compliance. |
| 5 | AWS WAF | ✅ Rate limiting (200 req/5min per IP) | Add managed rule groups (e.g., AWSManagedRulesCommonRuleSet) for SQL injection, XSS, and bot protection. Restrict webhook endpoint source IPs to Twilio's published IP ranges. |
| 6 | Amazon CloudWatch Logs encryption | Default encryption | Configure customer-managed AWS KMS keys for log groups containing sensitive data. |
| 7 | VPC endpoints | Not configured | AWS PrivateLink endpoints for Amazon DynamoDB, Amazon Bedrock, and Amazon CloudWatch to keep traffic within VPC. |
| 8 | Rate limiting | ✅ AWS WAF rate-based rules (200 req/5min per IP) | Tune rate limits per endpoint. Add Amazon API Gateway throttling for finer-grained control. |
| 9 | DNSSEC | Not enabled | Enable on Amazon Route 53 hosted zone for DNS integrity verification. |
| 10 | Container image signing | Not configured | AWS Signer for image provenance verification before deployment. |
| 11 | Amazon CloudWatch alarms | Not configured | Alarms for error rates, latency spikes, throttling, and unusual invocation patterns. |
| 12 | Amazon DynamoDB KMS keys | AWS managed | Customer-managed AWS KMS keys with automatic annual rotation for tables with real customer data. |