# Spike: Blue MCP Server on Superviber Infrastructure
| | |
|---|---|
| **Status** | In Progress |
| **Date** | 2026-01-30 |
| **Time Box** | 1 hour |
---
## Question
How can we run the Blue MCP server on Superviber infrastructure while maintaining client data sovereignty, encryption, and revocable access?
---
## Context
The current architecture (Appendix A of the financial portfolio doc) assumes Blue MCP runs in the client's AWS account. However, running MCP on Superviber infrastructure offers benefits:
- **Simpler client onboarding**: No deployment required in client account
- **Centralized updates**: Push new features without client coordination
- **Operational visibility**: Better observability and debugging
- **Cost efficiency**: Shared infrastructure across clients
The challenge: maintain data sovereignty guarantees while centralizing compute.
---
## Architecture Options
### Option A: Proxy Model with Client Data Store
MCP server on Superviber infra acts as stateless compute. All persistent data remains on client infrastructure, accessed via secure API.
```mermaid
flowchart TB
subgraph CLIENT["Client AWS Account"]
direction TB
DS[("Data Store
(S3/DynamoDB)")]
KMS["Client KMS"]
API["Client API Gateway"]
DS --- KMS
API --- DS
end
subgraph SV["Superviber Infrastructure"]
direction TB
MCP["Blue MCP Server"]
INF["Infisical
(Secrets)"]
MCP --- INF
end
subgraph CLAUDE["Claude Code"]
CC["User Session"]
end
CC -->|"MCP Protocol
(TLS 1.3)"| MCP
MCP -->|"Cross-Account
AssumeRole"| API
style CLIENT fill:#e8f5e9
style SV fill:#e3f2fd
style CLAUDE fill:#fff3e0
```
**Data Flow:**
1. Claude Code connects to Blue MCP on Superviber infra
2. MCP assumes cross-account role to access client API
3. Client API reads/writes to encrypted data store
4. Data encrypted by client KMS - MCP never sees plaintext keys
5. MCP processes in memory, never persists client data
### Option B: PrivateLink Model
AWS PrivateLink provides private connectivity without traversing public internet.
```mermaid
flowchart LR
subgraph CLIENT["Client VPC"]
direction TB
DS[("Encrypted
Data Store")]
EP["VPC Endpoint
(PrivateLink)"]
DS --- EP
end
subgraph SV["Superviber VPC"]
direction TB
MCP["Blue MCP"]
NLB["Network Load
Balancer"]
ES["Endpoint
Service"]
MCP --- NLB --- ES
end
EP <-->|"Private
Connection"| ES
style CLIENT fill:#e8f5e9
style SV fill:#e3f2fd
```
**Pros:** Traffic never leaves AWS backbone, lower latency
**Cons:** More complex setup, per-client PrivateLink costs
### Option C: Hybrid with Edge Cache
MCP runs on Superviber with optional edge caching for read-heavy ADR/RFC data.
```mermaid
flowchart TB
subgraph CLIENT["Client Account"]
DS[("Source of Truth
(Encrypted)")]
HOOK["Webhook
on Change"]
end
subgraph SV["Superviber"]
direction TB
MCP["Blue MCP"]
CACHE[("Edge Cache
(Ephemeral)")]
MCP --- CACHE
end
DS -->|"Sync on
Change"| HOOK
HOOK -->|"Invalidate"| CACHE
MCP <-->|"Read/Write"| DS
style CLIENT fill:#e8f5e9
style SV fill:#e3f2fd
```
**Pros:** Better performance for read-heavy workloads
**Cons:** Cache adds complexity, eventual consistency
---
## Recommended Architecture: Option A (Proxy Model)
The proxy model is simplest and maintains strongest data sovereignty guarantees.
### Detailed Architecture
```mermaid
flowchart TB
subgraph CLAUDE["Claude Code (User Machine)"]
CC["Claude Session"]
end
subgraph SV["Superviber Infrastructure"]
direction TB
subgraph MCP_CLUSTER["MCP Cluster (EKS)"]
MCP1["MCP Pod 1"]
MCP2["MCP Pod 2"]
MCPN["MCP Pod N"]
end
ALB["Application
Load Balancer"]
INF["Infisical"]
ALB --> MCP1 & MCP2 & MCPN
MCP1 & MCP2 & MCPN --> INF
end
subgraph CLIENT["Client AWS Account"]
direction TB
subgraph VPC["Client VPC"]
APIGW["API Gateway
(Private)"]
LAMBDA["Lambda
(Data Access)"]
subgraph DATA["Data Layer"]
S3[("S3 Bucket
(Dialogues, RFCs)")]
DDB[("DynamoDB
(State, Index)")]
end
KMS["KMS Key
(Client Owned)"]
end
IAM["IAM Role
(Cross-Account)"]
APIGW --> LAMBDA --> DATA
DATA --> KMS
end
CC -->|"① MCP over TLS 1.3"| ALB
MCP1 -->|"② AssumeRole"| IAM
IAM -->|"③ Scoped Access"| APIGW
style CLAUDE fill:#fff3e0
style SV fill:#e3f2fd
style CLIENT fill:#e8f5e9
style DATA fill:#c8e6c9
```
### Request Flow
```mermaid
sequenceDiagram
participant CC as Claude Code
participant MCP as Blue MCP
(Superviber)
participant INF as Infisical
participant STS as AWS STS
participant API as Client API
participant KMS as Client KMS
participant S3 as Client S3
CC->>MCP: blue_rfc_get("0042")
MCP->>INF: Get client credentials
INF-->>MCP: Client ID, Role ARN
MCP->>STS: AssumeRole(client_role_arn)
STS-->>MCP: Temporary credentials (1hr)
MCP->>API: GET /rfcs/0042
API->>S3: GetObject(rfcs/0042.md)
S3->>KMS: Decrypt(data_key)
KMS-->>S3: Plaintext key
S3-->>API: Decrypted content
API-->>MCP: RFC content
MCP-->>CC: RFC document
Note over MCP: Data processed in memory
Never persisted
```
### Access Control Matrix
| Resource | Superviber Access | Client Control |
|----------|-------------------|----------------|
| Blue MCP Server | Owns & operates | N/A |
| Client API Gateway | Invoke via role | Creates/deletes endpoint |
| Client S3 Bucket | Read/write via role | Owns bucket, sets policy |
| Client DynamoDB | Read/write via role | Owns table, sets policy |
| Client KMS Key | **No access** | Full control |
| Infisical Secrets | Read (membership) | Owns workspace, can revoke |
| IAM Cross-Account Role | AssumeRole | Creates/deletes role |
### Client IAM Role Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowBlueMCPAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::client-blue-data",
"arn:aws:s3:::client-blue-data/*"
]
},
{
"Sid": "AllowDynamoDBAccess",
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/blue-*"
},
{
"Sid": "DenyKMSAccess",
"Effect": "Deny",
"Action": "kms:*",
"Resource": "*"
}
]
}
```
**Key point:** The `DenyKMSAccess` statement ensures Superviber can never access encryption keys directly. S3 and DynamoDB use envelope encryption - they decrypt data using the KMS key, but the key itself never leaves KMS.
### Trust Policy (Client Creates)
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SUPERVIBER_ACCOUNT_ID:role/BlueMCPServiceRole"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "${client_external_id}"
}
}
}
]
}
```
**Revocation:** Client removes or modifies this trust policy → immediate access termination.
---
## Infisical Integration
```mermaid
flowchart LR
subgraph CLIENT_INF["Client's Infisical Workspace"]
direction TB
SEC1["AWS_ROLE_ARN"]
SEC2["EXTERNAL_ID"]
SEC3["API_ENDPOINT"]
SEC4["ANTHROPIC_API_KEY"]
end
subgraph SV_INF["Superviber Infisical"]
direction TB
SVC["Service Token
(Read-Only)"]
end
subgraph MCP["Blue MCP"]
ENV["Runtime Env"]
end
SVC -->|"Membership"| CLIENT_INF
CLIENT_INF -->|"Inject"| ENV
style CLIENT_INF fill:#e8f5e9
style SV_INF fill:#e3f2fd
```
**Client onboarding:**
1. Client creates Infisical workspace
2. Client adds required secrets (role ARN, endpoint, etc.)
3. Client invites Superviber service account (read-only)
4. Client can revoke by removing membership
---
## Data Sovereignty Guarantees (Updated)
| Guarantee | Previous (Client Infra) | New (Superviber Infra) |
|-----------|-------------------------|------------------------|
| Data at rest | Client S3/KMS | Client S3/KMS (unchanged) |
| Data in flight | TLS 1.3 | TLS 1.3 (unchanged) |
| Encryption keys | Client KMS | Client KMS (unchanged) |
| Compute location | Client account | Superviber account |
| Data in memory | Client account | Superviber account (ephemeral) |
| Revocation | IAM + Infisical | IAM + Infisical (unchanged) |
| Audit trail | Client CloudTrail | Client CloudTrail + Superviber logs |
**New consideration:** Data passes through Superviber memory during processing. Mitigations:
- No persistence - data only held during request lifecycle
- Memory encryption at rest (EKS with encrypted nodes)
- SOC 2 attestation for Superviber infrastructure
- Option for dedicated/isolated compute per client
---
## Client Onboarding Flow
```mermaid
flowchart TB
A["1. Client signs agreement"] --> B["2. Client creates
Infisical workspace"]
B --> C["3. Client provisions
IAM role with trust policy"]
C --> D["4. Client creates
S3 bucket + DynamoDB"]
D --> E["5. Client adds secrets
to Infisical"]
E --> F["6. Client invites
Superviber to workspace"]
F --> G["7. Superviber configures
MCP for client"]
G --> H["8. Client connects
Claude Code to MCP"]
style A fill:#ffecb3
style H fill:#c8e6c9
```
**Estimated onboarding time:** 30 minutes with Terraform/CDK templates provided.
---
## Open Questions
1. **Multi-tenancy:** Single MCP cluster serving all clients, or isolated per client?
- Single cluster: Cost efficient, simpler ops
- Isolated: Stronger security boundary, client preference for finance
2. **Latency:** Cross-account API calls add ~50-100ms per request. Acceptable?
- Most MCP operations are not latency-sensitive
- Dialogue runs are already async
3. **Compliance:** Does data-in-memory on Superviber infra affect client's compliance posture?
- May need to add SOC 2 Type II for Superviber
- Some clients may still require fully client-hosted
4. **Failover:** If Superviber MCP is down, clients have no access
- Consider multi-region deployment
- Or provide fallback to client-hosted MCP
---
## Recommendation
Proceed with **Option A (Proxy Model)** with the following implementation:
1. Deploy Blue MCP on EKS in Superviber AWS account
2. Use Infisical for per-client credential management
3. Provide Terraform/CDK module for client-side infrastructure
4. Offer "dedicated compute" tier for compliance-sensitive clients
5. Document the memory-processing caveat in security docs
**Next steps:**
- [ ] Create RFC for this architecture
- [ ] Build Terraform module for client infrastructure
- [ ] Add multi-tenant support to Blue MCP
- [ ] Draft updated security/compliance documentation
---
*Investigation by Blue*