Releases: false-systems/syva
Release list
v0.4.0 — the first complete release
Syvä's first complete release. Node-local Linux/eBPF enforcement: each workload runs in a zone, and kernel BPF-LSM hooks deny cross-zone operations on the syscall path — returning EPERM before the operation completes. No sidecar, no proxy, no control plane.
Every capability below is proven by reproducible privileged kernel gates (make verify-*) — it blocks what it should and doesn't over-block what it shouldn't. Full evidence: docs/release/v0.4.0-runtime-verification.md.
Install
kubectl apply -f deploy/k8s/ghcr.io/false-systems/syva-core:0.4.0
ghcr.io/false-systems/syva-adapter-k8s:0.4.0
Multi-arch (linux/amd64 + linux/arm64).
Highlights
- Nine kernel-enforced BPF-LSM hooks — file open, exec, executable
mmap,ptrace, signals, Unix-socket connect, and the network lock (outboundconnect/sendmsg+bind). - Layered network policy — per-zone lock/open, egress CIDR allowlists with optional ports (IPv4 + IPv6), and pod-IP → zone mappings so cross-zone TCP follows the same
AllowCommrule as everything else. - Composite
(dev, ino)file identity — cross-filesystem inode collisions no longer cause zone confusion (correct even on btrfs, via an in-kernel probe). - Deny events that explain themselves — every denial carries zone names, process
comm, the registered path or destinationip:port, and a templated reason; streamed live, logged structured, counted per-zone. - One-apply Kubernetes install — CRD + RBAC + DaemonSet, proven on a live k3s cluster including a real-container denial through the deployed DaemonSet.
- Proven both ways —
verify-allowasserts the must-not-block contract, so "green" can never mean "blocks everything."
Architecture
Small, frozen kernel mechanism; open, hot-swappable policy over one gRPC API — the boundary a control plane plugs into. See docs/design/predicate-shapes.md.
Requirements
Linux ≥ 5.10 with BPF-LSM enabled (bpf in /sys/kernel/security/lsm), cgroup v2, kernel BTF, and root for load/attach.
Full notes: CHANGELOG.md. Dual-licensed MIT OR Apache-2.0.
Syvä v0.3.0 — Kubernetes membership watcher
Highlights
Syvä's Kubernetes path is now wired end to end. syva-k8s watches pods on its node, resolves real runtime container IDs to host cgroup-v2 inodes, and drives AttachContainer/DetachContainer against the local core — proven by a new privileged enforcement gate.
- Annotation membership watcher (#66): pods annotated
syva.false.systems/zone: <zone>on the local node are attached after the adapter resolves the container's real host cgroup id from host/proc+/sys/fs/cgroup; deletion, node move, non-running state, or annotation change/removal detaches. - Reconciler, not event handler: attaches are not trusted until the core confirms them (unconfirmed attaches roll back and retry); unconfirmed detaches retry every event batch until acknowledged; generations are clock-seeded so core-side stale fencing survives adapter restarts; membership-watcher death kills the adapter so the DaemonSet restarts it.
- Node-scoped watch:
spec.nodeNamefield selector; the resolver rejects container IDs under 12 chars, refuses mountinfo-only PID matches, and truncates resolved cgroup paths to the container scope so nested sub-cgroups attach correctly. - Adapter observability:
syva-k8sserves Prometheus metrics on:9092—syva_k8s_membership_attach_total{result},syva_k8s_membership_detach_total{result},syva_k8s_memberships_active,syva_k8s_reconcile_errors_total{reason}. - New privileged gate:
sudo -E make verify-k8s-membershipproves the annotated-pod attach and the kernel denial end to end; it resolvesKUBECONFIGexplicitly, fails red (never skips), and dumps adapter/core logs on failure.
Installation
Multi-arch container images (linux/amd64, linux/arm64) are published to GHCR by the release-images workflow:
ghcr.io/false-systems/syva-core:0.3.0
ghcr.io/false-systems/syva-adapter-k8s:0.3.0
The syva-core image bundles syvactl and the release eBPF object at /usr/lib/syva/syva-ebpf; the adapter image carries syva-k8s. Deploy with:
kubectl apply -f deploy/v0.2/daemonset-k8s.yaml # from mainUse the manifest from main rather than the tag checkout: the packaging (Dockerfile, publish workflows) and a DaemonSet arg fix (--core-socket → --socket-path on the syva-core container) landed just after this tag was cut. The images themselves are built from main with version metadata aligned to 0.3.0; the enforcement code is identical to the tagged commit.
Node prerequisites (hard requirements, the DaemonSet does not relax them):
- BPF LSM active:
cat /sys/kernel/security/lsmmust includebpf(usually means addinglsm=lockdown,capability,landlock,yama,apparmor,bpfto the kernel cmdline and rebooting) - cgroup v2 and BTF at
/sys/kernel/btf/vmlinux - a containerd-style runtime whose host cgroup paths embed the container ID (k3s/containerd is the proven path)
To build images yourself instead, use the repo Dockerfile (two-step build against the published ghcr.io/false-systems/syva-builder toolchain image, overridable with --build-arg BUILDER_IMAGE=):
docker build --target syva-core -t syva-core:0.3.0 .
docker build --target syva-adapter-k8s -t syva-adapter-k8s:0.3.0 .Runtime Verification Evidence
All four privileged gates pass on cf9f863:
- Host:
Linux lima-syva-dev 6.8.0-124-generic(aarch64), LSM:lockdown,capability,landlock,yama,apparmor,bpf - Kubernetes: k3s
v1.35.5+k3s1, runtimecontainerd://2.2.3-k3s1; container gate viapodman
| Gate | Result |
|---|---|
verify-runtime |
PASS — 6/6 LSM hooks attached; cgroup, inode, and Unix self-tests passed |
verify-integration |
PASS — process file_open denied with EPERM, deny_delta=1 |
verify-container-integration |
PASS — container file_open denied with EPERM, deny_delta=1 |
verify-k8s-membership |
PASS — annotated pod attached and denied with EPERM, deny_delta=1 |
Kubernetes membership proof (gate run on this tag):
namespace: syva-k8s-it-33267 pod: syva-k8s-it-pod-33267 node: lima-syva-dev
container_id: 17b80e6e6dca049ea667b29c52e06171d2e89118fc51f225113bf8818f65981f
cgroup: .../cri-containerd-17b80e6e...f65981f.scope cgroup_id=17091
AttachContainer result: applied (containers_active=1)
zone-a read: exit=0 -> ALLOWED, content present
zone-b read: exit=1 stderr='cat: can't open '/work/zone-b/secret.txt': Operation not permitted'
file_open deny: before=0 after=1 deny_delta=1 (k8s-pod workload attributable)
DetachContainer result: applied
Known Gaps (unchanged, explicit)
- Kubernetes assignment is annotation-only; selector assignment, namespace defaults, leader election, finalizers, and CRD status are out of scope.
- Cgroup movement / zone escape protection is not enforced (
cgroup_attach_taskis not a BPF-LSM hook on supported kernels). - Only
file_openhas end-to-end process, container, and Kubernetes pod denial evidence. INODE_ZONE_MAPis keyed by inode only, not(dev, ino);/procand/syscoverage is incomplete.- Structured stale/conflict reasons on attach/detach responses are tracked in #67.
🤖 Generated with Claude Code
Syvä v0.2.0
Syvä v0.2.0
Syvä v0.2.0 is a node-local Linux/eBPF LSM enforcement engine: syva-core plus adapters that translate zones and policy into kernel-enforced BPF map state. No remote control plane.
Tag evidence: v0.2.0 at merge commit 244c91c.
This release supports six BPF-LSM hooks:
file_openbprm_check_securityptrace_access_checktask_killmmap_fileunix_stream_connect
Runtime verification passed on Ubuntu 6.8 with BPF LSM enabled. The release eBPF object loads, all six hooks attach, and cgroup/inode/unix self-tests pass.
End-to-end file_open enforcement is proven in two ways:
verify-integration: a zoned workload can read its own zone-a file but is blocked from reading a zone-b file.verify-container-integration: a real Podman/BusyBox container attached to zone-a can read its own zone-a file but is blocked from reading a zone-b file.
The blocked read fails with EPERM / “Operation not permitted”, no secret content is read, and file_open deny_delta=1.
Known limitations:
- Cgroup movement / zone-escape protection is not enforced in v0.2.0.
- Kubernetes adapter integration is not yet proven end-to-end.
- Only
file_openis proven end-to-end with process and container workloads in this release. - Runtime enforcement gates require a privileged Linux host with BPF LSM enabled.
- Runtime gates are not yet fully covered by ordinary hosted CI.
- File identity is still inode-based, and
/proc//syscoverage remains incomplete.