▲ Delonix Docs
v0.1.0

Arquitectura

Um comando, crates em cinco camadas (ADR-0040) — e nenhum processo residente.

Visão geral

O directório de cada crate é a sua camada, e o scripts/arch_fitness.py falha quando os dois discordam ou quando uma dependência vai contra a direcção das camadas (uma camada só depende das de baixo; um binário compõe UMA interface).

binários — delonix-runtime-bin · delonix-mcp-bin · delonix-mgmt-bin · delonix-node-api-bin a CLI delonix é a única porta: container · image · build · vm · volume · network · stack · cluster · …; delonix mcp/serve api/serve node-api/serve cri executam os binários irmãos
delonix-criservidor CRI runtime.v1 — o kubelet fala com o Delonix
delonix-mgmtAPI de gestão LOCAL (HTTP+JSON num socket unix), métricas Prometheus
delonix-node-apicontrato de nó delonix.node.v1 (gRPC + HTTP/JSON dos mesmos .proto num socket unix) — NodeService + openapi.json
delonix-mcpservidor Model Context Protocol, local e sem inquilino
delonix-provider-cloud-hypervisor · -libvirtbackends VmBackend locais (microVM por processo · libvirt/KVM, ADR-0044) — saíram do delonix-vm, que os regista
delonix-proxmoxVmBackend REMOTO e SDN contra a API de um nó Proxmox VE (ADR-0008)
delonix-truenasdataset, quota e partilha numa appliance TrueNAS (ADR-0009)
delonix-opnsenseGatewayProvider contra a API REST do OPNsense (ADR-0051)
delonix-powerdnscliente da API de um servidor PowerDNS (ADR-0064) — limpa os registos de gateway do nó
delonix-provider-btrfs · -zfs · -lvmdrivers de pool de armazenamento (subvolume btrfs · dataset zfs · LV thin lvm, ADR-0067)
delonix-provider-cephCeph nativo pela porta de storage: RADOS · RBD · CephFS · RGW S3 (ADR-0081)
delonix-storage-helperhelper PRIVILEGIADO dos pools — um processo por ligação, SO_PEERCRED + allowUsers (ADR-0067)
delonix-linuxclone() + namespaces, pivot_root, seccomp/caps, cgroups v2 delegados, exec, reconcile
delonix-sdnSDN rootless: holder netns + bridge + slirp único, DNAT/firewall nft, DNS interno, overlay WireGuard
delonix-ocipull OCI (digest verificado), build, export, buildpacks CNB, assinaturas
delonix-vmraiz de composição das microVMs: semeia o registo de VmBackend e monta o VmEngine; cloud-init
delonix-volumevolumes nomeados, bind mounts, quotas, nfs/cifs/webdav
delonix-stateStore/JsonStore com flock, escrita atómica, cofre de segredos cifrado
delonix-scannerSBOM + CVE
delonix-telemetrylogging estruturado, spans OpenTelemetry, registo Prometheus
delonix-computecontexto: a especificação única de execução, registos Container/Vm
delonix-stackcontexto: tabela de Kinds, reconciliador de 3 vias, revisões
delonix-networkingcontexto: portas de rede por papel (GatewayProvider, NetworkZoneProvider), registos e posse (ADR-0059)
delonix-storagecontexto: porta de driver de pool, registo, allowlist do administrador e posse (ADR-0067)
delonix-nodecontexto: eventos, verificações do host, contrato de dispatch
delonix-security-runtimecontexto: política e o único ponto de admissão
delonix-modelfundação pura: erro partilhado e códigos DX, Status, regras de firewall, modelo do segredo
delonix-net-rulesfundação pura, sem dependências: CIDR, nomes de bridge, IPAM

De cima para baixo: binários e interfaces · providers · adaptadores · contextos · fundação — os 35 crates em cinco camadas (ADR-0040). O detalhe completo, com as dependências reais, está no modelo C4.

Providers

O engine fala com o mundo por portas (traits): o mesmo VmBackend, GatewayProvider, porta de storage, NetworkZoneProvider e DNS servem tanto drivers locais (no host) como sistemas externos — appliances e APIs remotas (Proxmox, TrueNAS, OPNsense, PowerDNS).

Portas do engine (traits) Provider local (no host) Sistema externo (appliance/API)
Engine — portas (traits) VmBackend · Gateway · Storage · NetworkZone · Dns Local Sistema externo cloud-hypervisor (microVM) libvirt / KVM btrfs · zfs · lvm (pools) ceph — RADOS·RBD·CephFS·RGW Proxmox VE — VM · SDN · firewall TrueNAS — dataset · quota · share OPNsense — gateway / firewall PowerDNS — registos DNS

