Kubernetes Distribution Compatibility¶
Compatibility depends on the exact release, node kernel, active LSM and CNI. The component inventory below is not live chart qualification. The measured release path is single-node GKE COS/Calico; EKS, AKS and k3s inventories do not establish equivalent deployment support. Check Platform Compatibility and Supported Paths before selecting a platform.
Compatibility Matrix¶
Managed Kubernetes Services¶
| Distribution | Operator | Wrapper | eBPF Agent | Notes |
|---|---|---|---|---|
| GKE Standard (Ubuntu) | Requires verified nodes | Requires verified nodes | Refused on measured stock image | Measured 6.8.0-1062-gke lacks active BPF LSM; see platform evidence |
| GKE Standard (COS) | Measured cohort only | Measured cohort only | Ready on measured node | 6.12.105+ passed strict readiness through lsm+fmod_ret; qualify each image/release against platform evidence |
| GKE Autopilot | Unsupported for protected workloads | Unsupported for protected workloads | Not supported | Required node agent cannot run; the default gate refuses protected workloads. No wrapper-only mode is qualified |
| EKS (Amazon Linux 2/2023) | Not qualified here | Not qualified here | Not qualified here | No live chart qualification. AL2 capabilities remain unknown; AL2023 vendor defaults need running-node verification. Verify CNI NetworkPolicy enforcement explicitly |
| EKS (Ubuntu) | Not qualified here | Not qualified here | Not qualified here | No live chart qualification; verify active BPF LSM, required vectors and enforcing CNI on the exact AMI |
| EKS (Bottlerocket) | Not qualified here | Not qualified here | Not qualified here | Vendor configuration evidence only; active LSM, agent vectors, SELinux interaction and enforcing CNI require qualification |
| EKS Fargate | Unsupported for protected workloads | Unsupported for protected workloads | Not supported | No DaemonSets or host access; the default gate refuses protected workloads. No wrapper-only mode is qualified |
| AKS (Ubuntu 22.04 / 24.04) | Requires verified nodes | Requires verified nodes | Expected to refuse (assessed, not run) | Assessed stock defaults omit bpf; actual enforcement/refusal needs live evidence. A verified node configuration is required |
| AKS (Azure Linux 3.0) | Requires verified nodes | Requires verified nodes | Expected to refuse (assessed, not run) | Assessed default LSM list excludes bpf, conflicting with the dated March record below. Verify the running node; no current live AKS qualification |
| OpenShift (RHEL 9) | Not qualified here | Not qualified here | Not qualified here | No live chart qualification here; verify active BPF LSM, required vectors and the node-agent SCC |
| OpenShift (RHEL 8) | Not qualified here | Not qualified here | Not qualified here | No live chart qualification here; missing kprobe override alone does not settle readiness. Verify active LSM and required vectors |
Self-Managed Distributions¶
| Distribution | Operator | Wrapper | eBPF Agent | Notes |
|---|---|---|---|---|
| kubeadm (Ubuntu 22.04+) | Not qualified here | Not qualified here | Not qualified here | No live qualification here. A default Ubuntu kernel is not sufficient evidence; verify active BPF LSM and required vectors |
| k3s | Not qualified here | Not qualified here | Not qualified here | Guest-kernel CI is not chart qualification; strict direct-mode workload startup has known failures. See Supported Paths |
| RKE2 | Not qualified here | Not qualified here | Not qualified here | No live qualification here; verify exact host kernel, active LSM, node-agent readiness and CNI |
| Talos Linux | Not qualified here | Not qualified here | Not qualified here | No live qualification here; immutable OS and compiled BPF/BTF do not prove node-agent readiness |
Local Development¶
| Distribution | Operator | Wrapper | eBPF Agent | Notes |
|---|---|---|---|---|
| kind | Not qualified here | Not qualified here | Not qualified here | No qualification here; containers share the host kernel, whose active LSM and required vectors must be checked |
| minikube (Docker driver) | Not qualified here | Not qualified here | Not qualified here | No qualification here; shares the host kernel |
| minikube (VM driver) | Not qualified here | Not qualified here | Not qualified here | No qualification here; verify the actual VM kernel and active LSM |
| Docker Desktop (with K8s) | Not qualified here | Not qualified here | Not qualified here | Not qualified; verify LinuxKit kernel capabilities and node-agent admission |
Component Requirements¶
Operator¶
The operator is a standard Kubernetes controller with a mutating admission webhook. It has minimal requirements:
| Requirement | Minimum | Notes |
|---|---|---|
| Kubernetes | 1.30+ | Uses admissionregistration.k8s.io/v1 |
| Architecture | amd64; arm64 unverified | Artifact availability does not establish deployment qualification |
| Permissions | ClusterRole | See the generated RBAC inventory below; default inmemory grants no Secret verbs. Other backend selections can render Secret access |
| Network | Webhook reachable from API server | Service cloudtaser-operator-webhook on port 443 |
Wrapper¶
The wrapper runs as PID 1 inside application containers. Requirements depend on the desired protection level:
| Requirement | Minimum | For Full Protection |
|---|---|---|
| Protected deployment | Active BPF LSM and required agent vectors on the node; version alone is insufficient | Additionally verify memfd_secret (Linux 5.14+ with CONFIG_SECRETMEM) |
| Architecture | amd64; arm64 unverified | Qualify the complete protection path on the exact architecture |
| libc | Startup and delivery depend on the runtime | Dynamic glibc interposition or a validated CTSECR02 native-FD consumer; qualify the actual image |
| Secret delivery connectivity | TLS to the configured broker or direct store | Verify the selected delivery contract |
| Capabilities | None required | CAP_IPC_LOCK recommended for mlock |
Runtime-specific secret delivery
Starting the wrapper on an image does not establish its secret-delivery boundary. Supported dynamic glibc delivery can preserve ordinary application getters without application code changes. Snapshot runtimes need the matching mode; their ordinary heap copies are outside the protected memfd region. Static/musl or missing-interposer fallback retains secret values in the initial kernel environment for the process lifetime. Explicit strip/strict is refused on those fallback paths. Native-FD requires an application that implements the CTSECR02 reader. Use the generated runtime table below and qualify the actual image and entrypoint.
eBPF Agent¶
The eBPF agent has the strictest requirements because it loads BPF programs into the kernel:
| Requirement | Minimum | For Full Protection |
|---|---|---|
| Linux kernel | Required BPF/BTF features and active BPF LSM; verify the exact image | Every required vector must have an effective synchronous deny path; kernel version alone is insufficient |
| BTF | Required for CO-RE | /sys/kernel/btf/vmlinux must exist |
| Capabilities | Drop ALL, add BPF, PERFMON, SYS_RESOURCE |
Same; SYS_ADMIN belongs only to the explicit legacy profile |
| Pod security | Default privileged: false, UID 0, narrow capabilities and required host access |
Node policy must admit this exact profile; legacy profile is separately privileged |
| Host access | hostPID: true |
Required for cross-namespace PID monitoring |
| DaemonSet | Must be allowed | Not supported on Fargate or Autopilot |
S3 Proxy and DB Proxy¶
Both proxies are standard sidecar containers with no kernel requirements:
| Requirement | Minimum | Notes |
|---|---|---|
| Kubernetes | 1.30+ | Injected as sidecar by operator |
| OpenBao connectivity | TLS to EU OpenBao endpoint | For Transit engine key wrapping |
| Architecture | amd64; arm64 unverified | Artifact availability does not establish deployment qualification |
Kernel Requirements Per Feature¶
These are individual primitive requirements, not a supported deployment floor. The default agent additionally requires active BPF LSM and effective synchronous paths for every required vector; qualify readiness on the exact node/release.
| Feature | Kernel Config | Min Version | Impact if Missing |
|---|---|---|---|
| BPF syscall | CONFIG_BPF_SYSCALL |
Required primitive, not a deployment floor | eBPF agent cannot start |
| BTF (CO-RE) | CONFIG_DEBUG_INFO_BTF |
5.2+ | eBPF agent cannot start |
| kprobe override | CONFIG_BPF_KPROBE_OVERRIDE |
4.16+ | Vectors that need it have no synchronous deny path unless BPF LSM covers them; the default chart then reports HTTP 503 |
| memfd_secret | CONFIG_SECRETMEM |
5.14+ | Falls back to memfd_create + mlock |
| mlock | Standard | Any | Secrets may be swapped to disk |
| io_uring blocking | Tracepoints | 5.1+ | io_uring bypass possible |
See Kernel Compatibility for the full kernel support matrix.
Known Issues Per Distribution¶
GKE Autopilot¶
- eBPF agent cannot run (no privileged pods, no
hostPID) - Protected workloads are unsupported: the required agent cannot run, so the default admission/binding gate refuses them
- No wrapper-only deployment mode is qualified; a lower protection score is not a supported fallback
- Select a separately verified GKE Standard node configuration instead
EKS Fargate¶
- eBPF agent cannot run (no DaemonSets on Fargate)
- Protected workloads are unsupported: the default gate refuses workloads without a Ready node agent
- No wrapper-only deployment mode is qualified
- Select separately verified managed node groups instead of Fargate profiles
AKS node configuration¶
AKS requires a verified node configuration. Assessed stock Ubuntu
22.04/24.04 and Azure Linux 3 defaults omit bpf from the LSM list. With those
defaults the agent is expected to refuse (assessed, not run), leaving protected
workloads unavailable. Actual enforcement or refusal still needs live evidence. A compiled
CONFIG_BPF_LSM=y, kprobe override, confidential VM size or memfd_secret
support does not satisfy this requirement.
There is no current live AKS deployment qualification in this assessment. Verify the active LSM list, permitted node-agent deployment, required vector states, agent readiness and enforcing CNI on the exact node image and release. See Platform Compatibility. Do not weaken strict protection to make a stock image pass.
Dated Azure Linux 3 record — 2026-03-30¶
The earlier record for kernel 6.6.126.1-1.azl3 was labelled verified
2026-03-30. It reported CONFIG_SECRETMEM=y, CONFIG_BPF_LSM=y and BPF in the boot LSM chain;
CONFIG_BPF_KPROBE_OVERRIDE was not set. The record is labelled verified; provenance not recorded.
That label alone does not establish a live node inspection. Its reported active
LSM conflicts with the later vendor-default assessment excluding bpf.
Keep that conflict visible: neither record qualifies a different node image or
release. Read /sys/kernel/security/lsm on the actual node, confirm bpf is
active, and verify the released agent's required vectors, readiness and protected
workload admission. Do not infer a current AKS pass or refusal from either record.
AKS Helm upgrade note¶
AKS has a built-in admissionsenforcer that modifies webhook namespaceSelector fields. The Helm chart includes admissions.enforcer/disabled: "true" annotations to prevent SSA conflicts during upgrades.
OpenShift on RHEL 8¶
- Red Hat explicitly disabled
CONFIG_BPF_KPROBE_OVERRIDEin the RHEL 8 kernel config - With the default chart the eBPF agent is not ready and protected workloads are refused (no synchronous deny path)
- A RHEL 9 image also needs independent active-LSM/vector/SCC qualification; do not infer support from its name
kind / minikube (local development)¶
- eBPF features depend on the host kernel (containers share the host kernel)
- On macOS with Docker Desktop, the LinuxKit VM kernel may lack BTF support
- For full eBPF testing locally, use a Linux host with a 5.8+ kernel
- No blanket local-environment qualification is established; verify admission, active LSM, required vectors and protected startup
Talos Linux¶
- Immutable OS with no shell access
- Debugging requires
talosctlinstead ofkubectl execon nodes - Kernel configuration supports BPF and BTF by default
- No live CloudTaser chart qualification is established here; verify the exact Talos image and node-agent admission/readiness
Multi-Cluster Support¶
A single EU-hosted OpenBao can serve multiple Kubernetes clusters across different cloud providers and regions. The CLI's migration plan workflow supports this through per-cluster plan files:
# Generate plans for each cluster
cloudtaser-cli target discover --kubeconfig ~/.kube/gke-eu -o plan-gke.yaml
cloudtaser-cli target discover --kubeconfig ~/.kube/eks-eu -o plan-eks.yaml
# Apply both plans to the same vault
cloudtaser-cli source apply-plan plan-gke.yaml --openbao-addr https://vault.eu.example.com --token hvs.TOKEN
cloudtaser-cli source apply-plan plan-eks.yaml --openbao-addr https://vault.eu.example.com --token hvs.TOKEN
Each cluster gets its own plan. All plans point to the same OpenBao. OpenBao policies and Kubernetes auth roles are per-namespace, so clusters can share OpenBao paths or use isolated paths depending on the naming convention.
See Enterprise Deployment Architecture for the full multi-cluster topology.
Checking Compatibility¶
Use cloudtaser-cli target validate to check cluster compatibility:
This checks:
- OpenBao connectivity and health
- Kubernetes auth configuration
- Node kernel versions
- eBPF agent availability per node
For per-node kernel checks:
# Check kernel versions across all nodes
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kernelVersion}{"\t"}{.status.nodeInfo.osImage}{"\n"}{end}'
# Check BPF kprobe override support on a specific node
kubectl debug node/<node-name> -it --image=busybox -- \
zcat /proc/config.gz 2>/dev/null | grep CONFIG_BPF_KPROBE_OVERRIDE
Operator RBAC from the published chart¶
| Resources | Verbs | Condition from published chart |
|---|---|---|
["clusterroles"] |
["get"] |
Operator enabled |
["cloudtaserconfigs"] |
["get", "list", "watch", "create", "update", "patch", "delete"] |
Operator enabled |
["cloudtaserconfigs/status"] |
["get", "update", "patch"] |
Operator enabled |
["cloudtaserconfigs/finalizers"] |
["update"] |
Operator enabled |
["secretmappings"] |
["get", "list", "watch"] |
Operator enabled |
["secretmappings/status"] |
["get", "update", "patch"] |
Operator enabled |
["debugreports"] |
["get", "list", "watch"] |
Operator enabled |
["debugreports/status"] |
["get", "update", "patch"] |
Operator enabled |
["cloudtaserpolicies"] |
["get", "list", "watch", "create", "update", "patch", "delete"] |
Operator enabled |
["cloudtaserpolicies/status"] |
["get", "update", "patch"] |
Operator enabled |
["cloudtaserpolicies/finalizers"] |
["update"] |
Operator enabled |
["namespaces"] |
["get", "list", "watch", "patch"] |
Operator enabled |
["namespaces/status"] |
["patch"] |
Operator enabled |
["secrets"] |
["get", "list", "watch", "create", "update"] |
Operator enabled; backend differs from inmemory |
["pods"] |
["get", "list", "watch"] |
Operator enabled |
["nodes"] |
["get", "list", "watch", "patch"] |
Operator enabled |
["serviceaccounts"] |
["get", "list", "watch"] |
Operator enabled |
["events"] |
["create", "patch"] |
Operator enabled |
["mutatingwebhookconfigurations"] |
["get", "list", "watch", "create"] |
Operator enabled |
["mutatingwebhookconfigurations"] |
["patch"] |
Operator enabled |
["deployments"] |
["get", "list", "watch", "patch"] |
Operator enabled |
["statefulsets", "daemonsets"] |
["get", "list", "watch", "patch"] |
Operator enabled |
["networkpolicies"] |
["get", "list", "watch", "create", "update"] |
Operator enabled |
["networkpolicies"] |
["delete"] |
Operator enabled |
["nodes"] |
["get", "list", "watch"] |
Operator enabled |
["limitranges"] |
["list"] |
Operator enabled |
["endpointslices"] |
["get", "list", "watch"] |
Operator enabled |
["services"] |
["get", "list", "watch"] |
Operator enabled |
["validatingwebhookconfigurations"] |
["get", "list", "watch", "create"] |
Operator enabled |
["validatingwebhookconfigurations"] |
["patch"] |
Operator enabled |
["jobs"] |
["create", "delete", "get", "list", "watch"] |
Operator enabled |
["tokenreviews"] |
["create"] |
Operator enabled |
["subjectaccessreviews"] |
["create"] |
Operator enabled |
["persistentvolumeclaims"] |
["get"] |
Operator enabled |
The Secret rule is conditional on a non-inmemory backend in this published chart. Rendered access is an authorization boundary; it does not prove runtime storage behavior.
Proxy deployment qualification¶
| Platform | S3 proxy | DB proxy |
|---|---|---|
| GKE Standard COS/Calico | Planned; qualification pending | Planned; qualification pending |
| GKE Standard Ubuntu | Planned; qualification pending | Planned; qualification pending |
| EKS node groups | Planned; qualification pending | Planned; qualification pending |
| AKS | Planned; qualification pending | Planned; qualification pending |
| k3s and other distributions | Planned; qualification pending | Planned; qualification pending |
Statuses use the same proxy result records as Supported Paths. Code portability does not qualify a serving path, upstream authentication, storage or TLS wiring.
Runtime delivery conditions¶
| Runtime condition | Delivery inferred from published startup code |
|---|---|
| Dynamic glibc, supported libc getters | Interposer delivery can avoid application code changes; runtime enumeration and snapshot behavior require the matching delivery mode. |
cpython with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
dotnet with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
java with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
nodejs with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
perl with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
php with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
ruby with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
shell with available glibc interposer |
Automatic strip for mapped secrets unless a native-FD or explicit inherited-environment contract is selected. Strict mode has runtime-specific validation; qualify the actual entrypoint. |
| Dynamic Go | Ordinary Go environment access is refused with interposer delivery; use a validated CTSECR02 reader or an explicitly assessed alternative. |
| Static, musl, or missing interposer | Additive initial environment fallback can retain secret values for the process lifetime. Explicit strip/strict is refused. |
| Native-FD | Requires application support for the CTSECR02 reader; ordinary environment APIs are not populated. |