APEX is a multi-tenant AI platform built on AWS that provides solutions architecture guidance, opportunity management, and co-sell tooling for AWS partners. This document describes the technical controls that protect customer data at every layer of the platform.
Everything described here is implemented in production infrastructure defined as CloudFormation templates and application code — not aspirational policy. Where a control is designed but not yet deployed, it is explicitly noted.
When a user interacts with APEX, data moves through the following path:
Key properties of this flow:
APEX uses full resource isolation — not row-level filtering, not shared tables with tenant ID columns. Each tenant gets their own dedicated AWS resources.
| Resource Type | Count | Isolation Method |
|---|---|---|
| DynamoDB Tables | 11 | Separate tables per tenant (apex-{tenant}-*) |
| S3 Buckets | 4 | Separate buckets per tenant (chat-docs, tenant-config, alb-logs, s3-logging) |
| KMS Keys | 1 | Customer Managed Key with per-tenant alias, annual auto-rotation |
| Cognito User Pool | 1 | Separate identity provider per tenant |
| IAM Roles | 1 | EC2 instance profile scoped to tenant-specific resource ARNs only |
| CloudWatch Log Groups | 2+ | Separate log groups per tenant, encrypted with tenant KMS key |
| Bedrock Knowledge Bases | 1+ | Isolated per tenant with separate S3 data sources and KMS keys |
Resource isolation is reinforced at the application level:
owner_user_id before returning data| Resource | Encryption Method | Key Management |
|---|---|---|
| DynamoDB (11 tables) | SSE-KMS | Per-tenant Customer Managed Key, annual auto-rotation |
| S3 tenant-config bucket | SSE-KMS | Per-tenant Customer Managed Key |
| S3 chat-docs bucket | AES256 (S3-managed) | Required for CloudFront OAC presigned URL compatibility |
| S3 ALB logs bucket | AES256 (S3-managed) | ALB does not support KMS for access logs |
| CloudWatch Log Groups | SSE-KMS | Per-tenant Customer Managed Key |
| Bedrock Knowledge Bases | SSE-KMS | Per-tenant Customer Managed Key |
KMS key policy grants access only to the tenant's EC2 role and specific AWS service principals (S3, DynamoDB, Secrets Manager, Bedrock, CloudWatch Logs). Root account retains administrative access for key recovery.
| Endpoint | TLS Policy | Minimum Version |
|---|---|---|
| Application Load Balancer | ELBSecurityPolicy-TLS13-1-2-2021-06 | TLS 1.2 |
| CloudFront Distribution | TLSv1.2_2021 | TLS 1.2 |
| S3 Bucket Policies | DenyNonSSLRequests condition | TLS required |
| HTTP requests | 301 redirect to HTTPS | N/A |
All S3 buckets include bucket policies that deny any request made without SSL (aws:SecureTransport: false).
APEX does not log, store, or retain conversation content outside of the tenant's own DynamoDB tables. This is a deliberate architectural decision, not a default setting.
✦ What is logged (metadata only)
Token counts (input, output, cache read, cache write); session metadata (chat_id, user_id, model_id, timestamp); performance metrics (latency_ms, tool_calls count, turns count); HTTP metadata (method, path, status code, duration).
✦ What is never logged
User messages. Assistant responses. Tool inputs and tool results. Document content. Opportunity details, customer names, deal data.
Audit records are written to S3 partitioned by tenant, date, and session — containing only the metadata listed above.
Bedrock model invocation logging is disabled. No CloudWatch, S3, or any other destination receives conversation content from Bedrock API calls. This is enforced at the infrastructure level — there is no configuration to enable it.
Customers can download their conversation data at any time. The full conversation history is stored in the tenant's chat-messages DynamoDB table and is available for export.
If a customer's compliance requirements mandate conversation content logging, this can be enabled on a per-tenant basis. Content logs are stored in the tenant's own S3 bucket, encrypted with the tenant's KMS key, and billed to the tenant's usage. This is not enabled by default for any tenant.
Customer data is never used to train, fine-tune, evaluate, or improve any AI model. This is guaranteed by AWS Bedrock's data processing terms — customer data processed through Bedrock is not used by AWS or the model provider for any purpose beyond generating the immediate response.
Every tenant has a dedicated Amazon Cognito user pool. All API requests (except /api/health and /api/auth/config) require a valid JWT Bearer token validated against the tenant's Cognito user pool.
APEX enforces 9 Cognito groups server-side via Python decorators — not client-side checks:
| Role | Capabilities |
|---|---|
apex-platform-admin | Full platform access, all tenants |
apex-partner-admin | Tenant administration, user management |
apex-alliance-manager | Read-only access to all chats, oversight |
apex-opportunity-manager | Opportunity approval, pipeline management |
apex-sa-manager | Review approval, SA oversight |
apex-solution-architect | Chat creation, review submission and approval |
apex-overlay | Read-only access to assigned chats |
apex-sales-manager | Sales team oversight, read-only chat access |
apex-sales-person | Chat creation, opportunity drafting |
Self-approval is blocked on all approval workflows — the submitter and approver must be different users.
custom:idp_groups claimAPEX supports SCIM 2.0 for automated user lifecycle management with enterprise identity providers (Entra ID, Okta, OneLogin). SCIM endpoints authenticate via a dedicated bearer token stored in AWS Secrets Manager, rotatable without application redeployment.
APEX inspects user inputs before they reach the AI model. Detection covers:
[SYSTEM UPDATE], [OVERRIDE], ASSISTANT DIRECTIVE, and similar prompt injection patternsWhen an injection is detected or the model returns an empty response, APEX returns an identical refusal message in both cases. This prevents attackers from distinguishing between a detected injection and a model failure — they get no signal about whether their attack was identified.
Model responses are validated against the APEX domain. Responses that fall outside the platform's scope (e.g., attempting to discuss unrelated topics) trigger a guardrail refusal that redirects the conversation.
Bedrock context window limits are caught and handled gracefully. Users receive a clear error message rather than a failed request or truncated response.
Traffic to AWS services stays on the AWS backbone and never traverses the public internet:
| Endpoint Type | Services | Cost |
|---|---|---|
| Gateway (free) | S3, DynamoDB | $0 |
| Interface | STS, Bedrock Runtime, Partner Central Selling API | Per-hour + data processing |
VPC Endpoints are transparent to application code — the AWS SDK automatically routes through them when they exist in the VPC. No code changes are needed.
WAF is deployed on the ALB with the following rules:
EC2 instances have no SSH keys provisioned. All infrastructure access uses AWS Systems Manager Session Manager, which provides audited, IAM-authenticated access without opening inbound ports.
Security groups follow the principle of least privilege and reference other security groups rather than CIDR blocks:
All AI-generated content intended for customers goes through a review process:
PENDING_REVIEW)Self-review is enforced at the route level — the submitter and approver must be different users.
Opportunities submitted to AWS Partner Central go through a separate approval workflow:
When APEX submits opportunities to AWS Partner Central on behalf of a tenant:
CloudFormation templates are written and validated. Deployment is pending.
All stateful CloudFormation resources (DynamoDB tables, S3 buckets, KMS keys, CloudWatch Log Groups) have DeletionPolicy: Retain. This prevents accidental data loss if a CloudFormation stack is deleted.
Recovery Point Objective (RPO) and Recovery Time Objective (RTO) are documented in operational runbooks with tested procedures for each resource type.
CloudFormation templates are written and validated. Deployment is pending.
| Alarm | What It Detects |
|---|---|
| ALB Target Health | Unhealthy backend instances |
| 5xx Error Rate | Application errors exceeding threshold |
| Latency | Response time exceeding threshold |
| Auth Failures | Metric filter on authentication errors in logs |
| WAF Blocked Requests | Attack traffic patterns |
| DynamoDB Throttling | Consumed capacity approaching limits |
Alarms notify a per-tenant SNS topic with email subscription.
APEX_{MODULE}_{FUNCTION} prefix with key=value pairsAll customer data processing occurs within AWS services in the us-east-1 region. No other third-party processors touch customer data.
| Subprocessor | Purpose | Data Access | Location |
|---|---|---|---|
| AWS (Bedrock) | LLM inference | Processes prompts, returns responses, no retention | us-east-1 |
| AWS (DynamoDB) | Data storage | Stores tenant data, encrypted with tenant KMS key | us-east-1 |
| AWS (S3) | Document and artifact storage | Stores uploaded documents, encrypted | us-east-1 |
| AWS (Cognito) | Authentication | Stores user identity, manages sessions | us-east-1 |
| AWS (KMS) | Key management | Manages encryption keys, never exposes plaintext | us-east-1 |
| AWS (CloudWatch) | Monitoring | Receives operational logs (no conversation content) | us-east-1 |
| AWS (SES) | Email notifications | Sends system notifications only | us-east-1 |
| Field | Value |
|---|---|
| Version | 1.0 |
| Last Updated | 2026-03-28 |
| Owner | Jason Brown, Tap Innovations LLC |
| Review Cadence | Quarterly, or when significant architecture changes occur |
| Next Review | 2026-06-28 |
| Date | Version | Change |
|---|---|---|
| 2026-03-28 | 1.0 | Initial release |
Questions about these controls? privacy@discovertap.com
Tap Innovations LLC, Apopka, Florida, United States