The nønos microkernel
  • Rust 73.3%
  • Assembly 17.1%
  • Lean 6%
  • Python 1.6%
  • Shell 0.6%
  • Other 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
eKisNonos 4c79c48cbe seal: the host proof crates are not capsule sources
A change under userland/*_proofs made the seal treat the capsules as
changed and re-prove all of them, which ran the boot smoke past its
two hours. Those crates read capsule code and no capsule reads them;
the trailer check still catches any capsule whose bytes did change.
2026-10-10 18:56:31 +01:00
.cargo build: make the capsules, tools and kernel the same bytes on any host 2026-10-09 17:09:45 +01:00
.devcontainer add the dev container 2026-10-06 15:41:27 +01:00
.github ci: the USB boot finds the storage driver by any record it leaves 2026-10-10 14:16:05 +01:00
.keys update the public publisher keys 2026-10-06 16:35:41 +01:00
abi docs(abi): write the driver-broker ABI reference from the handlers 2026-10-08 14:35:10 +01:00
assets rewrite the readme for 0.9.2 and add the brand banner 2026-10-06 15:34:53 +01:00
audit update the audit material 2026-10-06 16:35:41 +01:00
benchmarks ci: publish benchmark artifacts (#250) 2026-06-29 17:11:15 +02:00
ci-reports settle the last of the release tree 2026-10-06 20:50:16 +01:00
docs docs: point README at the real docs tree, add the internals source map 2026-10-09 07:40:02 +01:00
mk run: the firmware variables copy is writable 2026-10-10 11:08:08 +01:00
nonos-attest-path add the attestation path crate 2026-10-06 16:30:47 +01:00
nonos-bench bench: one reduction for the kernel harness and the terminal command 2026-09-08 20:43:00 +02:00
nonos-boot-measure deny: allow the project's own AGPL-3.0-or-later, and give the STARKs dependency a version 2026-10-06 20:17:00 +00:00
nonos-bootloader nix: make Rust, python-zip and bootloader builds host- and path-independent (Cluster D) 2026-10-08 16:43:56 +01:00
nonos-ci seal: keep what the operator signed when there is no operator key 2026-10-10 00:47:01 +01:00
nonos-data trust: seal standard 2026-10-10 13:28:14 +01:00
nonos-device-attest add the device attestation crate 2026-10-06 16:30:47 +01:00
nonos-mk ci: the production lane checks the committed trust set against the flake's capsules, the bytes the seal signed 2026-10-07 09:22:46 +01:00
nonos-shield-prove add the shield prove crate 2026-10-06 16:30:47 +01:00
nonos-sign fold the signing crate into the tree 2026-10-06 16:30:47 +01:00
nonos-stark-enroll update the STARK enrollment tool 2026-10-06 16:30:47 +01:00
nonos-utils fold the shared utilities crate into the tree 2026-10-06 16:30:47 +01:00
nonos-verify release: the lane reads the tree's roots and writes release/, where the workflow takes them 2026-10-10 12:27:09 +01:00
receipts trust: standard seal 2026-10-07 08:27:31 +01:00
screenshots desktop: reliable full-size display and boot screenshots 2026-07-27 22:26:32 +02:00
scripts Revert "Merge pull request #616 from NON-OS/fix/609-one-idt" 2026-10-10 13:15:55 +01:00
security update the kernel-adjacent security policy 2026-10-06 16:35:41 +01:00
src Revert "Merge pull request #616 from NON-OS/fix/609-one-idt" 2026-10-10 13:15:55 +01:00
stark-attest settle the remaining STARK engine files 2026-10-06 16:30:48 +01:00
third_party feat(audio-player): vendor minimp3 + freestanding cc build 2026-07-25 20:11:44 +06:00
toolchain update the toolchain configuration for the release 2026-10-06 15:36:38 +01:00
tools seal: the host proof crates are not capsule sources 2026-10-10 18:56:31 +01:00
userland e1000e proofs: the modelled PHY wakes on the whole LANPHYPC toggle 2026-10-10 16:33:52 +01:00
verification evidence: hash with sha256sum when present so the macOS sandbox is not empty 2026-10-08 19:24:26 +01:00
wallpapers fold the wallpaper catalogue into the tree 2026-10-06 20:50:15 +01:00
.editorconfig v0.1.0: Advanced kernel with ZK-SNARKs, onion routing, and capability security 2025-09-19 08:20:28 -04:00
.gitattributes gitattributes: force GAS highlighting for .S/.s/.inc 2026-05-13 16:54:12 +02:00
.gitignore update the ignore rules for the 0.9.2 tree 2026-10-06 15:33:58 +01:00
aarch64-nonos.json build: add an aarch64 target and let the hand written asm assemble 2026-07-30 23:39:43 +02:00
build.rs record the 0.9.2 build metadata into the kernel image 2026-10-06 15:34:53 +01:00
build_info.rs record the 0.9.2 build metadata into the kernel image 2026-10-06 15:34:53 +01:00
Cargo.lock refresh the lockfile for the 0.9.2 dependency set 2026-10-06 15:33:57 +01:00
Cargo.toml build: fat LTO for release, ThinLTO's promoted symbol names differed between hosts 2026-10-09 18:00:27 +01:00
CHANGELOG-0.9.2.md add the 0.9.2 changelog 2026-10-06 15:33:58 +01:00
clippy.toml v0.1.0: Advanced kernel with ZK-SNARKs, onion routing, and capability security 2025-09-19 08:20:28 -04:00
CODE_OF_CONDUCT.md docs: add the community files that were missing 2026-07-29 11:56:03 +02:00
CONTRIBUTING.md update the contributing guide 2026-10-06 16:35:42 +01:00
deny.toml deny: allow the project's own AGPL-3.0-or-later, and give the STARKs dependency a version 2026-10-06 20:17:00 +00:00
flake.lock update the nix flake and lock its inputs for 0.9.2 2026-10-06 15:34:53 +01:00
flake.nix update the nix flake and lock its inputs for 0.9.2 2026-10-06 15:34:53 +01:00
LICENSE Add GNU Affero General Public License v3 2025-10-11 05:39:00 -04:00
linker.ld layout: define the section symbols, so the image table exists at all 2026-09-14 16:58:17 +02:00
linker_aarch64.ld update the aarch64 linker script 2026-10-06 15:33:57 +01:00
linker_riscv64.ld kernel: pqclean codegen + linker ltext sections + start.S stack align 2026-05-15 14:03:22 +02:00
Makefile rework the top level makefile for the 0.9.2 build 2026-10-06 15:36:38 +01:00
nonos.toml declare the image profiles in nonos.toml 2026-10-06 15:33:58 +01:00
README.md docs: point README at the real docs tree, add the internals source map 2026-10-09 07:40:02 +01:00
rust-toolchain.toml Update Rust toolchain to nightly-2026-01-16 2026-02-21 12:01:19 +01:00
rustfmt.toml Fix CI workflow 2026-03-05 16:03:37 +01:00
SECURITY.md docs: move the root guides into the wiki 2026-07-18 20:22:43 +02:00
VERSION release: 0.9.2, with every submodule at its documented head 2026-09-03 14:44:24 +02:00
x86_64-nonos.json update the x86_64 bare metal target specification 2026-10-06 15:33:57 +01:00

NØNOS · Privacy. Proofs. Software.

NØNOS

An operating system you can use every day that keeps nothing. It boots a measured image into RAM, runs every program as a signed capsule with only the capabilities it was enrolled for, sends traffic through the network the person chose, and wipes memory on the way down.

0.9.2 is the release that makes NONOS a daily driver. The desktop, the browser, the terminal, the wallet, a Linux userland, a private local model, first-boot setup and the installer are all in one image, and every one of them runs above a microkernel that checks a capability on every call. CHANGELOG-0.9.2.md lists every change with the proof behind it.

Every claim on this page is tied to code or to evidence in the tree. What 0.9.2 has shown on a booted machine and what it has shown only on the host is set out under Where 0.9.2 stands.

What you get

Desktop a compositor, a window manager and a desktop shell with a dock; windows size themselves from small laptop panels to 4K
Browser its own HTML parser, CSS layout, a QuickJS engine and TLS with the Mozilla roots; pages load over Nym, Anyone or direct
Terminal tabs, pipelines and jobs, built-in commands, git over HTTPS, and the bundled Linux tools
Linux programs a Linux personality that traps and translates Linux system calls, with a built-in BusyBox and CPython 3.12, Lua, zstd and John the Ripper in the store
Wallet BIP39 and HD keys held by the keyring capsule, sealed to the TPM, signing in ring 3
Qwen, local a private Qwen model installed from the store, fetched over the chosen network, checked against its published hashes and kept on the encrypted data volume
Apps files, text editor, image viewer, audio and video players, settings, process manager, clock, calculator, the market and app store
Network Nym mixnet by default, the Anyone onion network, or direct; chosen in setup and changed in Settings
Install amnesic by default; first-boot setup and an installer that writes NONOS to a disk only when the person types the disk's word
Proofs screen About shows every admitted capsule with its measurement and enroller, and how traffic is leaving right now

The handbook page for each is in the handbook. The person at the keyboard should read Using NONOS 0.9.2.

The kernel

The kernel is a capability microkernel in Rust: 282,997 lines under src/. It does what only ring 0 can do: page tables and address spaces, the scheduler, IPC between capsules, the syscall boundary with its capability check, the attestation gate at spawn, the TPM, and a hardware broker that hands device windows to driver capsules. Everything a person would call the operating system runs in ring 3: 235 crates under userland/, drivers included.

flowchart TB
 drv["driver capsules<br/>nvme, ahci, xhci, usb_hid, i2c_hid, e1000, iwlwifi, rtl8821ce, hda, virtio"] --> sc
 net["network capsules<br/>net.core, net.nym, net.anon, net.socks5"] --> sc
 app["desktop and apps<br/>compositor, wm, terminal, browser, wallet, keyring, vfs, installer"] --> sc
 sc["the syscall<br/>127 calls, each checked against the caller's capability word"]
 sc --> k["ring 0<br/>paging, scheduler, IPC, capabilities, attest gate, broker, TPM"]
 k --> hw["CPU, MMU, IOMMU, PCIe devices, TPM"]

A capability is one of 36 bits, defined once in abi/caps.toml. A capsule's word is fixed when it is enrolled, the kernel installs it from the verified manifest at spawn, and every syscall is checked against it. A capsule that was never enrolled for the network holds no socket and cannot send to the network services' inboxes by pid. Driver capsules reach their device only through a broker claim, with DMA confined by the IOMMU where a remapping unit is in service.

Architecture is the place to start reading the kernel. Then capabilities, IPC, memory, the IOMMU and the syscall surface.

Capsules

Everything that runs is a capsule. There are 96, each a directory with a Capsule.mk that names its service and its capability word. A capsule is compiled ahead of time, signed with Ed25519 and ML-DSA-65, enrolled under the STARK policy root and shipped inside the kernel image or the image's store. At spawn the kernel checks the certificate, the manifest and the proof, then installs the capabilities from the manifest.

sequenceDiagram
 participant S as spawn_verified
 participant P as preflight
 participant G as attest_gate
 participant R as attest_registry
 S->>P: the capsule's ELF, certificate and manifest
 P->>P: verify_id_cert, verify_with_publisher
 P->>G: an enrolled capsule
 G->>G: verify the v4 trailer against the policy root
 alt the proof verifies
 G-->>S: measurement and authority
 S->>R: record_attested(pid, measurement, caps)
 else anything else
 G-->>S: AttestationRejected, the capsule never runs
 end

The capabilities installed come from the verified manifest, never from what the spawn site asked for. Every capsule is listed with its service and decoded word in the capsule catalog. Writing one is in adding a capsule.

Privacy

The machine forgets because it has almost nothing to remember with. The kernel's file tree lives in RAM. Every boot is amnesic: nothing reaches a disk unless the person chose to install in first-boot setup, and then only the installer and the system's own store may touch a disk's raw sectors. At shutdown the kernel stops every device, then wipes live device buffers, every process's memory, the kernel stacks, the filesystem caches and the keys. That wipe sits on the one path that powers the machine off, and Lean proves no reachable state reaches off without it.

A program's traffic leaves by the network the person chose:

  • Nym mixnet, the default. Each packet is a Sphinx packet across three mix layers to an exit gateway, with single-use reply blocks for the way back.
  • Anyone, the onion network: three relays, each knowing only its neighbours.
  • Direct, which the sites reached can see.

When the chosen network is down, the browser, the terminal, the wallet and the Linux guests send nothing another way. Network cards transmit from a new locally administered address every boot. The private model runs without the network, and its files come only through the installer's checked fetch.

Some traffic does not follow the choice. The Nym and Anyone capsules fetch their directories and build their paths from boot on every image that carries them, so a machine set to Direct still shows Nym and Anyone traffic on its local network. Programs built on the toolchain's Rust std connect direct. The TPM's counter keeps a count of boots. These and the other gaps are listed on the privacy page.

flowchart LR
 app["a capsule with Network"] --> socks["net.socks5"]
 socks --> nym["net.nym<br/>Sphinx, three mix layers"]
 socks --> anon["net.anon<br/>three relays"]
 app --> direct["net.core<br/>only under Direct"]
 other["a capsule without Network"] -. "refused at the syscall".-> socks

The whole model, with what it does not cover, is in privacy, the amnesic design, storage and the route model.

The STARK gate

A signature says a key holder approved an image, and it keeps that key holder in the trust base for as long as the image exists. Admission asks a narrower question: is this one of the images the policy committed to. So the kernel and every capsule carry a transparent STARK proof over Poseidon, with a Fiat-Shamir transcript, that its measurement is a member of the set under one policy root. It is hash-based, with no trusted setup and no pairing.

flowchart LR
 img["the image about to run"] --> m["blake3 measurement"]
 m --> v["nox_verify"]
 tr["v4 trailer<br/>path and proof"] --> v
 root["the policy root, held by the verifier"] --> v
 v --> run["run"]
 v --> halt["refuse"]

The gates link only the verifier, nox_verify, from the STARKs repository at the commit flake.lock pins. The prover runs on the enrolling host in nonos-stark-enroll, which builds the one policy root over every capsule and checks each proof with the gates' own verifier before writing it. The machine that boots holds no prover. The verifier measures the image in front of it and supplies the root itself, so a trailer lifted from another image fails.

Signatures still answer what signatures answer well. The kernel is signed with Ed25519 and ML-DSA-65 together and measured into the TPM behind an anti-rollback counter: who released this image, and is it older than what this machine already accepted. The details are in the STARK layer, signing, keys and the TPM.

Lean 4 and the proofs

The security-critical surface is machine-checked. Lean 4 carries isolation and non-interference, the capability algebra and its delegation, the spawn path and the capabilities a spawn installs, page-table permissions, the user-copy boundary, the attestation binding, the anti-rollback floor and the ZeroState wipe: 1,511 theorems in verification/lean, with no sorry in any Lean tree. An extraction pipeline turns kernel functions into Lean so theorems speak about the shipped code, not a model of it. Verus takes the properties that live in real bit operations. 106 Kani harnesses sit in the source. 90 proof crates pull the shipped source in through #[path] and run it.

NONOS does not claim functional correctness of the whole kernel. The proved surface is what may run, what it may reach, and what survives a power cut. The proof suites says what each one guarantees and which run in CI. verification/MAP.md ties each property to the source it constrains.

Hardware

Drivers are written to the device class, so a machine that presents the class is served by the same driver: NVMe and AHCI storage, xHCI with USB HID and mass storage, PS/2 and I2C-HID keyboards and touchpads, HDA audio, the UEFI GOP display, e1000, RTL8139, RTL8169 and virtio under QEMU. Wi-Fi joins WPA2 and WPA3 networks on the RTL8821CE and on Intel AX211. A driver whose device is missing leaves at once, and one whose device fails gives up after a few seconds.

Each driver, what it does and what a boot must still confirm on it are in drivers and

Build it

You need Nix with flakes turned on (https://nixos.org/download) and nothing else. On Linux and on a Mac with Apple silicon:

make # the kernel, every capsule, the Linux userland and the loader make check # every proof crate and every static check

On Windows, run the same two commands inside WSL2, or open the repository in its devcontainer (.devcontainer/), which has Nix already.

The toolchain, every crate and every C source are pinned by hash, and the build runs offline in Nix's sandbox. make ends with a receipt: every artifact by sha256, the toolchain and every pinned input, the kernel's own bytes held to the profile's promises, and REPRODUCED when the artifacts are byte for byte the ones in the committed receipts/<profile>.json. Those artifacts are unsigned, and no build ever needs a key. Enrolling and signing take keys only the release holder has:

make seal # enroll, sign and pack: needs the keys make boot # boot the sealed image under QEMU, with a TPM make boot-install # beside a blank disk, to try the installer make usb DISK=/dev/sdX # write it to a stick, after typing the path again

A build is one of six profiles, set in nonos.toml or as PROFILE=airgapped make:

profile for what it adds or takes away
standard a person's own machine every driver, the desktop, first-boot setup and the installer
hardened a machine that may be seized Secure Boot and a TPM required at boot; no capsule writes to a serial console
airgapped keys that must never touch a network hardened, with no network driver, stack or online program compiled in
qemu trying NONOS in a virtual machine the desktop, without the drivers only real hardware has
dev working on NONOS the loader's development policy; never sealed for release
core kernel work the microkernel and its base capsules, no desktop

A release image is built hardened. docs/build is the step by step guide, from installing Nix on each platform to an installed disk. Build and verify is the whole flow, tools/nix/README.md the build in one page, and CONTRIBUTING.md the way in.

Where 0.9.2 stands

Every change in 0.9.2 was built for x86_64-nonos-user, with the kernel compile-checked, and held by the host proof suites. The session that made the release did not boot it. The boot run that shows each gate refusing and admitting, and each driver on real silicon, is the release's last step, listed step by step in Until its logs are committed, read "the kernel checks" on this page as "the kernel is built to check". records each row as its evidence lands, and the known gaps are at the end of the changelog.

Documentation

The handbook how NONOS works, one page per subsystem, every claim tied to a file and line
Building NONOS from a fresh machine to a sealed, booted and installed image, one page per step
Using NONOS 0.9.2 what changed for the person at the keyboard
Building on 0.9.2 the rules for capsule and driver authors
Capabilities in 0.9.2 every bit and every capsule's mask
CHANGELOG-0.9.2.md every change and the proof behind it

Design work happens at discord.gg/nonos.

License

AGPL-3.0-or-later. Redistributable device firmware is not part of the source and carries its own terms.