Defense in depth
Each boundary below has to be defeated before an attacker reaches the next one. The untrusted workload is at the center; the cluster is the outermost ring. A successful escape from the workload has to defeat every layer above before it can reach another tenant or the host.VM isolation
Every sandbox is a Kata Containers pod, which means a real VM with its own kernel running on KVM. The workload sees a virtio block device for its rootfs, a virtio NIC, and not much else. The virtual hardware surface is tiny compared to a shared host kernel.kata-firecracker-devmapperuses Firecracker — ~50k LoC Rust microVMM, ~5MB resident, ~125ms boot. The Firecracker process runs inside the jailer: a chroot jail with an empty filesystem, dropped capabilities, a restrictive seccomp filter, and an unprivileged UID. An integration test (tests/integration/test_firecracker.py::test_jailer_active) verifies the jailer is active on every install.kata-qemu-longhornuses QEMU — bigger surface than Firecracker but still hardware-isolated, and Kata applies its own sandboxing primitives.k7duses Katakate’s own KVM VMM (runtimeClassName: k7). CoW sibling-fork isolation differs — see the k7d security model.
Container hardening
Inside the VM, the user container is further locked down:Some package managers (
apk add, apt-get install) require root inside the container. Either run them in before_script with the defaults, or prebuild your image with the dependencies baked in.Network isolation
- Ingress is denied by default — pods cannot talk to each other, even within the same namespace.
kube-systemtraffic is allowed for cluster services.kubectl exec/k7 shellare unaffected (they use the K8s API). - Egress is configurable per sandbox via
egress_whitelist: open by default, blocked with[], restricted by CIDRs, or restricted by FQDNs (with Cilium). DNS is blocked by default when egress is locked down — see the Networking page.
API authentication
- API keys are generated with
secrets.token_urlsafe(32)and only shown once at creation. - Stored in
/etc/k7/api_keys.json(mode 0600) as SHA-256 hashes — the plaintext key is never written to disk. - Comparison uses
secrets.compare_digest(constant-time, timing-attack resistant). - Optional expiry; expired keys are purged opportunistically on every authenticated request.
- Optional namespace scope:
k7 generate-api-key NAME -n <ns>(repeatable). Enforced on every namespace-bearing endpoint — a scoped key cannot touch another namespace or run all-namespaces operations (403 Forbidden). Keys without a scope stay unrestricted (backward compatible). last_usedtimestamp recorded for audit.- Authenticate via
X-API-Key: <key>orAuthorization: Bearer <key>. - Registry SSRF guard (0.2.1+): control-plane OCI inspection rejects registry hosts that are not on the allowlist (default
registry-1.docker.io,ghcr.io,quay.io,public.ecr.aws; extend withK7_REGISTRY_ALLOWLIST) or that resolve to loopback / private / link-local / reserved addresses. Redirects are disabled; the oldlocalhost→ HTTP downgrade is gone.
k7-api control plane. 0.2.0 and earlier are unsupported.
The API runs as a K3s Deployment with its own ServiceAccount and a scoped ClusterRole — no admin kubeconfig is ever mounted.
Operational guidance
- Always lock down egress for untrusted workloads. Prefer FQDN allowlists (Cilium) — much less error-prone than tracking CIDR ranges that change.
- Don’t whitelist public DNS resolvers (
1.1.1.1,8.8.8.8) — that re-enables DNS exfiltration. - Rotate API keys with
k7 revoke-api-key+k7 generate-api-key. Treat them as credentials. Scope production keys with-nso a leaked key cannot list every namespace. - Set a TLS reverse proxy in front of the NodePort if you expose the API publicly (the NodePort itself is plain HTTP).
- Pin image tags —
:latestis convenient but non-reproducible. K7 itself pins every image and Kubernetes manifest version it ships; do the same in your sandbox configs.
Known limitations
- Pre-1.0 software under active security review. Avoid for hyper-sensitive workloads until 1.0.
- No API rate limiting yet — put a proxy with rate limits in front for public exposure.
- AppArmor profiles are on the roadmap (not yet shipped).
- TEE (Trusted Execution Environment) support is on the roadmap.
