k7: self-hosted VM sandboxes for untrusted code, and what the three backends actually cost you
Your own self-hosted infra for lightweight VM sandboxes to safely execute untrusted code. CLI, API, Python SDK. ⭐ Star it if you like it! ⭐
At a glance
- What is it?
- Katakate's k7 turns a Kubernetes node into a pool of Kata and Firecracker microVMs with a CLI, an HTTP API and a Python SDK. The interesting part is not the sandbox itself but the choice between three backends whose persistence and latency profiles barely resemble each other.
- Who is it for?
- k7 is for teams that already run Kubernetes on hardware with KVM and need to execute untrusted code without handing the job to a hosted sandbox provider. It is the wrong tool if you cannot get /dev/kvm on your nodes, if your nodes are arm64 and you wanted the k7d backend, or if you need a sandbox that survives the pod that created it.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap k7 fills: untrusted code with a real kernel boundary
Running arbitrary code from a model, a user, or a CI job inside a container shares one kernel with the host. Namespaces and cgroups limit what that code can see and consume, but the syscall surface stays shared, and the README frames the project's motivation around exactly that: AI agents that need to run arbitrary code at scale. k7's answer is to put each execution inside a virtual machine. Kata encapsulates containers into lightweight VMs, Firecracker provides the fast-booting VMM on one path, and Katakate ships its own runtime daemon, k7d, on another.
The audience is narrower than the tagline suggests. You need to own the nodes, because the sandboxes are VMs and VMs need hardware virtualization. The README lists custom serverless, hardened CI/CD runners without Docker-in-Docker, and blockchain execution layers as adjacent uses, but every one of them assumes you are prepared to run Kubernetes and provision bare metal or nested-virtualization-capable instances. If your compute is a managed container service, this is not a drop-in.
Three backends, three different storage and lifetime models
The backend is not an implementation detail you can ignore. `k7 install --backend <kfd|kql|k7d>` provisions one or more per node, and `k7 create --backend ...` selects one per sandbox, so a single cluster can host all three.
kfd pairs Kata with Firecracker and uses a devmapper snapshotter with thin-pool provisioning of logical volumes. That gives efficient disk use across many Firecracker VMs per node, but it needs a spare raw disk, and the README notes the benchmark node did not have one, so its create-to-ready time was not re-measured. It has no cross-pod persistence.
kql pairs Kata with QEMU and backs root disks with Longhorn PVCs. This is the persistent path: replicated disks, named snapshots, restore, disk-only fork, and cross-node mobility. The reported create-to-ready median is 17.1 seconds, snapshot 6.5 seconds, fork 46.7 seconds because it is a disk clone plus a cold boot, and pause/resume 1.3 and 4.1 seconds with the disk surviving.
k7d is Katakate's own microVM runtime daemon, a custom KVM VMM under RuntimeClass `k7`, with erofs images, reflink XFS and guest tmpfs. The README reports 2.1 seconds create-to-ready, roughly 5 millisecond VM-level copy-on-write fork, about 2.4 seconds end-to-end through k7 and Kubernetes to a Ready pod with exec, and pause/resume at 0.2 and 0.3 seconds with the VM frozen in place and memory surviving. It has no cross-pod persistence either; the fork is what carries state forward.
Those numbers come from medians of three runs on a single Hetzner AX41 node, and the README points to PERFORMANCE.md for methodology and ranges. Treat them as one machine's medians, not as a guarantee for your workload.
Getting a sandbox running
The README splits setup into nodes and a client. On the node, the CLI installs from apt: `apt install k7`. The API is deployed automatically by `k7 install` and can be toggled with `k7 api enable` and `k7 api disable`. On the client side, the Python SDK installs with `pip install k7-sdk`; the README states the `katakate` package name is deprecated, so new code should import from the k7-sdk distribution.
Node requirements are explicit. Ubuntu on amd64 or arm64, with hardware virtualization available and accessible. The check given is `ls /dev/kvm`, which should exist. The README is candid that cloud availability varies: Hetzner Robot dedicated instances work, AWS needs `.metal` instances, GCP generally works with `--enable-nested-virtualization`, and Azure lists specific Intel, AMD and ARM families. The k7d backend is amd64 only, matching the `*-x86_64-linux.tar.gz` release tarball, while kfd and kql cover both architectures.
Beyond that, the README references docs/BACKENDS.md for backend architecture, PERFORMANCE.md for measurements, and ROADMAP.md for planned work. Multi-node clusters are described as Ansible plus Longhorn, and Cilium is used as the CNI with FQDN egress policies, which is how you constrain where a sandbox can talk to on the network.
The persistence trade-off is the decision, not the boot time
It is tempting to read the table as k7d wins on speed and move on. The column that matters more is cross-pod persistence. kql is the only backend with it, through Longhorn snapshots and restore, and it pays for that with the slowest create and fork times in the table. kfd and k7d both mark it absent.
That shapes what you can build. A CI runner that needs a warm dependency cache across jobs wants kql, or wants to rebuild the cache every time. An agent loop that spawns a sandbox per tool call and discards it wants k7d, where the fork clones disk and memory and the state travels with the clone rather than through a volume. Choosing k7d and then discovering you needed the sandbox to outlive its pod means re-provisioning with `k7 install --backend kql` and accepting a create-to-ready figure an order of magnitude larger.
The docker sidecar is available on all three, which matters if the untrusted code is itself a container build. The README describes the difference in docker data lifetime: ephemeral on kfd, persistent on kql, and VM-lifetime on k7d. It also notes kql has the fastest `docker pull` in the reported measurements.
Beta status, security review, and the k7d architecture constraint
The README carries a note that Katakate is in beta and under security review, with the instruction to use caution for highly sensitive workloads. That sentence sits directly under a project whose entire purpose is isolating untrusted code, and it should be read literally. A sandbox product that has not finished its own security review is not the layer you want holding your most sensitive tenancy, even if the isolation primitives underneath it are well established.
The second constraint is architectural. k7d is amd64 only. If your fleet is arm64, that backend is unavailable to you, and the reported warm fork and pause/resume behaviour goes with it. You would be choosing between kfd, which needs a spare raw disk per node, and kql, which needs Longhorn and gives you the 17.1 second create path.
There is also a maintenance surface worth counting before you commit. A working deployment involves Kubernetes, K3s in the README's framing, Kata, Firecracker with the jailer, devmapper and thin-pool configuration, Longhorn, Cilium, and the k7 CLI and API on top. Each of those has its own upgrade cadence and its own failure modes. k7 does not remove that stack; it configures and drives it.
Where k7 sits next to gVisor and hosted sandbox APIs
The nearest comparison in kind is gVisor, which intercepts syscalls in userspace and presents a reimplemented kernel to the workload. That runs on ordinary Linux hosts without KVM, so it works on cloud instances where nested virtualization is unavailable, and it starts faster than a VM because there is no guest kernel boot. The trade-off is that the syscall surface is a reimplementation, and applications that depend on uncommon syscalls or on specific kernel behaviour can hit gaps.
k7 goes the other direction and uses real virtualization, so the guest gets an actual kernel and the isolation boundary is the hypervisor. The cost is the hardware requirement the README spells out: `/dev/kvm` must exist, which rules out most shared-cloud instance types, and the sandbox lifecycle now includes VM boot unless you are on the k7d fork path.
Against hosted sandbox APIs, the difference is operational rather than technical. You own the nodes, the network policy through Cilium, and the data path. Nothing about your untrusted code leaves your infrastructure. In exchange you own capacity planning, the Longhorn volumes, and the upgrade of every component in that list.
Licence and what the release history implies for upgrades
k7 is Apache-2.0, which permits commercial use, modification and redistribution provided you keep the licence and notice files and state significant changes. It also includes an explicit patent grant. That is a permissive choice with no copyleft obligation on your own code, and for a component you are deploying inside your own infrastructure the practical effect is that you can fork it if the project stalls. This is a description of the licence text, not legal advice; if you are redistributing a modified k7 or bundling it into a product, have counsel read the NOTICE and attribution requirements.
The release history shows three releases in August 2026, with v0.2.1 labelled a security release and v0.2.2 following three days later. A security release arriving between two feature releases, in a project that states it is still under security review, tells you the API and the runtime are both still moving. Pin the version you deploy, read the release notes for each bump, and expect that a patch-level change may alter behaviour in the API surface or the node-side install.
Editorial conclusion
k7 is for teams that already run Kubernetes on hardware with KVM and need to execute untrusted code without handing the job to a hosted sandbox provider. It is the wrong tool if you cannot get /dev/kvm on your nodes, if your nodes are arm64 and you wanted the k7d backend, or if you need a sandbox that survives the pod that created it. Before adopting, verify three things in your own cluster: that ls /dev/kvm succeeds on every node you intend to schedule onto, which backend you are provisioning with k7 install --backend, and whether the persistence model of that backend matches your workload, since kql keeps disk state through snapshots and restore while kfd and k7d do not.
Community notes