M1 (sessions over SSH, kept apart)
Goal
Alice and Bob log in over SSH, on QEMU, and on the console, into Elixir sessions, and are kept
apart: each session runs in a fixed sub-budget for its principal’s label set, with files (the
system read-only, /home writable). A dead steward restarts without a reboot, and the
scheduler’s targets hold. The attack suite is the kernel cases below and the cases for what this
milestone builds.
The milestone is one thin vertical slice through the whole system: the kernel, init and the
boot manifest, the drivers, the file servers, the steward, keyd and sshd, and beamlet running
the shell in each session. A session in this milestone needs only the console, files and
launching native programs. The rest of the shell is M2 (usable shell);
agents, approvals and the scripted hostile agent and user are
M3 (agents, approvals and the attack suite).
Attack suite
Each attack is a deterministic program in the test bench. Its outcome is judged by a party the attacker cannot impersonate: the kernel, a victim, or a clean power-off, never the attacker’s own output (rule F). A covert channel an attack finds is recorded as an observation against the side-channel wall, not as a breach.
Kernel cases
| Attack | Rules | Bench case |
|---|---|---|
| Revocation by budget: mint into a revocation scope and destroy it; the handles are dead everywhere, messages already sent through them fail and carry no reply’s handles, and handles inside queued messages arrive as 0 | R9 (stamps), R10 (destruction) | redoubt-revoke, budget-destroy-attack |
| Budgets: carving, charging and exhaustion | R6 (charging), R7 (carving) | budget, budget-carve-attack, budget-table-attack, budget-mem-churn, touch-beyond-ram |
| The scheduler: churn, carving, sleeping and ties gain nothing | R12 (scheduling) | sched-budget-churn, sched-carve-inflation, sched-debt-lift, sched-destroy-billing, sched-exit-churn, sched-idle-gap, sched-lift-delay, sched-ties, sched-wake-no-preempt |
| The timer: every blocking call returns by its timeout | I13 (every blocking call returns by its timeout) | timeouts, budget-deadline |
Memory: W^X, zeroed pages, no replacement by map_fixed | R11 (memory) | wx, kernel-wx, mem-attack, write-only-attack, map-fixed-attack |
| Devices: no device authority without a device object; DMA pages reset before reuse | R18 (device authority), I16 (DMA pages reset before reuse) | irq-attack, dma-rules, dma-reset-reuse, dma-reset-quarantine |
| Containment: hostile agents in leases are preempted, then ended at their deadlines or revoked by hand with their messages and lends in flight, while the driver, the steward and a victim server stay responsive | R10, R12, R3 (lends and abandoned calls), I2 (revocation is complete), I10 (create-destroy leaves the parent unchanged) | kernel-containment |
| Boot: a tampered or confused bundle does not run | R15 (verified boot), R16 (image confinement) | verified-boot-rejects-tamper, verified-boot-rejects-bare-archive, loader-rejects-kernel-address, loader-rejects-kernel-entry, loader-rejects-truncated-elf |
The gaps the kernel’s own cases leave (R1 (flow) across label sets on the real kernel, R2 (fair waiting)’s turns between groups, completion races between harts) are listed in kernel attack gaps.
Remaining work
Each part lands with the attack cases for what it builds. The order the parts run in, and which are under way, is kept with the project’s work plan (AGENTS.md), not on this page.
- The client library.
redoubt-client: the namespace, files over 9P, the file server’s typed operations, the console, launching, a launcher’s grants and one typed call, the API every userland binds to, tested on the host against real servers (native programs).initand beamlet’s platform are built on it, and anRerrorkeeps its name by one table (wire); a session binds each typed server through a generated Elixir client (wire). Still planned: dropped files’ fids that come back, calls by path, and whole reads and writes (native programs). - The VM’s remaining platform work. The VM and shell boot on the UART console, and its I/O
is asynchronous through the client library’s hub, files over 9P included
(beamlet,
files), and its system natives (the namespace, typed
calls, serving, budgets, labels and launching) run on the machine in a session a tester starts
in the steward’s place, and budgets and launching in the steward’s own sessions over SSH, a
vault session’s among them (beamlet); Elixir’s
Filein a steward’s session waits for the session’s namespace to reach its VM. - The steward. Principals from the manifest, fixed sub-budgets per label set, and sessions
on the console and over SSH run (the steward,
sub-budgets,
sessions), on the server graph, trust
tiers and capability holdings (the servers). Still to come: a dead
steward restarts without a reboot:
initempties theusersbudget, which ends every session, and relaunches the steward (the steward, init). - Files. The system volume read-only, and
/homewritable, served bywalfsd(walfsd).
Every follow-up page is placed above.
Progress
Built and attack-tested today:
- The kernel, except SUM and MXR clearing: handles and objects, IPC, memory, budgets, scheduling, the timer, processes, devices and DMA, verified boot (the kernel), and the executable model with its mutations (the model).
- The kernel containment gate: hostile leases preempted, ended at their deadlines and revoked by hand with their calls and lends in flight, while the victims stay responsive, on both widths (containment).
- The serving library and the wire formats: admission, the label check, minted connections, parked calls, typed dispatch, the 9P skeleton (serving, wire).
- The drivers and the network:
blkdandnetdattacked by hostile devices in host tests,blkd,netdandipdon the real kernel underinit(blkd, netd, ipd). - The file system’s core: littlefs against a hostile medium and power loss (littlefsd).
- The flash file server:
littlefsdoverblkd, placed byinit, with one volume per instance, quotas and typed operations (littlefsd). - walfs, the format for the SSD’s writable volumes: its library against a model, a power cut
at every write and hostile volumes, the bench’s packer, and its server,
walfsd, serving the image’s data volume underinit, with a power cut on the machine before or after (walfsd). bootfsd,consoledandkeyd, attacked in host tests and booted underinit(bootfsd, consoled, keyd).- Launching: the startup block and the loader stub (init).
initand the boot manifest: the loader loads only the kernel andinit;initchecks the manifest, builds the budget tree, hands each server its devices, and starts every server through the loader stub with fresh connections. It restarts a server that ends, a driver on its reset device, and reboots when one cannot stay up. Every server’s case bootsinit(init, starting a case’s programs).- The client library, with launching exercised by
init-booton the machine and its other tested operations exercised on the host against real servers (native programs). - beamlet on the host and under
initon Redoubt, with console, clock and randomness; its modules come from the userland disk, a volumeveritydchecks block by block against a root the signed manifest pins, those the shell’s prompt loads from one boot pack read whole before the VM starts (beamlet, verityd). Its I/O is asynchronous through the client library’s hub, and its files are 9P files in its namespace (files). - The shell on beamlet on the host: the loop, the commands, the file and text commands and
help, with hostile text drawn visibly and the cell protocol held to its vectors
(the shell,
the cell protocol).
The shell also boots on Redoubt’s UART console, and in a session its
execlaunches a native program from/boot(native programs); its files wait for a session’s namespace (the shell on the machine). - The steward: its policy core, tested on the host, and the server, which carves the
principals from the manifest, logs in
sshd’s users and starts each session as a beamlet VM in its label set’s sub-budget, and the console principal’s on the UART (the steward). A steward that dies is restarted with every session logged out,usersemptied by the kernel’sbudget_reap, and the console session starts again; the machine does not reboot (failure and restart). Each principal’s home holds the manifest’s quota, shared by all its sessions, its console session among them (home quotas and vaults). sshd’s core on its host platform, which the bench’s SSH sessions run against, with OpenSSH’s server as the reference (sshd, SSH sessions), and on the box’s, logins through the steward (sessions over SSH).
Not built: a session’s files, and a steward restart without a reboot.