Daemonless a sério

Não há daemon, nem sequer um monitor por container (o conmon do podman). O run faz clone() directo; em modo detached, um shim de logging efémero fica só a escoar o stdout/stderr para o ficheiro de log (com rotação) e morre com o container. O estado (spec completa de cada container/VM/volume/rede) vive em JSON sob $DELONIX_ROOT — o ps/start/inspect reconstruem tudo daí, e reapers oportunistas limpam órfãos (slirp sem alvo, hostfwd sem container) a cada invocação relevante.

Estado em ficheiros Processo (efémero)
$DELONIX_ROOT/*.json estado por recurso · flock · escrita atómica · cofre cifrado comando run · apply · stop ps · start · inspect reconcile · reapers escreve reconstrói o processo morre (crash/reboot) — o estado sobrevive

Execução local de um comando

Um comando é um processo efémero: fala directamente com o kernel (sem daemon, sem monitor por container), escreve o estado em ficheiros e desaparece. A rede rootless é servida por um único par holder-netns + slirp4netns partilhado, com DNAT nft para publicar portas.

Processo Kernel · fronteira de privilégio Estado e rede (ficheiros/namespaces)
delonix <cmd> 1 processo efémero sem daemon kernel namespaces · cgroups v2 pivot_root · seccomp/caps container · VM user ns · rootless clone() directo $DELONIX_ROOT/*.json estado · flock · atómico slirp4netns (1 partilhado) holder-netns · nft DNAT

Rootless-first

Sem root, o isolamento vem de user namespaces com mapeamento de subuid (newuidmap/newgidmap, como o podman) — o uid 0 do container é um uid não-privilegiado do host. O rootfs é um overlayfs nos dois modos: as layers da imagem são partilhadas e cada container tem a sua upper persistente. Em rootless o mount é feito pelo init do container, dentro do seu user namespace, porque um utilizador sem privilégio não pode montar no host (desde a v0.59.0; um container antigo com cópia flat migra no start seguinte). Com --privileged + labels de node Kind, o runtime prepara a delegação de cgroup v2 dedicada que um systemd aninhado (kindest/node) exige.

Host (sem privilégio) Container (fronteira) Exceção privilegiada
Host — utilizador sem privilégio uid 1000 · sem root newuidmap / newgidmap (gama subuid/subgid) Container (rootless) uid 0 → uid não-privilegiado do host namespaces · cgroups v2 seccomp · caps · overlayfs user ns subuid Exceção: delonix-storage-helper — processo PRIVILEGIADO por pool (SO_PEERCRED · allowUsers)

Rede rootless: o ingress

hostportas publicadas (127.0.0.1 por omissão; nomeia o endereço no spec para expor — 0.0.0.0:8080:80)
holder netns (1 por utilizador)bridge delonix0 · slirp4netns único · nft (DNAT «pre», firewall) · DNS interno com os nomes dos containers
containersveth por container, ligados à bridge; IP determinístico por id

Publicar uma porta = um add_hostfwd no api-socket do slirp único + uma regra DNAT na chain de ingress — estado do dataplane, não do container. É por isso que portas (e volumes, via mounts live) se trocam a quente: o processo do container nunca é tocado. Com --net host + -p, o container recebe um netns próprio com um slirp4netns dedicado (modelo podman), que morre com ele.

Segurança

Rootless por omissão; seccomp e drop de capabilities fora de --privileged, com arranque a FALHAR se não ficarem mesmo activos; pull com verificação de digest (incluindo artefactos VM OCI); inputs de manifesto de recursos como Cluster/Vm validados por whitelist antes de chegarem a qualquer shell remoto.

Auditoria de 2026-07-21 — 6 achados de severidade alta, CORRIGIDOS em 2026-07-23 (o COPY do build, por exemplo, era contornável por symlink apesar de uma correcção anterior ter tentado fechá-lo — agora canonicaliza e confirma o confinamento). Não há indícios de RCE pela rede. Uma auditoria adversarial independente (2026-07-26) confirmou 5 das 6 correcções e fechou um TOCTOU residual no kubeconfig, e reviu o núcleo de syscalls (namespaces, seccomp, clone3, higiene de fds, SO_PEERCRED) sem achados altos novos; uma 3.ª auditoria (2026-08-10) varreu as classes de CVE conhecidas do Docker/runc/CRI-O e corrigiu o que encontrou. Isto reduz o risco, não o elimina: num host partilhado, trata imagens e manifestos de terceiros com a mesma cautela que terias com qualquer runtime. Detalhe completo em AUDITORIA-E2E.md — ver também a comparação com Docker/Podman para o estado geral do projecto.

Architecture

One command, crates in five layers (ADR-0040) — and no resident process.

Overview

A crate's directory is its layer, and scripts/arch_fitness.py fails when the two disagree or when a dependency runs against the direction of the layers (a layer depends only on the ones below it; a binary composes ONE interface).

binaries — delonix-runtime-bin · delonix-mcp-bin · delonix-mgmt-bin · delonix-node-api-bin the delonix CLI is the one door: container · image · build · vm · volume · network · stack · cluster · …; delonix mcp/serve api/serve node-api/serve cri run the sibling binaries
delonix-criruntime.v1 CRI server — the kubelet talks to Delonix
delonix-mgmtLOCAL management API (HTTP+JSON over a unix socket), Prometheus metrics
delonix-node-apidelonix.node.v1 node contract (gRPC + HTTP/JSON of the same .proto over a unix socket) — NodeService + openapi.json
delonix-mcpModel Context Protocol server, local and tenancy-free
delonix-provider-cloud-hypervisor · -libvirtlocal VmBackend backends (per-process microVM · libvirt/KVM, ADR-0044) — split out of delonix-vm, which registers them
delonix-proxmoxREMOTE VmBackend and SDN against one Proxmox VE node's API (ADR-0008)
delonix-truenasdataset, quota and share on a TrueNAS appliance (ADR-0009)
delonix-opnsenseGatewayProvider against OPNsense's REST API (ADR-0051)
delonix-powerdnsclient of one PowerDNS server's API (ADR-0064) — reaps the node's gateway records
delonix-provider-btrfs · -zfs · -lvmstorage pool drivers (btrfs subvolume · zfs dataset · lvm thin LV, ADR-0067)
delonix-provider-cephnative Ceph over the storage port: RADOS · RBD · CephFS · RGW S3 (ADR-0081)
delonix-storage-helperthe PRIVILEGED pool helper — one process per connection, SO_PEERCRED + allowUsers (ADR-0067)
delonix-linuxclone() + namespaces, pivot_root, seccomp/caps, delegated cgroups v2, exec, reconcile
delonix-sdnrootless SDN: holder netns + bridge + single slirp, nft DNAT/firewall, internal DNS, WireGuard overlay
delonix-ociOCI pull (digest verified), build, export, CNB buildpacks, signatures
delonix-vmmicroVM composition root: seeds the VmBackend registry and assembles the VmEngine; cloud-init
delonix-volumenamed volumes, bind mounts, quotas, nfs/cifs/webdav
delonix-stateStore/JsonStore behind flock, atomic writes, encrypted secret vault
delonix-scannerSBOM + CVE
delonix-telemetrystructured logging, OpenTelemetry spans, Prometheus registry
delonix-computecontext: the one run specification, Container/Vm records
delonix-stackcontext: the Kind table, three-way reconciler, revisions
delonix-networkingcontext: network ports by role (GatewayProvider, NetworkZoneProvider), records and ownership (ADR-0059)
delonix-storagecontext: the pool-driver port, the registry, the admin allowlist and ownership (ADR-0067)
delonix-nodecontext: events, host checks, the dispatch contract
delonix-security-runtimecontext: policy and the single admission point
delonix-modelpure foundation: shared error and DX codes, Status, firewall rules, secret model
delonix-net-rulespure foundation, zero dependencies: CIDRs, bridge names, IPAM

Top to bottom: binaries and interfaces · providers · adapters · contexts · foundation — the 35 crates in five layers (ADR-0040). The full detail, with the real dependencies, is in the C4 model.

Providers

The engine talks to the world through ports (traits): the same VmBackend, GatewayProvider, storage port, NetworkZoneProvider and DNS serve both local drivers (on the host) and external systems — appliances and remote APIs (Proxmox, TrueNAS, OPNsense, PowerDNS).

Engine ports (traits) Local provider (on host) External system (appliance/API)
Engine — ports (traits) VmBackend · Gateway · Storage · NetworkZone · Dns Local External system cloud-hypervisor (microVM) libvirt / KVM btrfs · zfs · lvm (pools) ceph — RADOS·RBD·CephFS·RGW Proxmox VE — VM · SDN · firewall TrueNAS — dataset · quota · share OPNsense — gateway / firewall PowerDNS — DNS records

Genuinely daemonless

There's no daemon, not even a per-container monitor (podman's conmon). run does a direct clone(); in detached mode, an ephemeral logging shim just drains stdout/stderr to the log file (with rotation) and dies with the container. State (the full spec of every container/VM/volume/network) lives as JSON under $DELONIX_ROOT — ps/start/inspect rebuild everything from there, and opportunistic reapers clean up orphans (slirp with no target, hostfwd with no container) on every relevant invocation.

State in files Process (ephemeral)
$DELONIX_ROOT/*.json state per resource · flock · atomic write · encrypted vault command run · apply · stop ps · start · inspect reconcile · reapers writes rebuilds the process dies (crash/reboot) — the state survives

Running a command locally

A command is an ephemeral process: it talks to the kernel directly (no daemon, no per-container monitor), writes its state to files, and exits. Rootless networking is served by a single shared holder-netns + slirp4netns pair, with nft DNAT to publish ports.

Process Kernel · privilege boundary State & network (files/namespaces)
delonix <cmd> 1 ephemeral process no daemon kernel namespaces · cgroups v2 pivot_root · seccomp/caps container · VM user ns · rootless direct clone() $DELONIX_ROOT/*.json state · flock · atomic slirp4netns (1 shared) holder-netns · nft DNAT

Rootless-first

Without root, isolation comes from user namespaces with subuid mapping (newuidmap/newgidmap, like podman) — the container's uid 0 is an unprivileged host uid. The rootfs is an overlayfs in both modes: the image layers are shared and each container keeps its own persistent upper layer. In rootless mode the mount is done by the container's init, inside its user namespace, because an unprivileged user cannot mount on the host (since v0.59.0; an older container with a flat copy migrates on its next start). With --privileged plus Kind node labels, the runtime sets up the dedicated cgroup v2 delegation a nested systemd (kindest/node) needs.

Host (unprivileged) Container (boundary) Privileged exception
Host — unprivileged user uid 1000 · no root newuidmap / newgidmap (subuid/subgid range) Container (rootless) uid 0 → unprivileged host uid namespaces · cgroups v2 seccomp · caps · overlayfs user ns subuid Exception: delonix-storage-helper — PRIVILEGED process per pool (SO_PEERCRED · allowUsers)

Rootless networking: the ingress

hostpublished ports (127.0.0.1 by default; name the address in the spec to expose — 0.0.0.0:8080:80)
holder netns (1 per user)delonix0 bridge · single slirp4netns · nft (DNAT "pre", firewall) · internal DNS with container names
containersone veth per container, attached to the bridge; deterministic IP per id

Publishing a port = one add_hostfwd on the single slirp's api-socket plus one DNAT rule in the ingress chain — dataplane state, not container state. That's why ports (and volumes, via live mounts) swap on the fly: the container process is never touched. With --net host + -p, the container gets its own netns with a dedicated slirp4netns (the podman model), which dies with it.

Security

Rootless by default; seccomp and capability drop outside --privileged, with startup FAILING if they don't actually come up; pull with digest verification (including OCI VM artifacts); manifest inputs for resources like Cluster/Vm validated by whitelist before reaching any remote shell.

2026-07-21 audit — 6 high-severity findings, FIXED by 2026-07-23 (the build's COPY, for instance, was bypassable via symlink despite an earlier fix having tried to close it — it now canonicalizes and confirms confinement). There's no sign of remote code execution. An independent adversarial audit (2026-07-26) confirmed 5 of the 6 fixes, closed a residual TOCTOU on the kubeconfig, and reviewed the syscall core (namespaces, seccomp, clone3, fd hygiene, SO_PEERCRED) with no new high findings; a third audit (2026-08-10) swept the known Docker/runc/CRI-O CVE classes and fixed what it found. That lowers the risk, it does not remove it: on a shared host, treat third-party images and manifests with the same care you would with any runtime. Full detail in AUDITORIA-E2E.md — see also the comparison with Docker/Podman for the project's overall status.

Delonix Engine · Apache-2.0 · ngolacloud/delonix · Referência gerada do --help real do binário por docs/gen.py.Delonix Engine · Apache-2.0 · ngolacloud/delonix · Reference generated from the real --help of the binary by docs/gen.py.