Phantom — Technical Pitch
How it works, what it protects against, and why existing solutions don’t.
Architecture Overview
Three components, one goal: secrets never touch the cloud provider.
Three Components
| Component | What | Where | Phase |
|---|---|---|---|
| Mutating Webhook + Sidecar | Intercepts pod creation, injects phantom-proxy sidecar. Sidecar authenticates to OpenBao, fetches secrets, injects into app process (env vars, tmpfs files, or Unix socket) |
In-cluster | v1 (core) |
| eBPF DaemonSet | Monitors ptrace, /proc/[pid]/mem, process_vm_readv, core_dump. Detects node-level memory access attempts. Alerts + audit trail |
Per node | Phase 2 |
| EU-hosted OpenBao SaaS | Managed secrets backend. HSM-backed keys. Audit logging. Compliance dashboard. Revenue driver | EU data center | v1 |
Pod Startup Flow
- Developer deploys pod with
phantom: enabledlabel - Mutating webhook intercepts, injects
phantom-proxysidecar - Sidecar authenticates to EU OpenBao using K8s service account token + optional hardware attestation (SEV-SNP/TDX)
- OpenBao returns secrets scoped to namespace/service account
- Sidecar injects secrets into app process memory (env vars or shared tmpfs)
- App starts with secrets in memory — nothing in etcd, nothing on disk
Caching: Three Tiers
Hot cache (in-memory, instant) → Sealed local cache (encrypted, survives sidecar restart) → Grace period (existing secrets valid during vault outage). Pods survive OpenBao downtime.
Threat Model: What Happens When...
| Event | Without Phantom | With Phantom |
|---|---|---|
| CLOUD Act subpoena | Provider hands over etcd with all secrets in plaintext | etcd has no secrets. Keys are in EU OpenBao, outside US jurisdiction |
| Cluster-admin compromised | kubectl get secrets reads everything |
No secrets in K8s. Can delete webhook (future pods unprotected) but can’t extract from running pods |
| Node-level attack (ptrace) | Attacker reads process memory directly | eBPF detects + alerts. Short-lived tokens (15-min TTL) limit exposure. TEE upgrade blocks it |
| Hypervisor-level read | Provider snapshots VM memory | Requires TEE (confidential VMs) to block. Without TEE: short-lived credentials limit damage |
| Webhook deleted | N/A | Running pods unaffected. eBPF + operator reconciliation loop detects + restores within seconds |
| OpenBao goes down | N/A | Running pods use cached secrets. New pods wait. No data loss |
| GDPR audit / TIA | Scramble to explain US-controlled etcd | Cryptographic proof: secrets never leave EU jurisdiction |
Why HYOK / Cloud EKM Doesn’t Solve It
Cloud providers offer “Hold Your Own Key” and External Key Manager. You control the key, they encrypt with it. But:
| Property | HYOK / Cloud EKM | Phantom |
|---|---|---|
| Protection at rest | Yes | Yes (not stored at all) |
| Protection in use | No — key in provider RAM | Yes — secrets in pod memory only |
| Provider can access plaintext | Yes — during decryption | No — never enters provider infra |
| Survives CLOUD Act | No — compelled to intercept | Yes — nothing to intercept |
| K8s Secrets in etcd | Yes (decrypted on read) | No (bypasses etcd) |
| Granular revocation | All-or-nothing | Per-secret, per-namespace |
The core difference
HYOK encrypts data with your key but processes it inside the provider’s infrastructure. Phantom ensures sensitive data never enters that infrastructure at all.
Bootstrap & Trust Establishment
The “first secret” problem: how does the cluster authenticate to EU OpenBao the first time?
- Operator runs
helm install phantom --set bootstrap-token=<token> - Token is one-time, 10-minute TTL, generated by OpenBao admin
- Phantom operator uses token to register cluster identity + exchange for long-lived mTLS cert
- Bootstrap token is discarded — never stored in etcd, never persisted
- All subsequent auth uses K8s service account tokens + mTLS
Key Transfer Security
All secret transfer uses mTLS with pinned certificates. MITM on the EU↔US link can DoS (block traffic) but cannot intercept (no valid cert). Intra-cluster: sidecar↔app is same pod (localhost), eBPF↔sidecar is kernel-space — no network path to intercept.
Runtime Memory Protection
Secrets in process memory are protected by three layers — no special hardware required:
| Attack Vector | Detection | Prevention |
|---|---|---|
| ptrace attach | eBPF tracepoint | PR_SET_DUMPABLE=0, seccomp |
| /proc/[pid]/mem read | eBPF on sys_openat |
File permissions + seccomp |
| process_vm_readv | eBPF tracepoint | seccomp filter |
| Core dump | eBPF on coredump | PR_SET_DUMPABLE=0 |
| kubectl exec | Audit log + eBPF | RBAC + OPA policies |
| Hypervisor read | Not detectable | Requires TEE (optional upgrade) |
Compensating control: 15-minute TTL derived credentials. A memory dump yields secrets that expire quickly. Rotation is continuous and automatic.
Storage & Database Sovereignty
Phantom operates at the credential layer. The table below shows what is and isn’t protected by default, and what additional steps achieve full coverage.
| Data Layer | Phantom Default | Full Protection Path |
|---|---|---|
| Kubernetes Secrets / etcd | Protected — secrets bypass etcd entirely | No additional steps needed |
| K8s-deployed DB (PostgreSQL, MongoDB, MySQL) | Full — credentials + TLS + LUKS PV encryption keys from OpenBao. All SQL queries work normally. | Run DB as StatefulSet; Phantom delivers all keys. Cloud sees only ciphertext on block storage. |
| Managed DB (RDS, Cloud SQL) | Credential protected; cloud operates DB engine, must read data to query it | Migrate to K8s-deployed DB for sovereignty. Managed DBs cannot be fully protected. |
| Object storage (S3, GCS) | Full — with client-side encryption using Phantom-delivered key, cloud stores ciphertext it can’t read | App encrypts before write (~10–50 lines); key from EU OpenBao never enters cloud infra |
| SSE-S3 / SSE-KMS | Decryption happens server-side in US infrastructure | Move to client-side encryption for full sovereignty |
| SSE-C (Customer-Provided Keys) | Phantom delivers key from EU; server-side decrypt window exists | Client-side encryption eliminates the server-side window |
| Process memory (Standard) | Short-lived TTL + detection; hypervisor can read | Phantom Hardened: AMD SEV-SNP or Intel TDX |
| Process memory (Hardened/TEE) | Hardware memory encryption; hypervisor sees ciphertext | TEE side-channel caveat: known vulns exist |
| Workload metadata | Not protected — control plane is provider-operated | Self-managed Kubernetes on-premise only |
| Inter-pod network traffic | Not encrypted by Phantom (Phase 1) | Phase 2 Veilnet; or Istio/Linkerd with Phantom-delivered certs |
Client-Side Encryption Pattern
For object storage sovereignty: Phantom delivers an AES-256 key from EU OpenBao → application encrypts before writing to S3/GCS → cloud provider stores ciphertext only. Key never enters US infrastructure. Compatible with AWS Encryption SDK, GCP Tink, or any standard AEAD implementation. Requires ~10–50 lines of application code per storage call.
See the FAQ for detailed guidance on each protection path and regulatory positioning.
Break Glass & Resilience
Webhook Deletion
If an attacker deletes the webhook: existing pods are unaffected (secrets already in memory). eBPF DaemonSet detects the deletion. Phantom operator reconciliation loop restores the webhook within seconds. Audit alert fires immediately.
Vault Outage
Three-tier cache ensures running pods continue operating. New pods enter a wait state with clear error messaging. No silent failures. Circuit breaker prevents cascading failures.
TEE: Optional Upgrade, Not Requirement
| Phantom Standard | Phantom Hardened | |
|---|---|---|
| TEE required | No — runs on any instance | Yes — SEV-SNP / TDX |
| Cloud premium | None | 5–20% instance cost |
| Hypervisor protection | Short-lived credentials only | Full memory encryption |
| Hardware attestation | K8s SA tokens only | Cryptographic hardware proof |
| Use case | Most workloads | Highest sensitivity (finance, healthcare) |
Seamless upgrade path: start Standard, enable Hardened per namespace when needed. No infrastructure migration required.
Technology Stack
| Layer | Technology | Why |
|---|---|---|
| Webhook / Operator | Go | First-class K8s client libraries, low latency |
| Sidecar | Go | Small binary, fast startup, no runtime deps |
| eBPF programs | C + libbpf / cilium/ebpf (Go) | Kernel-level, near-zero overhead |
| Secrets backend | OpenBao (Vault fork) | Open-source, battle-tested, HSM support |
| Attestation | AMD SEV-SNP / Intel TDX | Hardware root of trust |
| Secret delivery | Env vars, tmpfs, Unix socket | Zero code changes for most apps |
| SDK (optional) | Go, Java, Python, Node.js | Explicit control for apps that want it |
Regulatory Alignment
| Regulation | Alignment | How |
|---|---|---|
| GDPR Art. 32 | Strong | Encryption with customer-controlled keys, secrets never leave EU |
| GDPR Art. 44–49 | Strong | Supplementary technical measures per EDPB guidelines |
| Schrems II/III | Strong | Designed specifically for this — US provider cannot access data |
| DORA | Good | ICT risk management, third-party oversight, audit trail |
| NIS2 | Good | Supply chain security, incident reporting |
| BSI C5 / EUCS | Planned | Certification on roadmap (Month 3+) |
MVP Scope
v1 (Month 1–5)
- Mutating webhook + sidecar
- OpenBao secrets injection (env vars + tmpfs)
- Three-tier caching + circuit breaker
- AMD SEV-SNP attestation on GKE
- Prometheus metrics + basic alerts
- Helm chart + docs
Phase 2
- eBPF DaemonSet (runtime monitoring)
- SaaS dashboard + compliance reporting
- EKS + AKS support
- Intel TDX attestation
- SDK (Go, Java, Python, Node.js)
- BSI C5 + SOC 2 Type II certification