Skip to content

Security: aws-samples/sample-bedrock-agentcore-twilio-agent-connect-reference

Security

SECURITY.md

Security

Reporting a Vulnerability

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 Overview

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 ⚠️ Partial — configure Amazon Bedrock Guardrails for production
Credential exposure .env gitignored; no secrets in code or git history ⚠️ Partial — migrate to AWS Secrets Manager for production
DDoS / resource exhaustion Amazon CloudFront edge caching and DDoS protection; AWS WAF rate limiting (200 req/5min per IP) on CloudFront and ALB

Scan Results

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

Data Residency

AWS Managed Data

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

Twilio Managed Data

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)

Shared Responsibility Model

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

Security Controls Implemented

  • 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. See infra/platform/lib/ CDK stacks.
  • IAM conditions: aws:SecureTransport condition 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.ts and server-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 (.env is 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 in tac_server/main.py and agents/support_agent/main.py. Profile ID format validation (alphanumeric, max 100 characters) on dashboard endpoints in dashboard/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 in dashboard/templates.py.
  • Point-in-time recovery: Enabled on both Amazon DynamoDB tables for backup and recovery.
  • Webhook signature validation: Twilio RequestValidator validates X-Twilio-Signature HMAC on all inbound Twilio webhooks (/webhook, /twiml, /conversation-relay-callback). URL built from TWILIO_VOICE_PUBLIC_DOMAIN environment variable to avoid proxy header reconstruction issues behind CloudFront. Server exits on startup if TWILIO_AUTH_TOKEN or TWILIO_VOICE_PUBLIC_DOMAIN is not set. See tac_server/main.py.
  • Dashboard basic auth: HTTP Basic Authentication middleware on all /dashboard* endpoints (except /dashboard/health for ALB health checks). Password from DASHBOARD_PASSWORD environment variable, falls back to TWILIO_API_KEY. See dashboard/app.py.
  • AWS WAF rate limiting: Rate-based rules (200 requests per 5 minutes per IP) on both deployment flows. CloudFront stack: CLOUDFRONT scope WebACL attached via webAclId. Custom Domain stack: REGIONAL scope WebACL attached via CfnWebACLAssociation on ALB. See server-cloudfront-stack.ts and server-custom-domain-stack.ts.

Service Security Guidelines

Amazon ECR

  • Scan-on-push enabled for vulnerability detection (scanOnPush=true in Makefile)
  • Lifecycle policy retains latest 5 images (implemented in Makefile)
  • For production: use immutable image tags, implement container image signing with AWS Signer

AWS Certificate Manager (ACM)

  • 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

Amazon Route 53

  • 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

AWS IAM

  • Amazon ECS task roles follow least privilege with scoped resource ARNs (implemented in CDK stacks)
  • aws:SecureTransport condition enforces TLS on Amazon DynamoDB operations (implemented in data-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

Key Management Strategy

  • 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.

Access Logging

  • 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 in server-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, and Scan operations. This provides a complete audit trail of data access.

Data Classification

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.

IAM Policy Justifications

  • 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/UpdateItem permissions: Required for the change_seat agent 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 each agentcore 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.

Threat Model Details

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.

Network Architecture

  • 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.0 inside 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.

Security Implementations

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

Considerations for Production

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.

There aren't any published security advisories