Security Model¶
Authorised application boundary
Authorised application code is trusted. An authorised app can send out a secret it has copied or encoded. Current content checks do not provide a general guarantee against this disclosure or a malicious authorised app. Memory-read tests and a Ready agent do not prove copied/encoded-secret exfiltration prevention. Enforced NetworkPolicy can restrict destinations, but allowed traffic remains a channel. The trust boundaries below apply.
Workload identity and direct store-login boundary
In direct mode, OpenBao authenticates the ServiceAccount and namespace, not the injected wrapper. Anyone who can run a pod as the application's ServiceAccount can request a matching audience-bound JWT, log in to any store role bound to that identity, and read the records its policies allow. Node root can steal the projected JWT and do the same. CloudTaser does not bind direct store release to the injected wrapper. This limit remains unresolved. Blocking exec or protecting process memory does not block a separate store login. Port/bootstrap attestation claims do not apply to direct-mode logins.
Use one workload per identity: a dedicated ServiceAccount and exact-record store policy for each app. Restrict who can create or change workloads using that ServiceAccount, including controller templates, through Kubernetes RBAC and admission policy. Namespace access alone is not isolation between apps sharing an SA. Audience checks, shorter JWT lifetimes and source CIDRs limit some replay; they do not establish wrapper identity or stop node root. Confidentiality claims on this page do not cover this credential-acquisition path.
One workload per identity applies on both direct and Port paths. Denial of a second same-identity workload on Port has not been established; a different-ServiceAccount reader test does not prove that denial.
cloudtaser is designed around a single premise: US cloud providers cannot be trusted with EU secrets. Not because they are malicious, but because US law compels them to comply with government data requests -- and EU law prohibits exactly that.
Enforcement depends on the running node
The default agent requires BPF LSM active in /sys/kernel/security/lsm;
CONFIG_BPF_LSM=y alone is insufficient. Without it, the default installation
refuses to start. BPF LSM protects the primary process-read paths; kprobe
override adds synchronous coverage for additional vectors. An explicit
reduced-mode deployment has a different threat model, including path-alias
limitations. See Platform Compatibility
for measured/config-audited platforms and per-vector limits. Confidential
computing addresses the hypervisor boundary, not malicious code inside the
guest kernel.
Threat Model¶
The Legal Reality¶
Two US laws create an irreconcilable conflict with EU data protection:
| Law | What It Does | Impact |
|---|---|---|
| CLOUD Act (2018) | Compels US companies to produce data stored anywhere in the world, regardless of where it is physically located | A US cloud provider must hand over data stored in EU data centers if served with a warrant |
| FISA Section 702 | Authorizes mass surveillance of non-US persons' communications through US service providers | EU citizens' data processed by US providers is subject to bulk collection without individualized warrants |
The Schrems II Problem
The Court of Justice of the European Union (CJEU) invalidated the EU-US Privacy Shield in Schrems II (C-311/18) precisely because these laws make it impossible for US companies to guarantee EU-equivalent data protection. Standard Contractual Clauses (SCCs) require supplementary technical measures -- cloudtaser provides them.
What cloudtaser Assumes¶
The adversary model covers three threat actors:
- The cloud provider itself -- has root access to hypervisors, management planes, and can be compelled by law to access customer data
- US government agencies -- can issue warrants, national security letters, and FISA orders to cloud providers
- Attackers who compromise a node -- escalate to root and attempt to extract secrets from running processes
cloudtaser aims to reduce provider access through covered delivery and runtime paths. This does not establish that every form of a secret is inaccessible to the provider. The wrapper fetches secrets from an EU-hosted OpenBao into process memory on the Kubernetes node, protected by kernel-level memory isolation, and monitored by eBPF enforcement programs.
Compute substrate matters
The strength of protection against the cloud provider threat actor depends on the compute substrate. On standard VMs, CloudTaser protects against software-level access; hypervisor-level protection requires confidential compute. See Confidential Computing Prerequisites for the full scoping.
Three Defense Layers¶
cloudtaser implements defense in depth through three independent components, each addressing a different attack surface:
Layer 1: Wrapper -- Memory Isolation¶
The wrapper binary runs as PID 1 inside the container. It authenticates to your EU-hosted OpenBao or OpenBao, fetches secrets over mTLS, and stores them exclusively in protected memory regions.
| Mechanism | Protection | Kernel Requirement |
|---|---|---|
memfd_secret(2) |
Removes secret pages from the kernel direct map; restricts ordinary access, not arbitrary kernel code | Linux 5.14+ with CONFIG_SECRETMEM enabled |
mlock(2) |
Pages pinned in RAM, never swapped to disk | Any Linux |
MADV_DONTDUMP |
Pages excluded from core dumps | Linux 3.4+ |
PR_SET_DUMPABLE(0) |
Disables ptrace attach, restricts /proc access | Any Linux |
| Secret delivery | Eligible glibc-dynamic programs use the interposer by default; static/musl programs use inherited environment delivery. Application copies remain subject to the memory boundary below | See runtime compatibility |
| cloudtaser Go SDK (optional) | Direct read from memfd_secret FD - bypasses the env-var intermediate for workloads whose threat model rejects it |
Any Linux 5.14+ |
The boundary of memfd_secret
memfd_secret removes the pages' direct-map alias. It does not make them
unreachable to arbitrary kernel code, and it does not protect ordinary heap
or environment copies created by the application. Kernel integrity and
restrictions on privileged node access remain part of the trust boundary.
Layer 2: eBPF -- Runtime Enforcement¶
A daemonset deploys eBPF programs on every node. These programs attach to kernel functions and provide runtime instrumentation. The published source has 37 catalogued kprobe syscall programs; verify each active detection and denial path:
- Memory access -- primary procfs and ptrace read paths are denied with BPF LSM active; consult the deployed vector states for each additional syscall.
- Exfiltration -- synchronous blocking depends on the available hook and kprobe override; detect-and-kill paths can have a disclosure window.
- Privilege escalation and evasion -- monitored according to the deployed enforcement profile; the default profile is not a blanket prohibition on every privileged kernel operation.
BPF LSM and kprobe override are distinct capabilities. Tier 2 retains LSM
protection for primary read paths while reporting secondary vectors such as
process_vm_readv, io_uring, zero-copy I/O and setns as detect-only in the
agent's current contract. A reactive kill does not establish that zero bytes were
read. Assess the actual status and vector evidence rather than a platform name.
Layer 3: S3 Proxy -- Storage Encryption¶
A transparent proxy sits between applications and cloud object storage (S3, GCS, Azure Blob). Data is encrypted with keys held in your EU OpenBao before it reaches the cloud provider. The provider stores only ciphertext and never holds decryption keys.
| Aspect | How It Works |
|---|---|
| Key management | Encryption keys fetched from EU OpenBao, held only in wrapper-protected memory |
| Encryption | Client-side AES-256-GCM before data leaves the pod |
| Transparency | Drop-in replacement for S3 SDK endpoint -- no application changes required |
| Key rotation | Automatic re-encryption with new keys, old ciphertext remains readable during transition |
Defense-of-the-defense: what happens if an attacker targets the eBPF daemon first?¶
A node-root attacker can try to kill the agent before reading a protected process. The shipped responses have distinct scopes:
- Pinned BPF state can outlive the userspace agent. Pinned maps and links support agent replacement. Agent death does not itself prove protection was removed, and process liveness alone does not prove pinned enforcement is intact.
- The wrapper checks its authenticated enforcement state. Loss or expiry of protection terminates the protected child and revokes secret use through the existing fail-closed path. This is a bounded response, not proof of zero exposure during arbitrary kernel compromise.
- The operator gates admission and binding. For protected workloads, the
node-aware admission check requires a non-terminating, Running, Ready agent
with ready containers on the target node. Lookup failures deny admission.
The operator does not taint nodes
NotReadyor drain them; those actions are not implemented by this gate.
Node-root protection is tamper-evident and fail-closed, not absolute
Under permissive node defaults, root can load kernel modules or BPF, kexec
on images without an effective lockdown/Secure Boot restriction, read
application heap copies through /proc/kcore, or remove bpffs pins after
killing the agent. The shipped defenses do not close every such path.
Detection, child termination and revocation do not undo a disclosure that
already occurred. memfd_secret removes the direct-map alias for its own
pages; it is not an isolation boundary against arbitrary kernel execution.
Use node-image integrity, module/BPF loading policy, lockdown where supported, and attested confidential compute as additional controls appropriate to the threat model. Confidential compute protects against the external hypervisor; it does not make a compromised guest kernel trustworthy.
Trust Boundaries¶
What cloudtaser Protects¶
| Threat | Protection |
|---|---|
| Cloud provider reading secrets from etcd | Secrets never enter etcd or Kubernetes Secrets API |
| Cloud provider reading secrets from disk | Default protected buffers use memfd_secret/locked memory; injected support files use memory-backed emptyDir. Application copies and swap require separate assessment |
| Cloud provider reading process memory | In-guest controls require a trustworthy kernel; hypervisor resistance additionally requires confidential compute |
| Root attacker dumping process procfs files | BPF LSM denies monitored /proc/PID/mem and /proc/PID/environ reads when active; this does not cover arbitrary kernel code or all /proc/kcore copies |
| Root attacker using ptrace | BPF LSM denies ptrace ATTACH/SEIZE on monitored processes when active; the default agent refuses without BPF LSM |
| Container escape followed by host-level exfiltration | Host enforcement covers configured paths; node-root and authorised application disclosure remain limits |
| Network exfiltration of secrets | Content matching covers specific patterns; enforced NetworkPolicy restricts destinations. An authorised app can send out a secret it copied or encoded |
| Core dump exposure | MADV_DONTDUMP + eBPF blocks coredump_filter writes |
What cloudtaser Does NOT Protect¶
Understand the boundaries
No security product protects against everything. These are the known limitations.
| Threat | Why | Mitigation Path |
|---|---|---|
| Arbitrary guest-kernel execution or unrestricted node root | Kernel code and ordinary application copies are outside the memfd_secret isolation boundary | Kernel integrity, lockdown/loading policy and least privilege |
| Hypervisor-level memory inspection | The hypervisor has physical access to VM RAM | Confidential computing (AMD SEV-SNP, Intel TDX, ARM CCA) |
| DMA attacks from host devices | Physical memory access bypasses all software protections | Confidential computing with IOMMU enforcement |
| Cold boot attacks | Physical RAM can be frozen and read | Confidential computing with memory encryption |
| Authorised application copying, encoding, logging or transmitting secrets | Application code can access and disclose delivered values; no general prevention guarantee | Trust/review application code and restrict egress; remaining allowed channels still need assessment |
| Secrets during active CPU processing | Values in CPU registers during computation | Spectre/Meltdown kernel mitigations (verified by protection score) |
| Hibernate / suspend-to-disk | Full RAM written to disk as a kernel-level operation | Disable hibernate on cloudtaser nodes |
Comparison with Alternatives¶
cloudtaser's approach is fundamentally different from other Kubernetes secret management tools because it eliminates the Kubernetes Secrets API as an attack surface entirely.
| cloudtaser | Vault Agent | External Secrets Operator | Sealed Secrets | |
|---|---|---|---|---|
| Secrets in etcd | Never | Never (with annotations) | Yes -- creates K8s Secrets | Yes -- creates K8s Secrets |
| Secrets on disk | Never | Yes -- writes to tmpfs/volume | Yes -- mounted as files or env vars | Yes -- standard K8s Secret mount |
| Memory protection | memfd_secret, mlock, MADV_DONTDUMP | None | None | None |
| Runtime enforcement | 37 catalogued kprobe syscall programs | None | None | None |
| Root attacker resistance | Active read-path enforcement with the node-root limitations above | Root can read tmpfs files | Root can read mounted secrets | Root can read mounted secrets |
| Cloud provider resistance | Conditional on node integrity and confidential-compute substrate | OpenBao is EU-hosted but secrets land in plaintext on node | Provider can read etcd | Provider can read etcd |
| Application changes | Depends on the runtime API: interposer by default for eligible glibc-dynamic programs; inherited environment for static/musl programs · Optional SDK | None (file/env template) | None (K8s native) | None (K8s native) |
The key difference
Vault Agent, ESO, and Sealed Secrets all eventually produce a Kubernetes Secret or a file on disk. cloudtaser never does. Secrets exist only in process memory, protected by kernel-level isolation and monitored by eBPF enforcement.
vs. confidential-compute-native and sovereign-cloud stacks¶
cloudtaser is not the same class of product as a CC-native Kubernetes distribution or a sovereign-cloud provider. A serious evaluation should understand the trade-off explicitly.
| cloudtaser | Nitro Enclaves (direct) | Constellation (Edgeless) | Fortanix / SCONE | SecNumCloud (OVH / Bleu / Outscale) | |
|---|---|---|---|---|---|
| Deployment shape | Annotation-based operator on supported node kernels | App-level enclave on EC2 | Replaces the K8s distribution with a CC-native one | Application-level TEE runtime (SGX / SEV) | Replaces the cloud provider |
| Code changes required | Depends on runtime API and delivery mode · SDK optional | Yes - app must be enclave-aware (Nitro vsock API) | None in most cases - existing manifests still work | Yes - apps ported to run inside enclave | None - app runs as usual |
| Hypervisor-memory sovereignty | Only on CC node SKUs (see deployment guide) | Yes - hardware enclave | Yes - all nodes are SEV-SNP/TDX | Yes - TEE isolation | Depends - N/A if provider already trusted |
| Multi-cloud portability | Depends on the running node kernel and privileged-agent policy | No - AWS-only | Yes, but requires the Constellation distro | Varies - SGX is Intel-only, SEV is AMD-only | No - you commit to one sovereign provider |
| Migration cost | Helm install + annotations | Rewrite application for Nitro | Migrate the cluster onto Constellation | Port applications into enclaves | Move workloads off hyperscaler |
| Schrems II supplementary-measure story | Yes, conditional on substrate (CC + EU-hosted OpenBao) | Yes on AWS-EU | Yes - full stack CC | Yes at the application layer | Native - provider is EU-sovereign |
| Ecosystem lock-in | Low - still on standard K8s | High - AWS APIs | Medium - Constellation distro | Medium - TEE runtime dependency | High - leaving the sovereign provider is hard |
| Maturity | Preview (2026) | GA, production | GA, production | GA, established | GA, regulated |
| Where cloudtaser wins | You already committed to managed K8s and can't re-platform | - | - | - | - |
Positioning in plain language. cloudtaser is the incrementalist path: you have GKE / EKS / AKS for talent, ecosystem, and tooling reasons, you cannot migrate to a CC-native distro or leave the hyperscaler, and you need a Schrems II supplementary-measure story that survives audit. The alternatives above are strictly stronger in specific dimensions - Nitro Enclaves is hardware-isolated but AWS-only and code-invasive; Constellation gives you CC at the cluster level but requires a migration; SecNumCloud providers give you sovereign-by-construction at the cost of leaving the hyperscaler ecosystem. None of these is the same product. If you can re-platform and the alternatives fit, take them - cloudtaser exists for customers who cannot.
We document this because it's the most honest answer to "why cloudtaser and not X?" and it's the question every procurement committee asks. If the answer is "we can move to OVH / Bleu" and the business tolerates it, OVH / Bleu is often the cleaner outcome.
Protection Levels¶
In-guest protection¶
CLOUDTASER_REQUIRE_MEMFD_SECRET=true requires the secret-memory primitive;
it does not establish complete software isolation. Active BPF LSM, appropriate
per-vector enforcement, a trustworthy kernel, and bounded wrapper failure
handling are separate requirements.
Hypervisor protection¶
Confidential computing (for example AMD SEV-SNP or Intel TDX) adds a hardware boundary against the external hypervisor, subject to attestation and key-release policy. It does not remove guest-root, application-copy, or in-process exposure. Evaluate these layers separately rather than calling the combination complete isolation at every layer.
Protection Score | Root Attack Surface | Trust Chain & Per-Pod Isolation