If you discover a security vulnerability in this project, please report it responsibly. Do not open a public issue. Instead, contact the maintainers directly via email or your organization's security reporting channel.
- All API endpoints (except CORS preflight) require a valid Amazon Cognito ID token in the Authorization header.
- API Gateway uses a Cognito User Pool authorizer to validate tokens before any Lambda is invoked.
- Self-signup is enabled with email verification. Passwords require minimum 8 characters, uppercase, lowercase, and numbers.
- The frontend stores no credentials — Amplify manages token refresh and storage via secure browser mechanisms.
- No public endpoints expose the Lambda MicroVM directly. Access requires a short-lived
X-aws-proxy-authJWE token generated by the Worker Lambda. - The AgentCore Gateway uses AWS IAM (SigV4) authentication. Only the MicroVM's execution role can invoke it.
- CORS origin is explicitly configured at deploy time (no wildcard default). The
AllowedOriginparameter is required. - API Gateway has a Usage Plan with rate limiting (20 req/s sustained, 50 burst) to prevent abuse.
| Resource | Encryption | Key Type |
|---|---|---|
| DynamoDB Tasks Table | At rest (SSE) | Customer-managed KMS CMK |
| S3 Results Bucket | At rest (SSE) | AES256/KMS |
| S3 Logging Bucket | At rest (SSE) | AES256 |
| S3 Artifacts Bucket | At rest (SSE) | AES256 |
| CloudWatch Logs (API GW) | At rest | Customer-managed KMS CMK |
| Lambda environment variables | At rest | Customer-managed KMS CMK |
| SQS Dead Letter Queue | At rest | Customer-managed KMS CMK |
| All data in transit | HTTPS/TLS | AWS-managed certificates |
- Each Lambda function has its own dedicated IAM role with only the permissions it needs:
- Submit Lambda:
dynamodb:PutItem,lambda:InvokeFunction(worker only),sqs:SendMessage(DLQ) - Poll Lambda:
dynamodb:GetItem,sqs:SendMessage(DLQ) - Worker Lambda:
dynamodb:UpdateItem,lambda:*Microvm*,iam:PassRole(execution role only),sqs:SendMessage(DLQ)
- Submit Lambda:
- The MicroVM execution role is scoped to specific Bedrock model ARNs, a single S3 bucket, and one AgentCore Gateway.
iam:PassRoleis restricted to only the MicroVM execution role ARN — not wildcard.
- The research agent's URL browsing tool validates DNS resolution against private IP ranges (RFC 1918, link-local, loopback) before fetching any URL.
- This prevents the agent from being tricked into accessing internal AWS metadata endpoints or VPC-internal services.
- Each Lambda MicroVM runs in its own Firecracker microVM with hardware-level isolation (separate kernel, memory, and network namespace).
- The agent process runs as a non-root user inside the container.
- MicroVMs auto-terminate after 8 hours maximum lifetime (
maximumDurationInSeconds: 28800). - MicroVMs auto-suspend after 5 minutes idle and auto-terminate after 60 seconds in suspended state.
- DynamoDB task records have a TTL of 1 hour — they are automatically deleted after expiry.
- S3 research reports expire after 90 days (lifecycle policy on the Results Bucket).
- S3 access logs expire after 30 days.
- In-memory sessions on the MicroVM are lost when the VM terminates (no persistent session store).
- No API keys, passwords, or secrets are stored in code or configuration files.
- All authentication is IAM/SigV4-based (backend) or Cognito token-based (frontend).
- Frontend configuration (Cognito pool IDs, API endpoint) is loaded from environment variables (
.envfile, gitignored). - Cognito User Pool Client IDs are not secrets — they are public identifiers safe for client-side use.
- API Gateway access logs are written to CloudWatch Logs (KMS-encrypted).
- X-Ray tracing is enabled on the API Gateway stage for request tracing.
- Lambda MicroVM runtime logs stream to CloudWatch at
/aws/lambda-microvms/research-agent. - The Worker Lambda's Dead Letter Queue captures failed async invocations for investigation.
- The
boto3-latestLambda layer is built from pinned versions at deploy time usingbuild-layer.sh. - Frontend dependencies are locked via
package-lock.json. - No third-party runtime dependencies beyond AWS SDK (boto3) and standard library in Lambda functions.
- CloudFormation templates are scanned with
cfn_nagfor security best practices. - The repository is scanned with ASH (Automated Security Helper) for secrets, misconfigurations, and vulnerabilities.
- Known cfn_nag suppressions are documented with
reasonin template metadata.
| Finding | Severity | File | Status |
|---|---|---|---|
| SECRET-SECRET-KEYWORD: 'Secret Keyword' detected at line 62 | HIGH | research-agent-ui/infrastructure/template.yaml | False positive. GenerateSecret: false is a standard CFN property name, not a secret value. |
| KMS Key With Vulnerable Policy | CRITICAL | research-agent-ui/infrastructure/template.yaml:73 | Fixed. Replaced kms:* wildcard with explicit key administration and usage actions. |
| CFN_NAG_W89 / CKV_AWS_117: Lambda not in VPC | MEDIUM/HIGH | research-agent-ui/infrastructure/template.yaml | Accepted risk. Lambdas only access AWS managed services via IAM-authenticated HTTPS. No private resources. VPC would add latency + NAT Gateway cost with no security benefit. |
| CKV_AWS_18: S3 LoggingBucket logging disabled | HIGH | research-agent/infrastructure/template.yaml:27 | Not applicable. This IS the logging destination bucket. Logging to itself would create infinite recursion. Standard AWS pattern. |
| API Gateway Deployment Without Access Log Setting | MEDIUM | research-agent-ui/infrastructure/template.yaml:249 | Not applicable. Access logging is configured on the Stage resource (not Deployment). Logs flow to CloudWatch with KMS encryption. |
| API Gateway Method Does Not Contain An API Key | MEDIUM | research-agent-ui/infrastructure/template.yaml | Accepted risk. Authentication uses Cognito JWT authorizer, which is stronger than API keys. API keys are for rate limiting, handled by Usage Plan instead. |
| API Gateway Without SSL Certificate | MEDIUM | research-agent-ui/infrastructure/template.yaml:261 | Accepted risk. Mutual TLS (client certificates) is for backend-to-backend auth. Frontend browsers cannot present client certs. TLS is enforced by default on all API Gateway endpoints. |
| API Gateway V2 Stage Access Logging Not Defined | MEDIUM | research-agent-ui/infrastructure/template.yaml:261 | Not applicable. This is a REST API (V1), not HTTP API (V2). Access logging is configured on the V1 Stage resource. |
| IAM policy allows for data exfiltration | MEDIUM | research-agent/infrastructure/template.yaml:185 | Accepted risk. The bedrock:InvokeModel permission is required for the agent to call Claude. The policy is scoped to specific model ARNs only, not wildcard. |
| API Gateway without WAF | MEDIUM | research-agent-ui/infrastructure/template.yaml:264 | Accepted risk for development. WAF adds ~$5/mo + per-request costs. Cognito auth + Usage Plan rate limiting provide adequate protection. WAF recommended for production deployment. |
| CloudWatch Metrics Disabled | MEDIUM | research-agent-ui/infrastructure/template.yaml:261 | Fixed. Added MethodSettings with MetricsEnabled: true on the API stage. |
| API Gateway Endpoint Config is Not Private | MEDIUM | research-agent-ui/infrastructure/template.yaml:139 | By design. The API must be publicly accessible for browser-based frontend clients. Authentication is enforced via Cognito authorizer on all protected endpoints. |
| CVE-2024-47081: Requests .netrc credential leak | MEDIUM | research-agent/requirements.txt | Fixed. Upgraded requests>=2.32.3 which patches all known CVEs. |
| CVE-2024-35195: Requests Session verify=False | MEDIUM | research-agent/requirements.txt | Fixed. Upgraded requests>=2.32.3. |
| Requests insecure temp file reuse | MEDIUM | research-agent/requirements.txt | Fixed. Upgraded requests>=2.32.3. |
Full justifications with detailed rationale are in .ash/ash_output/reports/ash_justifications.csv.
- All data encrypted at rest with KMS CMKs
- All data encrypted in transit (HTTPS/TLS)
- Cognito authentication on all API endpoints
- No wildcard IAM permissions (except MicroVM actions which don't support resource-level)
- No hardcoded secrets in source code
- CORS restricted to explicit origin
- API rate limiting via Usage Plan
- Dead Letter Queue for failed invocations
- SSRF protection on URL browsing
- Auto-expiring data (DynamoDB TTL, S3 lifecycle)
- Compute isolation via Firecracker MicroVMs
- Non-root container execution
- Access logging with KMS encryption
- X-Ray tracing enabled