Introduction
The official InterGenOS documentation
Welcome to the official documentation for InterGenOS. The system is built from source with public recipes, nothing about how it works is hidden, and the user stays in control of their own machine.
This wiki is organized into two tracks:
- End-User Guide — installing with FORGE, the local AI assistant, building from source, GPU compute & AI workloads, the Security Handbook, desktop use, administration, and troubleshooting.
- Developer & Contributor Guide — internals and contribution workflows for packaging, FORGE, the AI assistant, the ROCm-from-source pipeline, security review, and localization.
How this documentation works
- Self-contained. No external CDNs, scripts, or trackers — the same posture as the rest of the system.
- Offline-first. The wiki ships as an installable package you can read without a network connection.
- Cited by the assistant. The local AI assistant answers from this documentation and links you to the exact canonical page it drew from, so you can always verify the source. It verifies a page’s integrity before citing it and refuses to cite on a mismatch.
- Versioned by release once v1.0 ships, so guidance always matches the system in front of you.
This wiki is in active development alongside InterGenOS itself. The structure is in place; pages fill in as v1.0 takes shape.
Start Here
Welcome to the InterGenOS End-User Guide. InterGenOS is a Linux distribution built entirely from source, with one purpose behind every default: giving you a machine you understand, can modify, and can trust. Security is not first. It is only.
This guide is written for two kinds of reader, and you can move between them freely:
- End users who want to set up the desktop, manage software, and use the onboard AI assistant.
- Contributors who want to understand how InterGenOS is built and how to work in the source tree.
This page orients you to those tracks and walks you through the first thing you will see on a new install: the Welcome app.
What ships today
InterGenOS is at version 1.0-dev (build id v1.0-dev1), in active pre-1.0 development.
- Desktop: GNOME 49 on Wayland, with the InterGenOS shell theme.
- Built from source: the whole system is compiled from source across six package tiers (toolchain, core, base, desktop, ai, extra). The total is roughly 857 package templates as of this writing; tier counts drift between builds, so treat any number you see as a snapshot, not a fixed promise.
- Package manager:
pkm— install, remove, search, verify, and query dependencies. - Installer: Forge — partitions the disk, deploys the system image, and sets up a signed boot chain you own.
- Trust chain: a signed Secure Boot chain (firmware enforcement is off by default — enable it with a one-time MOK enrollment), dm-verity integrity over the read-only system image, and UKI (unified kernel image) signing. You can verify these yourself.
- InterGen — your onboard AI assistant: tiered, hardware-detected, offline-first, local, with zero telemetry (Qwen models).
- InterGen Sentinel — a pluggable security scanner. The default is local-only (Local-Rules plus Local-Qwen). Six cloud providers are opt-in: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek. You choose which, if any, reaches across the network.
The desktop ships with GNOME on Wayland today. Switchable desktop environments such as KDE Plasma are planned, not shipped — this guide describes only what is in your hands now.
Guide tracks
| If you want to… | Go to |
|---|---|
| Install InterGenOS on real hardware | The Forge installer guide |
| Set up the desktop and your first-boot choices | This page, then the Desktop guide |
Manage software with pkm | The package manager guide |
| Meet and configure the InterGen assistant | The InterGen guide |
| Understand how InterGenOS is built | The Developer & Contributor guide |
| Get a quick answer | FAQ |
A visual tour of first boot
The first time you log in to a fresh InterGenOS install, the Welcome app opens. It is a short, skippable walk through the choices that make the machine yours: appearance, layout, extensions, shortcuts, services, terminal prompt, and your AI assistant. Nothing here is permanent — every choice can be changed later in Settings, in the Extensions app, in the InterGen app, or by re-running the Welcome app.
Step 1 — Welcome

You are now running a system built from source. The next few steps make it yours. A Skip Setup option is available in the top bar if you would rather configure things later.
Step 2 — Choose your look

Pick a visual style. The native InterGenOS look (ECG blue on deep navy) is selected by default, with alternates such as Orchis Dark, WhiteSur, and Catppuccin Mocha. Each entry lists the icon and cursor themes it applies. You can change this anytime in Settings.
Step 3 — Choose your layout

Choose how the desktop is arranged: a Windows-style bottom taskbar with a start menu and system tray, or the classic GNOME top bar plus dock with the Activities overview. This is also changeable later in Settings.
Step 4 — Extensions

GNOME Shell extensions are pre-installed and ready. Toggle what you want — appearance effects such as Blur my Shell and Burn My Windows, productivity helpers, and more. Everything here is opt-in per toggle.
Step 5 — Keyboard shortcuts

A reference card of the essentials: Activities overview (Super), all applications (Super + A), open terminal (Ctrl + Alt + T), lock screen (Super + L), window tiling, and workspace switching, among others. Worth a glance before you move on.
Step 6 — Enable services

This is the security posture in plain view: these services ship OFF. InterGenOS installs locked down by default. Turn on only what you need — print services (CUPS), local network discovery (mDNS / Avahi, opens udp/5353 on the LAN), and a key-only SSH server (opens tcp/22). You are prompted for your root password when you enable any of them, and each can be turned back off at any time.
Step 7 — Choose your prompt

Pick your terminal prompt style: the stock classic bash prompt (minimal, universal, no per-line processing) or Starship (contextual, showing git branch, language version, exit code, and command duration). Open a new terminal after selecting to see it. You can change this later by re-running the Welcome app or editing ~/.bashrc.
Step 8 — Meet InterGen

InterGen is your onboard AI assistant, built into InterGenOS. It can help you find files, explain system settings, troubleshoot, and remember the preferences you set. InterGen is opt-in — it does not run without your consent. If you choose Set up InterGen now, Forge downloads the local AI model that fits your hardware (about 1.5 GB for the standard CPU tier, up to ~21 GB for the largest GPU tier) and gets it ready. The model runs entirely on your machine; no conversation data leaves the computer, and the model’s license is shown at install. You can also enable it later from the InterGen app in your Applications menu.
For the assistant’s full capabilities, including the permission model and InterGen Sentinel’s pluggable scanners, see the InterGen guide. Cloud review through any of the six opt-in providers is handled through Phone-A-Friend (Frontier/Cloud Escalation), which never reaches the network unless you choose a provider.
Step 9 — You are part of something

InterGenOS is open source and built in the open: read it, build it, make it better. This step links out to the source and releases, the issue tracker (every report makes the system more secure), and the documentation and wiki.
Step 10 — You are all set

Your desktop is configured and ready. Anything you chose here can be changed anytime — re-run the Welcome app, or use Settings, the Extensions app, or the InterGen AI app from your Applications menu. Choose Get Started and the machine is yours.
Where to go next
- New to the desktop? Continue to the Desktop guide.
- Installing on hardware? Start with the Forge installer guide.
- Want software? See the package manager guide.
- Curious how it is all built? The Developer & Contributor guide covers the from-source lifecycle, signing, and the rules that decide what ships.
A machine you understand, can modify, and can trust. That is the whole point.
InterGenOS in One Page
The fast path. Read the 30-second version to know what InterGenOS is; read the 5-minute version to know whether it is for you. Everything else on this site is detail underneath these two.
The 30-second version
InterGenOS is a built-from-source Linux distribution with one organizing principle: security is not first — it is only. Every default is hardened, the entire boot chain is signed and checkable by you, and it ships a local AI assistant that never sends your data anywhere unless you explicitly opt in. The goal is a machine you understand, can modify, and can trust — where you never have to take a security claim on faith, because you can verify it yourself.
The 5-minute version
What it is. A security-only desktop Linux, assembled from source (Linux From Scratch lineage), shipping GNOME 49 on Wayland. It is not a general-purpose distribution with security added on — security is the lens every decision passes through.
The four pillars:
- Security as the only lens. Hardened kernel (integrity lockdown, enforced module signing), a default-deny firewall, mandatory access control, and a signed boot chain. Features that cannot be made safe are not shipped.
- You control the machine. Built from source and fully transparent: nothing about how it works is hidden. The package manager records a hash of every file it installs, so you can re-verify the whole system at any time.
- Verify, don’t trust. Every security claim is something you run a command and confirm — see Verify It Yourself. A claim you cannot check is just marketing.
- AI that stays local. InterGen is an offline-first assistant with zero telemetry. It is useful out of the box; cloud providers are opt-in and explicit, never on by default.
What ships today, honestly. InterGenOS is at the v1.0-dev stage. The wiki is careful to separate enforced today from built and coming — for example, the boot chain is fully signed, Secure Boot has been validated end to end, and native Secure-Boot-from-the-installer arrives with an upcoming build. You will never find a reassuring headline here that the shipped configuration does not back up.
How to try it. The lowest-risk way to look is in a virtual machine — see Installing in a Virtual Machine. When you are ready for hardware, the FORGE installer walks you from the live environment to a verified install, and nothing is written to disk until you confirm.
Where to go from here:
- Why InterGenOS Exists — how it compares to Fedora, Arch, NixOS, Qubes, and others, and when one of those is the better fit.
- What InterGenOS Is — the full picture.
- Threat Model & Security Philosophy — who this is built to defend against, and the doctrine behind it.
- Verify It Yourself — prove the claims on your own machine.
What InterGenOS Is
InterGenOS is a Linux distribution built entirely from source, designed around a single conviction: the person sitting at the machine should be in control of it. Not the vendor, not a telemetry pipeline, not an auto-updater that changes the system while you sleep. Every package is compiled from source with a deliberate choice behind it, and every default is there to give you a machine you understand, can modify, and can trust.
This page explains the model that shapes those choices, the user-control vision behind them, and — just as important — what InterGenOS deliberately leaves out. It is philosophy, not a command reference. For setup and day-to-day use, see the FAQ and the Forge install guide.
The current version is 1.0-dev (build id v1.0-dev1). InterGenOS is in active pre-1.0 development.
Security is not first. It is only.
Most systems treat security as the top item on a list of priorities. InterGenOS does not have that list. Security is not the first concern competing against convenience, speed, or convention. It is the only lens that gets a veto.
We build assuming adversaries have superhuman vulnerability-discovery capability. AI-assisted vulnerability discovery is treated as a foregone conclusion, not a theoretical threat, and that capability will only proliferate. Under that assumption, the things that get a system compromised are rarely dramatic. They are the quiet ones: a masked error, a blanket “ignore failures,” an unverified “known-good” claim, a feature that shipped degraded instead of fixed. Those are exactly what a capable adversary exploits.
So the working question behind every decision is the same: does this eliminate a silent failure and turn an unverified assumption into a checked gate? If an option masks rather than verifies, it is wrong, and no amount of convenience rescues it.
In practice that means the system is hardened from the moment it boots, not by a script you run afterward:
- A signed boot chain. From a Microsoft-signed shim through GRUB to the Linux kernel and Unified Kernel Images. Secure Boot enforcement is optional and off by default on the current fleet; with it enabled, unsigned kernel modules are not trusted.
- dm-verity integrity. A verified-integrity hash tree is generated over the read-only system image, and its root hash is sealed into the signed kernel command line. A tampered system image cannot boot under a validly signed kernel.
- UKI signing on your own machine. The release-signing key never leaves a hardware token under InterGenOS control. The installer generates a Machine Owner Key (MOK) on your machine, and installed systems re-sign each kernel’s UKI with that key at every kernel install or upgrade. The trust anchor is yours.
- A signed package mirror. The package index is the signed manifest of the whole repository; clients verify the entire index against one signature, and every published archive’s hash is checked locally before install.
- Locked by default. A fresh install ships with no remote access enabled and a default-deny firewall. Server packages bind to localhost unless you deliberately open them. There are no default or blank passwords.
A fuller breakdown of the enforced defaults — AppArmor in enforce mode, systemd sandboxing across daemons, and the build-chain supply-chain protections — lives in the hardening baseline.
A machine you understand, can modify, and can trust
The security model and the user-control vision are not two ideas. They are the same idea from two angles: a machine the user cannot trust is a machine they do not control.
Control begins with transparency. InterGenOS is based on Linux From Scratch and Beyond Linux From Scratch, and every component is compiled from source rather than pulled from an opaque binary you cannot inspect. The build is deterministic by construction — pinned, checksum-verified sources and deterministic ordering — so what you run is what the source tree says you run; full byte-identical reproducibility across independent builders is a documented 1.x goal.
That same preference for the transparent path shows up in smaller, visible ways. There is no boot splash hiding the startup. You watch the kernel hand off to systemd and every service report [OK] or [FAILED]; if a mount breaks or a module misbehaves, you see it the moment it happens. Spotting odd boot output is a real practice for catching a compromise or a hardware change, so we give you that surface instead of covering it with a logo.
InterGenOS ships its own tooling to keep the system legible end to end:
pkm— the package manager. Install, remove, search, verify, and inspect dependencies.- Forge — the system installer. It takes you from partitioning through the signed boot chain to a booted desktop. Forge is InterGenOS’s own installer, not a third-party framework bolted on.
- A signed Secure Boot chain, dm-verity integrity, and UKI signing, all described above — verification you can check yourself rather than take on faith.
The rule that gates all of it: bespoke complexity that hides how the system works is not welcome, no matter how conventional it is. When a clever shortcut and the standard, inspectable path disagree, the inspectable path wins.
What ships today
State things by what is real now, not by what is planned. Today, InterGenOS ships:
- A GNOME 49 desktop on Wayland. Dark theme, InterGenOS branding, Wayland-native.
- Six package tiers — toolchain, core, base, desktop, ai, and extra. As of June 2026 that is roughly 857 package templates across the six tiers (toolchain ~28, core ~272, base ~23, desktop ~420, ai 2, extra ~112). These counts drift as packages are added and revised; treat the live tree as the source of truth, not any fixed number.
- A 20-phase from-source build, in fixed order:
validate → verify-sources → setup → toolchain → chroot-prep → chroot-tools → core → config → core-extra → base → kernel → desktop → ai → extra → bootloader → image → manifest → squashfs → ukis-verity → iso, with an optional publish step. The build always runs through the bootloader, ISO, install, and boot chain, because a clean compile is not the same as a known-good system.
InterGen — the local assistant
InterGen is the onboard AI assistant: tiered, hardware-detected, and offline-first. At setup time it detects the CPU, RAM, and GPU and selects a local model (Qwen) and quantization appropriate to the machine, from a 4 GB laptop up to a GPU workstation. No cloud, no accounts, no round-trip latency, and zero telemetry. It is text-only by design.
What separates it from a generic local-LLM wrapper is the permission model. Every tool call is treated as privileged; the default mode asks for confirmation before any action that modifies system state, tool signatures are pinned against drift across upgrades, and a separate audit log records every invocation. The assistant is a system component, not a hole in the system.
InterGen Sentinel — pluggable security scanning
InterGen Sentinel is a pluggable security-scanner architecture. It routes a tool call through a scanner of your choice before it executes. The default is local-only: Local-Rules (rule-based and deterministic) and Local-Qwen (your local Qwen model reviewing the call), both fully offline.
For richer review you can opt in — explicitly, never by default — to one of six cloud providers: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek. This Phone-A-Friend (Frontier/Cloud Escalation) path exists because frontier models routinely surface security-relevant findings at scale, and some users will want that capability through a vendor they trust. The user picks which scanner, if any, reaches across the network. Everything else stays on the box, and the schema-pinning, audit logging, and sandbox enforcement are vendor-neutral local plumbing that apply no matter which scanner is active.
What we deliberately exclude
What a system refuses to do is part of its design. InterGenOS leaves things out on purpose:
- No telemetry, analytics, or crash reporting. Zero. There is nothing to opt out of in a settings menu, because the data never leaves the machine to begin with.
- No auto-updates. The system does not change software behind your back. Updates happen when you explicitly run them.
- No silent failures. Every error surfaces. An unverified assumption is turned into a checked gate or it is not trusted.
- No stubs. Placeholder code that pretends to work does not ship. A stub is a lie.
- No proprietary firmware in the core. The core relies on open drivers and firmware. Proprietary blobs are available if your hardware strictly requires them, but they are never forced on you.
- No fixes that only work on a hand-patched box. A change is done only when it lives in the source tree and a clean build reproduces the corrected behavior with zero manual steps. Live-patching is allowed for diagnosis, never as the finished fix.
What is planned, not shipped
To be precise about the line between today and tomorrow: the following are planned and are not part of the current system.
- Switchable desktop environments. v1 ships GNOME on Wayland only. KDE Plasma (Qt6) and other Wayland-capable desktops are planned after v1; the per-tier architecture already supports the split, but they do not ship today.
- Application campaigns. Additional applications are roadmapped (for example creative and productivity tools), but only what is present in the shipping tiers today is current.
When in doubt, trust the running system and the source tree over any roadmap.
Where to go next
Why InterGenOS Exists
There are a lot of good Linux distributions. This page is the honest answer to a fair question: why build another one?
The short version: InterGenOS occupies a combination that nothing else quite fills — security as the only lens, a machine you genuinely control and can verify, and a capable local AI assistant that never phones home — all on a built-from-source, transparent base. Plenty of systems are excellent on one or two of those axes. InterGenOS is built around all of them at once, and refuses the usual trade-offs between them.
What InterGenOS optimizes for
- Security is not first. It is only. Every package, default, and design decision is a security decision. Features that cannot be made safe are not shipped; convenience never silently wins over safety.
- You control the machine. It is built from source (Linux From Scratch lineage), every claim is checkable (see Verify It Yourself), and nothing about how it works is hidden from you. A machine you understand, can modify, and can trust.
- AI that stays on your machine. InterGen is an offline-first local assistant with zero telemetry — useful out of the box, with optional cloud providers you turn on explicitly, never by default.
- Honesty about what ships today vs. what is planned. The wiki and the system both separate “this is enforced now” from “this is built and coming.” No reassuring headlines that the configuration does not back up.
How it compares
Every system below is a serious, well-engineered project, and for many people one of them is the right answer. The table is about emphasis, not a scoreboard — what each is built to optimize first.
| System | Built to optimize | Where InterGenOS differs |
|---|---|---|
| Fedora | A polished, current, general-purpose desktop; upstream-leading; SELinux on by default | InterGenOS is security-only, not general-purpose; built from source rather than from a corporate binary archive; ships a local AI assistant and a checkable boot chain as first-class. |
| Arch | Maximal user control and a do-it-yourself, rolling system | InterGenOS shares the control-and-transparency ethos but ships an opinionated, secure-by-default posture (signed boot, hardened kernel, default-deny firewall) instead of leaving hardening entirely to you. |
| Debian | Rock-solid stability, software freedom, an enormous package set | InterGenOS trades breadth and conservatism for a tightly curated, security-first set with a hardened default configuration and a per-file-verifiable install. |
| NixOS | Declarative configuration and reproducible builds | InterGenOS shares the reproducibility and verify-it-yourself values, without the Nix language/model as a prerequisite, and adds the security-only posture and local AI. |
| secureblue | Hardened, image-based Fedora Atomic | Closest on security philosophy. InterGenOS differs in being built from source (not a Fedora-derived immutable image) and in shipping a local assistant; the trust model is per-file pkm verification rather than an atomic image. |
| Qubes OS | Security through strict VM compartmentalization | A different and excellent paradigm. InterGenOS hardens a single conventional system you use directly (lighter hardware needs), rather than isolating workloads into Xen domains. |
| openSUSE | A polished general-purpose system with YaST and snapshots | InterGenOS is narrower by design — security-only, built from source, with the local-AI and checkable-boot pillars rather than a broad admin toolkit. |
When something else is the better fit
Honesty cuts both ways:
- You want the widest possible software availability out of the box → Debian or Fedora.
- You want rolling, bleeding-edge, fully hand-assembled → Arch.
- You live in a declarative/reproducible config workflow already → NixOS.
- You need hard workload isolation above all (separate, mutually distrusting compartments) → Qubes OS.
- You want Fedora’s ecosystem with hardening in an immutable image → secureblue.
If those are your priorities, use them — they are good at what they do.
When InterGenOS is the fit
Choose InterGenOS if you want one system that is:
- security-first to the point of being security-only, with a hardened default you do not have to assemble yourself;
- transparent and built from source, where every guarantee is something you can check yourself rather than take on faith;
- shipped with a genuinely useful local AI assistant that does not send your data anywhere;
- honest with you about exactly what it enforces today.
That specific combination is the reason InterGenOS exists. If it is the combination you have been looking for, start here.
Threat Model & Security Philosophy
InterGenOS is a security-only-aligned, built-from-source Linux distribution. This page describes who and what the system is designed to defend against, the assumptions behind that design, and the concrete consequences those assumptions have for how InterGenOS is built and how it behaves on your machine.
The guiding principle is short: Security is not first. It is only. When a security control conflicts with convenience, security wins. The goal of every decision is a machine you understand, can modify, and can trust — because a machine you cannot trust is a machine you do not control.
This is version 1.0-dev (build id v1.0-dev1). Where a feature is planned rather than shipped, this page says so explicitly.
The adversary we assume
InterGenOS is built on the working assumption that adversaries have superhuman vulnerability-discovery capability. We do not design only for the casual attacker who needs a known, published exploit. We design for an attacker who can find the silent failure you did not know was there.
That assumption changes what counts as “safe.” A masked error, a blanket “ignore failures,” an unverified “known-good” claim, or a degraded-but-shipped feature is not a minor blemish. It is precisely the seam such an adversary pulls on. So throughout InterGenOS, the question asked of every control is not “is this convenient?” but “does this eliminate a silent failure and turn an unverified assumption into a checked gate?” If an option masks rather than verifies, it is treated as wrong.
This threat model spans several concrete adversaries:
- A tampered or substituted system image — someone swapping the read-only system files underneath a validly signed kernel.
- A tampered boot chain — an attacker trying to run an unsigned kernel, an unsigned bootloader, or an untrusted kernel module.
- A compromised software supply chain — malicious code injected upstream into a language ecosystem package or a build dependency.
- A tampered package mirror or man-in-the-middle on install — corrupted or substituted packages delivered when you install or update software.
- A compromised system service — a daemon that gets exploited at runtime and tries to escalate or move laterally.
- A coerced on-device AI assistant — an attacker using prompt injection to talk the local assistant into weakening the system’s own protections.
- Silent data exfiltration — software phoning home with telemetry, analytics, or usage data you never agreed to send.
The rest of this page describes the design consequences of defending against each of these.
Defending the boot and integrity chain
InterGenOS anchors trust at power-on and carries it forward, so a tampered system cannot quietly boot.
- Signed boot chain. A Microsoft-signed shim (the pre-signed shim from Fedora) validates the InterGenOS GRUB bootloader, which in turn verifies the Linux kernel and the Unified Kernel Images (UKIs). Secure Boot enforcement is optional and off by default on the current fleet; with it enabled, unsigned kernel modules are not trusted.
- Integrity-verified system image. The system files ship as a read-only image with a verified-integrity hash tree (dm-verity) generated over it. Each signed kernel image carries the root hash of that image on its command line, so with Secure Boot enabled, a tampered system image cannot boot under a validly signed kernel. A whole-file checksum path exists as a fallback, asserted non-empty at build time and verified again at boot.
- Signed end to end. One hardware-token signing step covers the bootloader and all of the unified kernel images. Signing only appends a signature; it never alters the payload. Inputs are re-staged and re-checked against the freshly built system image before every signing, and the signed outputs are verified afterward.
- Your own keys for your own kernels. The InterGenOS release-signing key never leaves a hardware token under InterGenOS control. If you need out-of-tree modules such as proprietary drivers, the Forge installer walks you through enrolling a Machine Owner Key (MOK) on first boot. Installed systems regenerate and sign each kernel’s UKI with your machine’s local MOK at every kernel install or upgrade, so the same boot-time signature verification keeps applying to kernels you add after the original ISO.
This is the trust chain referenced elsewhere on this site as “the trust chain that keeps this machine yours.” For a deeper walkthrough, see the verified-boot pages under the installation guide.
Defending the supply chain and the mirror
A from-source distribution lives or dies by what goes into the compiler and what comes off the mirror.
- Built from source in an isolated, reproducible environment. Every source is pinned and checksum-verified before it is used. Builds are deterministic by construction (a fixed source date, pinned checksum-verified sources, deterministic ordering); full byte-identical output across independent builders is a documented 1.x goal.
- Reduced exposure to language-ecosystem attacks. To protect against active attack windows targeting Python packages, InterGenOS sources critical dependencies from verified GitHub release tags rather than relying on PyPI. Rust and Go packages use a reproducible vendor pipeline: dependencies are fetched, verified, and packaged offline, so upstream ecosystem volatility cannot break the build or inject compromised code during a compile step.
- A signed binary mirror. Software installs pull from
repo.intergenos.org. The package index is the signed manifest of the whole repository. Everypkm synccryptographically verifies theInterGenOS.dbindex signature against a release-signing subkey held on a hardware token and certified by the offline InterGenOS master key, and on downloadpkmvalidates each file’s SHA-256 hash locally before installation. Publishing regenerates and re-signs the complete index every time — incremental data transfer, never a partial signature — and the live repository is promoted by an atomic swap so clients never see a half-published state. - A Software Bill of Materials for the boot trust anchor. InterGenOS ships a deterministic SPDX 2.3 JSON SBOM for the Secure Boot shim — the Microsoft-signed binary every other boot component is verified through — attesting its exact build inputs and source hashes: the pinned upstream shim source, the base build image, the embedded InterGenOS Secure Boot CA certificate, and the SBAT entry. It is a real, machine-readable provenance record for the most security-critical binary in the chain, not a claim you take on faith.
For v1.0, InterGenOS uses an index-only signature trust model: a centralized, verifiable source of truth.
Defending the running system
Once booted, the system limits the blast radius of any single compromised component.
- AppArmor in enforce mode. InterGenOS ships AppArmor profiles for system daemons in enforce mode by default, not complain mode or disabled.
- Aggressive systemd hardening. System services run sandboxed with extensive isolation directives so that a compromised daemon has very little reach. Baseline directives applied across system daemons include
NoNewPrivileges=true,ProtectSystem=strict,ProtectHome=true,PrivateTmp=true,PrivateDevices=true, theProtectKernel*family,ProtectControlGroups=true,RestrictAddressFamilieslimited toAF_UNIX AF_INET AF_INET6,RestrictNamespaces=true,MemoryDenyWriteExecute=true(except for packages that explicitly require a JIT),SystemCallArchitectures=native, and a@system-servicesystem-call filter with@privileged @resources @mount @swap @rebootdenied. - Safe network binds. Any server package shipped by InterGenOS binds to localhost (
127.0.0.1) by default. Services never listen on a public interface unless you deliberately change their configuration. - No default passwords. InterGenOS does not ship databases or services with blank or default “admin” credentials. Initial credentials are randomly generated or require manual setup during installation.
- Locked by default. A freshly installed system ships locked: no remote access enabled and a default-deny firewall.
Defending the privacy boundary
InterGenOS treats your data leaving the machine as a security event, not a settings preference.
- No telemetry. Zero analytics, crash reports, or usage statistics are collected.
- No auto-updates. The system does not change software behind your back. Upgrades happen only when you explicitly run
pkm upgrade. - No opt-out privacy. There are no toggles to stop your OS from exfiltrating usage data, because it collects and sends none. The network is used only for things you initiate — package syncs, the one-time model download, a browser, a service you start, or an opt-in Phone-A-Friend request — never to report on you.
- No proprietary firmware forced into the core. The core operating system relies on open-source drivers and firmware. Proprietary blobs are available if your hardware strictly requires them, but they are never forced on you.
Defending against a coerced AI assistant
InterGenOS ships an on-device assistant called InterGen: a tiered, hardware-detected, offline-first local assistant (built on Qwen models) with zero telemetry. Its permission model is part of the threat model, not an afterthought.
Two ideas drive its design.
Inherit the OS’s gate; do not invent a new one. InterGen mirrors the privilege model you already understand: you can freely touch your own things, and you need sudo/PolicyKit for system things. Every action is classified by zone and operation and resolved to one of three outcomes:
- FREE — done immediately, no prompt. All reads of non-secret data, and everything in your own user space.
- AUTH-PROMPT — InterGen triggers the OS’s real authorization (pkexec/PolicyKit), phrased plainly (“InterGen wants to restart Bluetooth. That needs admin rights. Authorize?”). Your password is the gate; the kernel enforces it. This covers writing or state-changing system configuration, and reading secrets such as the shadow file — because you yourself could do that with
sudo, so InterGen does not pretend to be stricter than the OS. - FORBIDDEN — InterGen will not do it, and says so transparently, handing control back to you. It states plainly what it will not do and why, and confirms you can do it yourself.
The assistant cannot edit its own restraints. InterGen’s own code, model pins and signature, daemon units, PolicyKit policy, verified model store, and signing/provenance state are treated as system-critical — in the same protected class as the boot keys and the integrity hashes. Writing or modifying them is FORBIDDEN to InterGen. This closes a specific attack: a capable adversary’s whole game is to talk the assistant into rewriting its own gate, manifest, or guardrails. If the assistant’s substrate is write-forbidden to the assistant, even a flawless prompt injection cannot make it weaken itself. Only you, acting manually and outside the assistant, can change those files.
A deliberate separation underpins this. Two orthogonal axes are evaluated by two independent mechanisms and are never conflated:
- The privilege axis asks “would a human need
sudofor this?” On this axis, a read is always free. - The content-trust axis independently watches what crosses the boundary: injection on the way in, secrets on the way out. This is the job of the scanner and provenance layer, including InterGen Sentinel, a pluggable security scanner whose default configuration is local-only (Local-Rules plus a local Qwen model). Sentinel supports six opt-in cloud providers — Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek — none of which are engaged unless you choose to enable them.
Escalating a hard question to a frontier cloud model is called Phone-A-Friend (Frontier/Cloud Escalation). Like the Sentinel cloud providers, it is opt-in and never the default path. The default assistant stays on the device with zero telemetry.
Design consequences for the build itself
The threat model is not only a set of runtime controls; it shapes how a release is allowed to come into existence. The reasoning is simple: a build whose packages all compiled is not a build that is known-good. The expensive failures of a from-source distribution compile fine, package fine, and only manifest when the artifact is installed and booted on real hardware — a service locked down with no writable path, a directory omitted from a package’s file list, a hardware-detection heuristic wrong for a specific GPU, a first-boot race.
Several rules follow, and they are non-negotiable:
- No silent failures. Every error surfaces; an unverified assumption becomes a checked gate or it is not trusted.
- No stubs. Placeholder code that pretends to work does not ship — “a stub is a lie.”
- No cheating around a build failure. A failing package is fixed in the source tree, never worked around by moving it to another tier, disabling a feature to dodge a missing dependency, or silently skipping a step.
- Only a clean build counts. A fix is done when it lives in the source tree and a clean from-scratch build reproduces the corrected behavior with zero manual intervention. A fix that only works because of a hand-edit on the running target is a note about a fix, not a fix.
- Validate on real hardware. The candidate loop always runs through the full bootloader → ISO → install → boot chain, and race-class issues must clear several consecutive cold boots on representative lower-end hardware.
A candidate becomes a stable release only when a complete from-scratch cycle runs end to end with zero triggers — nothing required a fix — with the hardware-token signing step as the only sanctioned human action.
The build runs as an ordered, reproducible lifecycle of 20 phases (validate, verify-sources, setup, toolchain, chroot-prep, chroot-tools, core, config, core-extra, base, kernel, desktop, ai, extra, bootloader, image, manifest, squashfs, ukis-verity, iso), with publishing as an optional final step. Packages are organized across six tiers (toolchain, core, base, desktop, ai, and extra). Exact package counts are derived live from the source tree and drift between builds; as of this writing (2026-06-15) the total is in the neighborhood of 857 packages.
What ships today versus what is planned
This page describes the system as it exists in 1.0-dev. To keep the threat model honest, the line between shipped and planned is drawn explicitly.
Shipped today:
pkm, the package manager, against the signed mirror.- Forge, the InterGenOS installer.
- A signed Secure Boot chain, dm-verity integrity verification, and UKI signing.
- The GNOME 49 desktop on Wayland.
- The InterGen local assistant and InterGen Sentinel as described above.
Planned, not shipped (do not treat as current):
- KDE/Plasma (Qt6) and switchable desktops.
- The application campaigns (for example Kdenlive, OBS, Krita, Blender, FreeCAD, GnuCash, and Boxes).
Further reading
Switching to InterGenOS
If you are coming from Debian, Ubuntu, Fedora, Arch, or another mainstream Linux distribution, this page maps what you already know onto how InterGenOS does things. The goal is not to convince you that everything is different. Most of it is not. The differences that matter are deliberate, and they all serve the same purpose: a machine you understand, can modify, and can trust.
Security is not first. It is only. Every default on this page exists because of that posture.
What is the same
InterGenOS is a Linux distribution. The kernel, the shell, the GNU coreutils, systemd, OpenSSH, and the GNOME desktop all behave the way you expect. Your shell scripts, your dotfiles, your editor, your terminal habits, and the standard command-line tools carry over without translation.
The desktop that ships today is GNOME 49 on Wayland. If you have used recent GNOME on any other distribution, the Activities overview, the app grid, Quick Settings, and the Settings app are all where you left them. The default icon theme is Papirus-Dark.
InterGenOS is built from source on the Linux From Scratch (LFS 13.0) and Beyond Linux From Scratch (BLFS 13.0) foundation. That is a build-time fact, not something you have to think about while using the system day to day.
What is different, and why
Package management uses pkm, not apt/dnf/pacman
InterGenOS ships its own package manager, pkm. It covers the operations you already do under other names, and it accepts the command names you would naturally reach for. The dispatch resolves aliases to a canonical command, so behavior is identical regardless of which name you type.
| You are used to (apt / dnf / pacman) | On InterGenOS |
|---|---|
apt update / dnf check-update / pacman -Sy | sudo pkm sync (also update, refresh) |
apt upgrade / dnf upgrade / pacman -Su | sudo pkm upgrade |
apt install <pkg> / pacman -S <pkg> | sudo pkm install <pkg> |
apt remove <pkg> / pacman -R <pkg> | sudo pkm remove <pkg> (also uninstall) |
apt search / dnf search / pacman -Ss | pkm search <term> (also find) |
apt show / dnf info / pacman -Si | pkm info <pkg> (also show) |
dpkg -l / pacman -Q | pkm list installed (also ls) |
dpkg -S <file> / pacman -Qo <file> | pkm provides <file> |
debsums / rpm -V | sudo pkm verify <pkg> (or pkm verify --all) |
One important distinction from apt: pkm sync only refreshes the local index. It does not change anything on disk. pkm upgrade is the command that actually installs newer versions. Nothing upgrades on a timer — though a daily check does notify you when upgrades are available (it installs nothing, and you can disable it; see below).
For the full command surface, see The Package Manager.
Proprietary and third-party apps come through pkm install
Software that other distributions reach for via a vendor .deb, a third-party repository, or the AUR is installed through the same pkm install command as everything else. InterGenOS ships a small download-helper for each, and pkm routes to it automatically — there is no separate command to remember:
sudo pkm install chrome # Fetches from Google, installs via pkm
sudo pkm install vscode # Fetches from Microsoft, installs via pkm
sudo pkm install claude-code # Fetches from Anthropic, installs via pkm
Because these are proprietary, pkm will not install one silently. The install stops for an explicit, interactive license acceptance — you cannot complete it by accident:
pkmfirst names the vendor license and asksContinue? [y/N].- The vendor’s own installer then prints its license and requires you to type
I ACCEPT(exact match, capitals) to proceed. Anything else aborts the install.
Only after you accept does the helper download from the vendor, verify the download against the vendor’s signed metadata (a SHA-256 integrity check), and install. Your acceptance is recorded under /var/lib/intergen/legal/, so a later reinstall of the same version does not prompt again.

No background network activity
This is the largest behavioral change for most people switching:
- No background refresh. The system does not reach out to the network until you explicitly run
pkm syncorpkm install. - No telemetry. There is no popcon, no countme equivalent, no usage analytics.
- No unattended upgrades. The system stays exactly as it is until you command a change.
- A daily update check, opt-out. One timer (
pkm-check-updates.timer) compares your installed packages against the index you last synced and shows a count of available upgrades (a tray indicator and a login message). It downloads and installs nothing, reaches no further than your local index, and turns off withsudo systemctl disable --now pkm-check-updates.timer.
If a package ships under a non-OSI license, pkm halts and shows a banner requiring your explicit consent before downloading.
How that compares to the package managers you may know:
| Feature | pkm (InterGenOS) | apt (Debian/Ubuntu) | pacman (Arch) | dnf (Fedora) |
|---|---|---|---|---|
| Trust model | Signed index | Signed index (InRelease) | Signed index / per-package sigs | Signed metadata / per-package sigs |
| Auto-updates | Never | Configurable | Configurable | Configurable |
| Telemetry | None | Popcon (opt-in) | None | countme (opt-out/opt-in) |
| Non-OSI license | Halts for consent | Relies on repo separation | AUR / user discretion | Relies on repo separation |
A signed boot chain you own (Secure Boot optional)
On other distributions, Secure Boot is often something you disable to get work done, or a chain you do not control. InterGenOS ships a signed boot chain where the trust anchor is your own MOK key, generated per machine by the installer, Forge: signed shim, MOK-signed GRUB, and a MOK-signed Unified Kernel Image. Secure Boot enforcement is optional — the current fleet ships with it off, and you can enable it (and enroll your MOK) on hardware that supports it. dm-verity seals the live install image.
If you enable Secure Boot you enroll your MOK at install time; either way the machine boots through a chain you can audit. See the Forge installer guide.
Transparent boot, no splash
There is no Plymouth splash screen hiding the boot. You watch the kernel hand off to systemd and every service report [OK] or [FAILED]. If a mount breaks or a module misbehaves, you see it the moment it happens. Reading boot output is a real practice for noticing a compromise or a hardware change, so the system gives you that surface rather than covering it.
A local AI assistant, fully offline
InterGenOS ships InterGen, a tiered, hardware-detected local assistant built on Qwen models. At setup time it detects your CPU, RAM, and GPU and picks a model and quantization that fit the machine, from a 4 GB laptop up to a GPU workstation. It runs fully offline with zero telemetry, no accounts, and no cloud round-trip. Every tool call is permission-gated; the default mode requires confirmation before anything changes system state.
Paired with it is InterGen Sentinel, a pluggable security scanner that reviews MCP tool calls before they execute. The default is local only: a deterministic rule-based scanner plus a local-Qwen-backed reviewer. Six cloud providers are strictly opt-in, and you choose which (if any) ever reaches the network: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek. This opt-in cloud routing is called Phone-A-Friend (Frontier/Cloud Escalation). Schema-pinning, audit logging, and sandbox enforcement are local plumbing that applies no matter which scanner is active.
What you should know before switching
InterGenOS is version 1.0-dev (build id v1.0-dev1) and under active, pre-1.0 development. A few expectations to set:
- GNOME on Wayland is the only desktop today. Switchable desktop environments such as KDE Plasma and XFCE are on the roadmap and are not part of the current system. If you require a non-GNOME desktop right now, this is not yet the system for you.
- The package set is from-source and curated, not exhaustive. As of June 2026 the build comprises roughly 857 package templates across six tiers (toolchain, core, base, desktop, ai, extra). These counts drift as the set is finalized. If a piece of software you rely on is not yet packaged, you can build it yourself in the meantime.
- The public binary mirror is being finalized. The signing-key ceremony is complete and mirror infrastructure is provisioned at
repo.intergenos.org; the first public publish goes live once the v1.0 archive set is complete.
Migrating your data and habits
Because the userland is standard, the practical migration is the ordinary one:
- Copy your home directory, dotfiles, and project files as you would between any two Linux machines (
rsync, an external drive, or your usual backup). - Reinstall applications with
pkm install <pkg>— the same command covers proprietary or third-party apps (e.g.pkm install vscode), which prompt for vendor-license acceptance the first time. - Your shell configuration, SSH keys, and Git setup carry over unchanged.
There is no in-place upgrade path from another distribution. InterGenOS is a fresh install through Forge.
Where to go next
FAQ
Common questions about InterGenOS. Answers here describe what ships today, not what is planned. Where the answer differs for planned work, it says so explicitly.
What is InterGenOS?
InterGenOS is a Linux distribution built entirely from source, based on Linux From Scratch 13.0 and Beyond Linux From Scratch 13.0. Every package is compiled from source with deliberate choices. It ships a custom package manager (pkm), a from-source build system (igos-build), a native installer (Forge), a signed Secure Boot chain, and a tiered local AI assistant. The goal behind every default is a machine you understand, can modify, and can trust.
What does “security-only alignment” mean?
It is the project’s governing doctrine. Where a security control conflicts with convenience, security wins. The phrasing the project uses is direct: security is not first, it is only. In practice that means a fully signed boot chain (with optional Secure Boot enforcement), AppArmor profiles in enforce mode for system daemons, aggressive systemd sandboxing, localhost-only network binds by default, and zero telemetry. See Hardening Baseline and Threat Model & Security Philosophy for the full picture.
What version is this?
The current development line is 1.0-dev (build id v1.0-dev1). InterGenOS is in active development, pre-1.0. The package set, build tooling, and installer are functional; the public binary mirror’s first publish lands once the v1.0 archive set is complete.
What desktop does it use?
InterGenOS ships GNOME 49 on Wayland with a dark theme and InterGenOS branding. There is no Plymouth splash: you watch the kernel hand off to systemd and every service report [OK] or [FAILED] at boot. That visibility is deliberate. Spotting unusual boot output is a real practice for catching a compromise or a hardware change.
Switchable desktop environments such as KDE Plasma and others are on the roadmap. They are not shipped today.
How do I install software?
With pkm, the InterGenOS package manager. The common commands:
sudo pkm sync # refresh the local index, verify its signature
pkm search audio # search the local index (no network needed)
sudo pkm install htop # download, verify, and install a package
sudo pkm upgrade # install newer versions of installed packages
sudo pkm remove htop # uninstall, and clean orphaned dependencies
pkm list installed # list everything installed
pkm info openssh # show metadata for a package
pkm verify openssl # check installed files against recorded hashes
pkm also accepts familiar aliases from other distributions: update accepts sync/refresh, remove accepts uninstall, search accepts find, and so on. See The Transparent Package Manager for the full reference.
Does pkm phone home or auto-update?
pkm does not phone home, and it never installs or upgrades software on its own — your system changes only when you explicitly run pkm install, pkm upgrade, or pkm remove. There is no telemetry of any kind. It does ship one opt-out convenience: a daily timer that checks whether upgrades are available and shows a count (a GNOME tray indicator and a login message), installing nothing and reaching no further than the index you last synced. Turn it off with sudo systemctl disable --now pkm-check-updates.timer if you would rather it not run. The project’s phrasing is that silence is golden.
How is software trust verified?
pkm fetches the InterGenOS.db index from the official mirror and verifies its signature against a release-signing subkey — held on a hardware token and certified by the offline InterGenOS master key — whose fingerprints are pinned locally. When you install a package, its SHA-256 hash is checked against the verified index before extraction. A signature failure or hash mismatch is a hard rejection. The v1.0 release uses an index-only signature trust model.
What about proprietary software?
InterGenOS does not ship proprietary binaries in its archive set. Instead, you install them with the ordinary pkm install <name> command (e.g. pkm install vscode); pkm recognizes these as proprietary and routes to a small download-helper that fetches the payload from the vendor. The install stops for an explicit, interactive vendor-EULA acceptance the first time — you confirm a Continue? [y/N] prompt and then type I ACCEPT to proceed, and the acceptance is recorded so a later reinstall does not re-prompt. Helpers cover software such as Brave, Chrome, Edge, Spotify, Discord, VS Code, and Claude Code. The core operating system itself relies on open-source drivers and firmware; proprietary firmware blobs are available only when your hardware strictly requires them.
How many packages are there?
The package set is organized into six tiers and drifts as the system grows. As of June 2026 it is roughly 857 templates: toolchain (28), core (272), base (23), desktop (420), ai (2), and extra (112). Treat these as a live count rather than a fixed number; query your synced index for the current state.
| Tier | Purpose |
|---|---|
| toolchain | Cross-compilation (LFS Ch. 5-7) |
| core | Full system: kernel, shell, coreutils, systemd, GCC, SSH |
| base | CLI tools: htop, rsync, strace, screen |
| desktop | GNOME on Wayland: GTK, Mesa, GStreamer, GNOME Shell |
| ai | Local AI assistant: InterGen (which includes Sentinel) and llama.cpp |
| extra | User applications: Node.js, Chrome, VS Code, Claude Code |
What is InterGen?
InterGen is the onboard AI assistant: a tiered, hardware-detected, offline-first local assistant built on Qwen models with zero telemetry. At setup time it detects your CPU, RAM, and GPU, then selects a model and quantization appropriate to the machine, from a 4 GB laptop up to a GPU workstation. No cloud, no accounts, no round-trip latency. It is text-only by design.
Every tool call InterGen makes is treated as privileged. The default escalation mode requires user confirmation before any action that changes system state, tool signatures are pinned against drift across upgrades, and a separate audit log records every invocation. The assistant is a system component, not a hole in it.
What is InterGen Sentinel?
InterGen Sentinel is a pluggable security-scanner architecture. It routes MCP tool calls through a scanner of your choice before they execute. The default is local-only: Local-Rules (rule-based, deterministic) and Local-Qwen (your local Qwen model reviewing the call), both fully offline.
For richer review you can opt into any of six cloud providers: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek. This escalation path is called Phone-A-Friend (Frontier/Cloud Escalation). It is entirely opt-in. You pick which scanner (if any) reaches across the network; everything else stays on the machine. Schema-pinning, audit logging, and sandbox enforcement are vendor-neutral local plumbing that apply regardless of which scanner is active.
How does Secure Boot work here?
The boot chain is fully signed: a Microsoft-signed shim to a signed GRUB to a signed kernel and Unified Kernel Image. Secure Boot enforcement is optional and off by default on the current fleet — the signatures are present and verifiable, ready to enforce on hardware where you enable Secure Boot and enroll your Machine Owner Key (MOK). The Forge installer generates that MOK per machine. Installed systems sign each kernel’s UKI with your machine’s local MOK at every kernel install or upgrade. The InterGenOS release-signing key never leaves a hardware token under project control; only your machine-local MOK signs the kernels you install. See Verified Boot & Secure Boot.
What integrity protections ship by default?
A signed Secure Boot chain, dm-verity integrity, and UKI signing. System daemons run under AppArmor in enforce mode and under extensive systemd isolation directives (NoNewPrivileges, ProtectSystem=strict, PrivateTmp, syscall filtering, and more). Server packages bind to localhost by default. No service ships with a blank or default password.
What hardware does it run on?
Bare-metal installs have been validated across widely varying hardware, from current laptops back to a roughly 2012 2nd/3rd-generation Intel Core i5, each through the full signed boot chain and the end-to-end ISO-installer path.
How is the OS built?
A single build runs 20 phases:
validate -> verify-sources -> setup -> toolchain -> chroot-prep ->
chroot-tools -> core -> config -> core-extra -> base -> kernel ->
desktop -> ai -> extra -> bootloader -> image -> manifest ->
squashfs -> ukis-verity -> iso
Publishing to the mirror is an optional follow-on step. The build can resume from any phase with --start-at and stop with --stop-after; checkpoints are saved after the toolchain, core, and desktop phases.
What is on the roadmap but not yet shipped?
Several items are in flight and not present in the current build: switchable desktop environments (KDE Plasma and others), the public binary mirror’s first publish, packaging pkm itself so it works out of the box on a fresh target, a higher AI tier for high-end hardware, and NVIDIA open-module packaging. Curated application campaigns (for example Kdenlive, OBS, Krita, Blender, FreeCAD, GnuCash, Boxes) are planned and not current. None of these are guaranteed in the current build.
Where can I learn more?
- The Transparent Package Manager
- Hardening Baseline
- FORGE Installation Guide
- Threat Model & Security Philosophy
Install with FORGE
FORGE is the InterGenOS installer. It takes you from the live environment to a deployed, bootable, user-configured system on a target disk. Every install runs through a verification gate that checks the cryptographic integrity of each package against the signed release manifest before any disk write occurs, so the system you boot is the system that was actually published.
This section covers what to expect during installation, how the installer is structured, and the device- and security-specific notes that matter once you commit to writing a disk.
What FORGE installs
FORGE deploys InterGenOS 1.0-dev (build id v1.0-dev1). The shipped desktop is GNOME 49 on Wayland. The installer also lays down the components that make the system trustable end to end:
- pkm, the transparent package manager.
- A signed boot chain (shim → GRUB → UKI) with a per-machine Machine Owner Key (MOK) generated during install. Secure Boot enforcement is optional and off by default on the current fleet; the signatures are present and ready for hardware where you turn it on.
- dm-verity integrity sealing the live ISO image. (The installed root is an ordinary
ext4filesystem, verified per-file bypkm.) - UKI signing for the boot image.
- InterGen, the tiered, hardware-detected, offline-first local assistant (Qwen models, zero telemetry), which includes a built-in security scanner, InterGen Sentinel (default Local-Rules plus Local-Qwen, with opt-in cloud providers).
Packages are organized into six tiers (toolchain, core, base, desktop, ai, and extra). The total count drifts as the distribution evolves; derive the live figure from the release manifest rather than treating any single number as fixed. As of 2026-06-15 the installable set is roughly 857 packages across those tiers.
How FORGE works
FORGE uses a split frontend/backend architecture joined by a declarative state model. A frontend collects your choices and emits a serialized YAML description of the system you want. The backend consumes that YAML and the credentials you supply, then executes the install.
Two frontends are available, and both drive the same backend identically:
- GUI — a GTK4 / libadwaita wizard with a multi-screen flow (welcome, keyboard and locale, disk, user, packages, confirm, progress, done). Use this for a standard desktop install.
- TUI — a
dialog-based text interface suited to SSH sessions, headless servers, or keyboard-only navigation.
The backend runs a linear, phased pipeline. The first phase after configuration validation is the integrity gate: FORGE computes the SHA-256 of every package archive it intends to deploy and verifies it against the signed archive manifest. A mismatch halts the install before partitioning begins, unless you provide explicit, typed confirmation to override. That override phrase must be typed in full; the installer disables paste, drag-and-drop, and the right-click menu on the field so the consent is deliberate.
If a phase fails, FORGE halts the pipeline, performs best-effort unmounts scoped to how far the install progressed, and surfaces the exact point of failure on the final screen. Non-fatal warnings, such as a trust-chain audit-log copy failure, are reported there too so you always know the true state of the deployment.
Security posture
The install path is built so the result is a machine you understand, can modify, and can trust: the integrity gate proves what was written, the on-machine MOK keeps the boot chain under your control, the signed UKI protects the boot path (enforced once you enable Secure Boot), and pkm’s per-file hashes let you verify the installed system at any time.
In this section
- FORGE Installation Guide — step-by-step walkthrough of an install from boot to first login.
- Disk Encryption & LUKS — encrypting the target disk.
- Verified Boot & Secure Boot — the MOK, signed GRUB, dm-verity, and UKI signing.
- Per-Device Install Notes — hardware-specific guidance.
- Installing in a Virtual Machine — trying InterGenOS as a guest in VirtualBox or VMware.
- Recovery & Reinstall — repairing or reinstalling an existing system.
If you run into trouble during or after install, see the Troubleshooting section and the FAQ.
FORGE Installation Guide
FORGE is the InterGenOS installer. It takes you from the live environment to a deployed, bootable, configured system on your target disk. This page walks through the graphical installer screen by screen, in the order you encounter them.
Before any data is written to disk, FORGE runs a verification gate that checks the cryptographic integrity of every package archive against the signed release manifest. If anything fails to match, the install halts before partitioning. Nothing is committed to your disk until you reach the confirmation screen and click Install.
InterGenOS is a built-from-source Linux distribution where security is not first. It is only. The installer is part of that: a machine you understand, can modify, and can trust starts with an install flow that tells you exactly what it is doing.
FORGE also ships a text-based (TUI) frontend for headless and SSH installs. It collects the same choices and runs the same backend. This guide documents the GTK4 graphical wizard.
Step 0 — Boot menu

The boot menu, the first screen after you boot the install media. Select “Install InterGenOS (Graphical)” to follow this guide.
When you boot the InterGenOS media you land here first. The menu is served by a signed GRUB, and selecting an entry hands off to a signed Unified Kernel Image (UKI) — the boot path is verified end to end. Try InterGenOS boots the live GNOME session (you can also launch FORGE from there); the two Install entries start the installer directly. Advanced options holds “Boot from first hard disk” and “UEFI firmware setup”. This guide follows Install InterGenOS (Graphical).
The live GNOME session and, after installation, your first login both land on the InterGenOS greeter:

The InterGenOS greeter — the themed GNOME login screen, carrying the project creed.
Step 1 — Welcome

The FORGE welcome screen. Click “Let’s begin” to start the wizard.
The first screen introduces the installer and confirms what you are about to do: build a machine from source, with every default verified before install. Click Let’s begin to start.
Step 2 — Language and keyboard

Language, locale, and keyboard selection. The summary card at the top reflects your current choices.
This screen sets your system language, locale, and keyboard layout. The card at the top summarizes the active configuration (for example, English (United States), en_US.UTF-8).
- Language sets the language of menus, dialogs, and regional formatting for numbers, dates, and currency.
- Keyboard sets the physical keyboard layout. A test field lets you confirm that special characters and symbols type the way you expect before moving on.
Scroll down to change any item, then continue on the same screen to set your timezone.

Timezone selection. Click the map or use the Region dropdown to set the system clock.
The timezone you pick sets the system clock and the timestamps on log entries. Click a region on the map or choose it from the Region dropdown. When the language, keyboard, and timezone are correct, click Next.
Step 3 — Disk and encryption

Disk selection. The selected disk will be completely erased. The disk hosting the live ISO is filtered out automatically.
Pick the disk InterGenOS will be installed onto. The selected disk is completely erased — all existing data on it becomes unrecoverable. A red warning banner states this plainly, and you must tick I understand — erase this disk before you can continue.
- All detected disks are listed under Destination. The disk the live ISO is running from is filtered out automatically.
- If no disks are auto-detected, you can tick Type a disk path manually and enter a path such as
/dev/sda. A manual entry stays marked “unverified until ‘Next’” until the installer validates it.
Full-disk encryption (optional)
Scrolling down on this screen reveals the encryption and boot options. Full-disk encryption is opt-in, not the default — FORGE asks, and you choose. Ticking Encrypt the root filesystem with LUKS2 turns it on.
If you enable encryption:
- FORGE prompts for a passphrase with a confirmation field. A live strength label appears as you type. The guidance is a soft warning, not a hard block: 8 characters is the floor below which the warning fires, and 12 characters with at least two character classes is the recommended baseline. You can accept a passphrase that fires the warning after confirming.
- The target partition is formatted with LUKS2 using
cryptsetup. Forge explicitly forces the memory-hardargon2idkey-derivation function (resistant to GPU and ASIC brute force); the cipher is cryptsetup’s default of AES-256 in XTS mode, which Forge does not override. - Your passphrase is never written to disk outside the LUKS header slot itself, never logged, and never sent anywhere. There is no recovery-key escrow and no master key. If you forget the passphrase, the data is gone. This is by design.
Two unlock methods are wired as EXPERIMENTAL v1.0 sub-options that compose with the passphrase: TPM2-sealed unlock and FIDO2-token unlock. Both add an additional LUKS key slot alongside the passphrase slot — the passphrase slot is always retained as the unconditional fallback. For the full encryption model, boot-time unlock flow, and recovery procedures, see the full-disk encryption documentation.
When the disk and encryption choices are set, click Next.
Step 4 — User accounts and Secure Boot

Identity setup. Pick a hostname and username; both default to safe values if left as-is.
This screen sets up your accounts. The card at the top tracks four items: Username, User password, Admin password, and the optional MOK enrollment password.
Under Identity you set:
- Hostname — the machine’s name on the network.
- Username — the unprivileged account you log in with day to day.
Both default to safe values if you leave them as-is.

Administrator password and optional Secure Boot (MOK) enrollment.
Scrolling down reveals the password and Secure Boot fields.
- Administrator sets the root password, used only for system maintenance via
sudo. Pick a different password from your user account; minimum 8 characters. A strength indicator confirms when the password passes the minimum recommendation. - Secure Boot enrollment is optional and applies to EFI systems only. The MOK enrollment password is a one-time password you type at first boot when MokManager prompts you to register your per-machine Machine Owner Key (MOK) with the firmware. Leave it empty to skip; you can re-enroll later with
mokutil. A link to the first-boot walkthrough explains the MokManager prompts and the recovery procedure if enrollment fails.
When your accounts are set, click Next.
Step 5 — Package groups

Package group selection. Core and GNOME Desktop are required; Base, Extras, and the local AI runtime are optional.
Here you pick what gets installed alongside the essential system. The packages are organized into groups. As of this build, InterGenOS spans roughly 850-plus packages across six tiers (toolchain, core, base, desktop, ai, and extra); these counts drift between builds, so derive the live numbers from the manifest rather than relying on a fixed figure.
The groups shown on this screen:
- Core system — Required. The essential system: kernel, shell, coreutils, systemd, SSH. Locked on.
- GNOME Desktop — Required. The desktop environment. InterGenOS ships GNOME 49 on Wayland. Locked on.
- Base CLI tools — optional command-line utilities.
- Extras — optional additional packages.
- Local AI runtime — optional. This enables InterGen, the system’s tiered, hardware-detected, offline-first local assistant (Qwen models, zero telemetry). The screen links to more detail about it.
You can toggle the optional groups on now or install them later. Everything is also available afterward on the running system through pkm, the InterGenOS package manager, with sudo pkm install <package name> or sudo pkm remove <package name>. When your selection is set, click Next.
Step 6 — Review and confirm

The confirmation screen. Nothing is committed to disk until you click “Install”.
This is the last screen before any disk writes. A Ready to install summary lists your choices: the package groups and services selected, your hostname, and your username. A red banner repeats the disk-erase warning, naming the target disk explicitly (for example, Installing onto /dev/sda will erase ALL existing data on that disk.).
Review everything. If something is wrong, click Back to step backwards through the prior screens and change it. Nothing is committed to disk until you click Install. When you are ready, click Install to begin.
Step 7 — Installing

The install runs through its phased pipeline, with a live backend log you can watch.
The install now runs through its pipeline: verifying package integrity, partitioning and formatting the disk, mounting the target, extracting and registering packages, generating configuration, creating accounts, generating the Machine Owner Key and signing the bootloader on EFI systems, running post-install hooks, enabling services, and cleaning up. A failure halts the pipeline, performs best-effort unmounts, and surfaces the exact point of failure rather than leaving you guessing.
A progress bar tracks overall completion, and a Backend log (live) panel streams the install as it happens, including the per-package hook progress (for example, phase=hooks 150/154). If you need to abort, Cancel install is available. When the log reads Install complete, click Continue.
Step 8 — Install complete

Installation finished. Remove the install media and reboot.
InterGenOS is installed. Remove the install media and click Reboot now.
On EFI systems, you are prompted to enroll the InterGenOS vendor certificate via MokManager on the first boot. This is where the MOK enrollment password you set in Step 4 is used. If you set one, have it ready; if you skipped it, you can enroll later with mokutil. For the MokManager prompts and the recovery procedure, see the first-boot walkthrough.
What FORGE installs
This release is InterGenOS 1.0-dev (build id v1.0-dev1). A completed install gives you:
- pkm, the package manager, for adding and removing software afterward.
- GNOME 49 on Wayland as the desktop. (KDE/Plasma and switchable desktops are planned, not shipped today.)
- A signed boot chain and UKI signing (Secure Boot enforcement is optional and off by default on the current fleet), plus dm-verity sealing the live install image — the boot-chain protections.
- Optionally, InterGen, the local offline-first assistant, and InterGen Sentinel, a pluggable security scanner that defaults to Local-Rules plus a local Qwen model. Sentinel can be extended with six opt-in cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), DeepSeek) through “Phone-A-Friend” (Frontier/Cloud Escalation).
Further reading
Disk Encryption & LUKS
InterGenOS offers first-class full-disk encryption at install time. This page explains the encryption model, what you choose during installation, what the boot prompt looks like, and how to recover when something goes wrong.
Encryption-at-rest is one of the controls that makes InterGenOS a machine you understand, can modify, and can trust: your disk is yours, and its contents stay unreadable to anyone who has the disk but does not have you.
For the signed-boot story that runs around the encrypted volume, see Verified Boot.
The short version
- Full disk encryption is opt-in, not default. The Forge installer asks; you choose.
- The format is LUKS2 with a passphrase. TPM2-sealed unlock and FIDO2-token unlock are wired as EXPERIMENTAL sub-options that compose with the passphrase. Pick any combination; the passphrase slot is always retained as the unconditional fallback.
- Your passphrase is never written to disk outside the LUKS header slot itself, never logged, and never sent anywhere. There is no recovery-key escrow.
- The encrypted volume holds the entire root filesystem. The ESP (the small boot partition) is not encrypted, because the firmware needs to read it before any operating system is running. Secure Boot signature verification on the UKI protects that surface.
- At boot, a small InterGenOS-branded prompt asks for your passphrase. Three attempts, then a recovery shell.
- If you forget your passphrase, your data is gone. This is by design. There is no master key.
Why encrypt
Encryption-at-rest protects the data on the disk from anyone who has the disk but does not have you: a stolen laptop, a discarded SSD, a seized device, a borrowed loaner. It does not protect the data from someone who has both the disk and your passphrase, and it does not protect a running system once you have unlocked it.
The trade-off is small. You type a passphrase once per boot. In exchange, the contents of the disk are an unreadable cryptographic blob to anyone without your passphrase. Encryption is left opt-in rather than default so that users who do not want the boot prompt are not forced into it, but it is recommended for any portable device.
The encryption model
InterGenOS uses LUKS2 (Linux Unified Key Setup, version 2) as the on-disk encryption format. LUKS2 is the standard Linux full-disk-encryption format. The tooling is cryptsetup, the algorithm defaults are modern (AES-256 in XTS mode), and the key-derivation function is argon2id (memory-hard, resistant to GPU/ASIC brute-force).
A LUKS2 volume has:
- A header, at the start of the encrypted partition, holding the encryption metadata: the cipher choice, the master-key wrapping, and up to eight key slots.
- Key slots, each independently holding a wrapping of the master key by one passphrase (or by a TPM-sealed key, or by a FIDO2-derived key). You can have several unlock methods active at once; deleting one slot does not affect the others.
- The encrypted payload, which is your root filesystem.
The master key never leaves the LUKS header. Your passphrase unwraps a key slot, which yields the master key, which decrypts the payload. The passphrase itself is held only in volatile memory during the unlock, and the unlock prompt zeroes the buffer when it finishes. There is no on-disk copy of your passphrase.
The Forge install flow
When you run the Forge installer (TUI or GUI), the partitioning stage offers an Encrypt the root filesystem with LUKS2 checkbox under the “Full-disk encryption (LUKS)” heading. If you tick it:
- Forge prompts for a passphrase with a confirmation field. Both frontends enforce a non-empty value and a matching confirm field, and both surface length-and-diversity guidance, but the exact wording differs between them. The GUI shows a live strength label as you type and warns when a passphrase is under 12 characters and uses only a single character class — its baseline is roughly 12 characters with at least two character classes. The TUI presents the NIST 800-63B style guidance up front: 12+ characters with at least three character classes, or 4+ unrelated dictionary words (the diceware pattern). The guidance is a soft warning in either case: you can accept a passphrase that fires it. The installer asks you to confirm, but does not block. You can paste, but most users type. A passphrase you cannot recall under stress is not a passphrase, it is a paperweight.
- Forge formats the target partition with LUKS2 using
cryptsetup luksFormat. The argon2id KDF parameters (1 GB memory cost, 4 iterations, 4 threads of parallelism) are forced by Forge per RFC 9106’s recommendations for memory-hard KDFs, rather than relying on whatever defaults the host’scryptsetuphappens to ship. The cipher — AES-256 in XTS mode — is not forced: it is cryptsetup’s own default, which Forge leaves in place. They sit between RFC 9106’s first-recommended (t=1, m=2 GB) and second-recommended (t=3, m=64 MB) profiles, calibrated to defeat GPU-accelerated brute-force without risking out-of-memory on 4 GB systems. - Forge writes
/etc/crypttabon the target system so the boot-time FDE initramfs knows what to unlock. The entry is namedcryptrootand references the partition byUUID=. - Forge writes
/etc/fstabwith the unlocked device-mapper node (/dev/mapper/cryptroot) as the root mount source, not the raw partition. - The kernel post-install hook bundles the FDE initramfs into the UKI. Because of the composition with Secure Boot (see below), the unlock prompt lives inside the same signed envelope as the kernel.
The passphrase you type is held only in memory while the install runs. It is piped to cryptsetup via stdin (never on the command line, never in argv), zeroized after use, and cleared from the installer’s state on both the success and failure paths. No copy is written to disk except in the LUKS header slot itself.
Before it writes anything, Forge shows you a summary of what it is about to do — the encryption choice and the queued MOK enrollment among them:

Two EXPERIMENTAL unlock methods compose with the passphrase: TPM2-sealed unlock (a sub-checkbox under the encryption opt-in) and FIDO2-token unlock (a separate sub-checkbox). Both add an additional LUKS key slot at install time alongside the passphrase slot; the passphrase is never replaced, only augmented. The TPM2 sub-checkbox is greyed out with a tooltip if your hardware does not expose a TPM (/dev/tpmrm0 absent) or if the live ISO is missing the static TPM2 tools. The FIDO2 sub-checkbox is always visible when LUKS is selected; the token does not need to be plugged in when the checkbox appears, only when enrollment runs (you will be prompted to plug it in and touch it).
EXPERIMENTAL: TPM2-sealed unlock
If you tick Unlock with TPM2 (EXPERIMENTAL), Forge seals a fresh 32-byte random key against the current measured-boot state, adds that key as an additional LUKS slot, and writes the sealed-blob triplet (primary.ctx, secret.pub, secret.priv) to the ESP under /intergen/tpm2/. The seal is bound to a PCR0 + PCR7 policy: PCR0 tracks the firmware (BIOS/UEFI code), and PCR7 tracks Secure Boot policy state (the db/dbx/KEK/MOK enrollment status). On normal boots the system unlocks automatically without prompting for a passphrase.
This is flagged EXPERIMENTAL because the failure modes are subtle. A firmware update changes PCR0; a signed kernel update that touches your shim/MOK state can change PCR7; a Secure Boot reconfiguration changes PCR7. Any of these invalidates the seal, and the boot falls through to the next configured method (FIDO2, if enrolled) and ultimately to the passphrase prompt. The cost of thinking you are TPM-unlocked and then suddenly being prompted is real, so this is held back from a general recommendation until it has more field validation.
The sealed blob written to the ESP is not a secret: without the specific TPM that performed the seal (and the same PCR0/PCR7 state), the blob is useless. You can copy it for backup if you want, but it cannot be unsealed on any other machine. The passphrase slot remains untouched; if the TPM rejects the unseal, the boot prompt asks for the passphrase exactly as in the passphrase-only flow.
EXPERIMENTAL: FIDO2-token unlock
If you tick Unlock with FIDO2 token (EXPERIMENTAL), Forge enrolls a credential on a FIDO2 security token (YubiKey, Solo, Nitrokey, and similar) plugged in during the install. Enrollment runs in two interactive steps:
- Generate credential:
fido2-cred -Mcreates a new credential on the token. You will be prompted to touch the token when it blinks. - Derive unlock key: a fresh 32-byte random nonce is generated,
fido2-assert -G --hmac-secretis invoked with that nonce as salt, and the token returns an HMAC output bound to the credential and the nonce. You will be prompted to touch the token a second time. The HMAC is added as an additional LUKS slot.
Forge writes cred_id and stored_nonce to the ESP under /intergen/fido2/. Neither file is a secret: without the physical token, the credential ID and the salt are useless. The relying-party ID is intergenos. At boot, the same fido2-assert call against the same nonce yields the same HMAC bytes, which unlock the slot.
This is flagged EXPERIMENTAL for the same family of reasons as the TPM2 path: a lost token, a firmware update on the token that rotates the underlying credential storage, or a token swap all invalidate the slot. The passphrase slot stays in the LUKS header for fallback.
The boot-time flow
When an encrypted InterGenOS system boots, the path looks like this:
Firmware (UEFI)
|
| Secure Boot signature verification on the UKI
v
Signed UKI (kernel + FDE initramfs + cmdline,
| bundled and signed by your local MOK)
|
v
Kernel hands off to /init
|
v
InterGenOS - encrypted root unlock
|
| read /etc/crypttab options for "tpm2" / "fido2"
| mount ESP read-only (by IGOS_ESP label, fallback scan)
v
Try TPM2 unlock (if enrolled + /dev/tpmrm0 present)
| unseal against PCR0+PCR7 policy
| -> pipe unsealed bytes to cryptsetup --key-file=-
| on any failure: fall through
v
Try FIDO2 unlock (if enrolled + tools available)
| wait up to 30s for the token to enumerate
| fido2-assert -G --hmac-secret against stored nonce
| -> pipe HMAC to cryptsetup --key-file=-
| on any failure: fall through
v
Passphrase prompt (always the final fallback)
Enter passphrase: _ (three attempts; the prompt runs
| inside the signed UKI envelope)
| cryptsetup open
v
/dev/mapper/cryptroot mounted
|
| switch_root
v
systemd PID 1 - normal boot continues
If neither TPM2 nor FIDO2 was enrolled, the chain skips straight to the passphrase prompt; the unlock path is identical to a passphrase-only install. The prompt you see in that case is plain text:
InterGenOS - encrypted root unlock
Enter passphrase for /dev/disk/by-uuid/<uuid>:

The prompt is set off by a bordered banner deliberately, so it is unmistakable in the wall of early-boot kernel messages rather than scrolling past unnoticed. Three wrong attempts drops you into a recovery shell with cryptsetup available. From there you can retry the unlock manually, inspect /etc/crypttab, or reboot.
The FDE initramfs is tiny: a static cryptsetup binary, a static busybox, the dm_crypt and ext4 kernel modules, and the storage drivers needed to see your disk. When TPM2 or FIDO2 unlock is enrolled, the initramfs also carries the static TPM2 / FIDO2 tools and the corresponding kernel modules (tpm/tpm_tis/tpm_crb for TPM2; usbhid/hid_generic for FIDO2). It does no logging to disk, no telemetry, and no network. Its only job is to attempt the unlock chain, mount the root filesystem, and hand off to systemd.
Debugging the unlock chain
The FDE init script emits journal-grep-friendly prefixes when running EXPERIMENTAL methods. From a recovery shell or after boot, you can correlate each attempt by searching for the prefix:
| Prefix | What it means |
|---|---|
[fde-init][EXPERIMENTAL TPM2] | TPM2 unlock attempt. Outcomes include skipping (no /dev/tpmrm0, no tools, or no sealed blob on ESP), attempting unlock via sealed key (PCR0+PCR7), tpm2_load failed, a tpm2_unseal | cryptsetup failure (PCR drift or broken seal), or unlock succeeded. |
[fde-init][EXPERIMENTAL FIDO2] | FIDO2 unlock attempt. Outcomes include skipping (no tools or no metadata), attempting unlock - plug your security token + touch when it blinks, no FIDO2 token detected within 30s, a specific diagnostic from the unlock pipeline, or unlock succeeded. |
[fde-init] (no EXPERIMENTAL suffix) | Passphrase prompt path, the recovery-shell drop, and root-mount errors. |
These messages go to the console during early boot. Once the system is up, they are also captured by systemd-journald and remain available via journalctl -b | grep fde-init.
Composition with Secure Boot
The encrypted-root and signed-boot stories are designed to compose. They do not interact at runtime except through the FDE initramfs being part of the signed UKI.
A UKI is a single signed file that bundles the kernel, the initramfs, and the kernel command-line. On a non-encrypted install, the UKI’s bundled initramfs is minimal or empty: the kernel-builtin storage drivers, a PARTUUID= rootspec, and rootwait are sufficient. On an encrypted install, the UKI’s bundled initramfs is the FDE initramfs: the same script that prompts you for the passphrase is part of the same signed envelope as the kernel.
The practical consequences:
- An attacker cannot substitute a fake unlock prompt that captures your passphrase, because the prompt code is inside the signed UKI. Tamper with it and Secure Boot refuses to load it.
- A kernel upgrade rebuilds the UKI with the new kernel and the same FDE initramfs, signed with your machine’s MOK. The unlock experience is identical across kernel upgrades.
- If UKI signing fails on a kernel upgrade (ESP full, MOK missing, signing-key error), the system falls back to GRUB loading the bare vmlinuz directly. On an encrypted install you would need to supply an initramfs to that recovery path manually; see Recovery below.
For the full signed-boot model, see Verified Boot.
Validated together
This composition is not just designed, it is validated. InterGenOS has been installed onto a LUKS2-encrypted target and booted to the desktop under enforced Secure Boot — the encrypted-root unlock prompt itself appearing under Secure Boot enforcement, the strictest combination of the two controls. The encrypted install runs every installer phase to completion, including the bootloader stage:

…and at boot, the signature gate and the encryption gate run in series with no conflict: the firmware verifies the signed chain (shim → GRUB → UKI), the signed UKI’s FDE initramfs prompts for your passphrase, and only then does the encrypted root mount.

You can confirm the full matrix yourself — mokutil --sb-state: enabled, the enrolled CN=InterGenOS Machine Owner Key, the LUKS2 argon2id root over an unencrypted ESP, sig_enforce=Y — on the Security Verification page.
What is and is not protected
Encrypted at rest:
- The entire root filesystem, including
/home,/var,/etc,/root, swap (if you put it on the encrypted volume), and any other partition you place inside the LUKS container. - Anything written to disk by any program once the system is running and the volume is unlocked.
Not encrypted:
- The ESP (the small
/boot/efipartition). The firmware reads this before any operating system runs, so it cannot be encrypted. Its integrity is protected by Secure Boot signature verification on the UKI, not by encryption. - The LUKS header itself is on disk and visible. It tells an observer that the partition is LUKS-encrypted and what cipher is in use. It does not reveal anything about the payload.
- A running system. Once you have entered your passphrase and the volume is unlocked, the master key lives in kernel memory and the filesystem is readable to any process with the right permissions. Encryption-at-rest does not replace the operating system’s process isolation, user permissions, or AppArmor confinement.
If your threat model includes someone with physical access to your machine while it is running, full disk encryption is not the control you are looking for. You want a screen lock or a powered-off machine.
Recovery
Most of the time you will never think about any of this. When something goes wrong, you have several recovery paths.
I forgot my passphrase
Your data is gone. There is no master key, no recovery-key escrow, no back door, and no service that will recover it. This is intentional: a recovery channel that could be used by you is a channel that could be used by an attacker.
If this happens, boot a live ISO and reinstall. Back up early and often is the only mitigation.
I want to add a second passphrase
LUKS2 supports up to eight key slots. From a running system, as root:
cryptsetup luksAddKey /dev/disk/by-uuid/<uuid>
You will be prompted for an existing passphrase (to unwrap the master key) and then for the new one. The new passphrase will work on the next boot.
I want to remove a key slot
cryptsetup luksRemoveKey /dev/disk/by-uuid/<uuid>
You will be prompted for the passphrase belonging to the slot you want to remove. The other slots are untouched.
I want to back up the LUKS header
The LUKS header is a small region at the start of the encrypted partition. If it is corrupted (disk-level damage at exactly the wrong offset, or an accidental dd to the wrong device), the payload becomes unrecoverable even with the correct passphrase, because the encryption metadata lives in the header.
Back it up to a separate medium:
cryptsetup luksHeaderBackup /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
Store the backup offline. Anyone with the backup file and your passphrase can decrypt your disk; treat it accordingly.
To restore:
cryptsetup luksHeaderRestore /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
UKI signing failed on a kernel upgrade and I cannot boot the encrypted root
The kernel post-install hook preserves the GRUB-loads-vmlinuz path as a recovery fallback. From the GRUB recovery entry, you can boot the bare vmlinuz, supply the FDE initramfs as an initrd= argument, and unlock as normal. Check /var/log/intergen-kernel-postinstall.log (and the troubleshooting table below) for the underlying signing-failure messages before retrying the post-install hook.
Boot drops me to the FDE recovery shell
Three failed passphrase attempts (or a missing /etc/crypttab, or a missing LUKS volume) drop you to a small busybox shell with cryptsetup available. From there you can:
- Retry the unlock manually:
cryptsetup open /dev/disk/by-uuid/<uuid> cryptroot, thenmount /dev/mapper/cryptroot /newroot, thenexec switch_root /newroot /sbin/init. - Reboot: type
reboot -f(the standardrebootcommand is not available pre-systemd). - Inspect the partition table:
ls /dev/disk/by-uuid/.
The recovery shell has no network access and no logs. It is intentionally minimal.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Boot prompt asks for passphrase but every attempt fails | Wrong passphrase, or keyboard layout differs at boot from inside the OS | Confirm the layout. The FDE initramfs uses the US-QWERTY layout by default; if your passphrase contains layout-sensitive characters, type the QWERTY equivalents. |
| Boot drops straight to the FDE recovery shell with “no LUKS volume specified” | /etc/crypttab was not written, or the install did not complete the encryption stage | From the recovery shell, inspect /etc/crypttab with cat /etc/crypttab. If empty, the install did not enable encryption; boot a live ISO and reinstall. |
| Boot drops to the FDE recovery shell with “LUKS volume not found after 30s wait” | The disk did not enumerate in time (failing drive, USB-attached storage, slow RAID controller init) | From the recovery shell, run ls /dev/disk/by-uuid/ to see what is visible. If the volume appears, retry cryptsetup open manually. If not, the disk is the problem. |
| TPM2-sealed unlock falls through to passphrase | PCR0 or PCR7 has changed (firmware update, Secure Boot reconfiguration, shim/MOK update) | Enter the passphrase to boot. The system continues to unlock normally with the passphrase slot; re-enrolling TPM2 against the new PCR state restores automatic unlock. Check `journalctl -b |
| FIDO2 unlock does not detect the token | Token not plugged in early enough, or token battery dead | The FDE initramfs waits up to 30 seconds for the device to enumerate. Plug the token in before boot. For battery-dead tokens, fall back to the passphrase. Check `journalctl -b |
cryptsetup luksAddKey says “No key available with this passphrase” | The passphrase you entered does not match any existing slot | Try other passphrases you have set. If none work, you are in the forgot-passphrase case. |
| The ESP filled up on a kernel upgrade and the new UKI was not written | UKI generation logs ESP-full and skips; the previous kernel’s UKI remains the default | Use pkm to remove the old kernel package to free space, then re-run the post-install hook for the current kernel. See /var/log/intergen-kernel-postinstall.log for the underlying messages. |
Further reading
- Verified Boot — the signed-boot story that wraps the encrypted-unlock story.
- Forge Installer Guide — the install walkthrough that reaches the encryption opt-in step in context.
- Recovery — broader recovery procedures for an installed system.
- FAQ — common questions, including encryption.
Verified Boot & Secure Boot
InterGenOS builds a fully signed boot chain and signs every kernel image it produces. Being precise about what that buys you matters more than a reassuring headline, so this page is exact about what is signed versus what is enforced on the hardware InterGenOS ships on today.
Security is not first. It is only — and “only” includes being honest about the current enforcement posture rather than implying a guarantee the shipped configuration does not yet provide.
The 30-second version
- InterGenOS produces a signed boot chain: a Microsoft-signed shim (Fedora’s pre-signed shim) → InterGenOS GRUB → a signed Unified Kernel Image (UKI). Those artifacts are built, signed, and shipped.
- On the current target hardware (the HP fleet), UEFI Secure Boot is left disabled by default, and no Machine Owner Key (MOK) is enrolled. The signatures are present and verifiable, but firmware does not enforce them on a default install today. Secure Boot has been validated end to end (in a UEFI VM that enforces it) — with an enrolled MOK the chain boots under enforced Secure Boot, including with full-disk encryption active (a LUKS2-encrypted root and enforced Secure Boot together, the strictest combination). Now that GRUB carries its SBAT revocation record, the chain Secure-Boots with no hand-patching. The default fleet install still ships it off — signed, not yet firmware-enforced — and turning it on is the one-time MOK enrollment described below.
- The release signing key never leaves InterGenOS hardware. The live ISO and install-mode images are signed offline by a release subkey on a hardware token; that key never touches your machine.
- The live ISO’s read-only system image is sealed with dm-verity. The installed root filesystem is an ordinary
ext4volume (referenced byPARTUUID, or unlocked as/dev/mapper/cryptrooton an encrypted install), not a dm-verity device. - Every kernel you install after the original ISO is rebuilt into a UKI and signed with a per-machine MOK, so the signing machinery is in place for when Secure Boot is enabled.
- If a kernel signing step fails, GRUB still offers a known-good fallback so you never end up with a system that cannot boot.
What is signed, and what is enforced
It is worth separating two things that are easy to conflate:
- Signed — the artifact carries a cryptographic signature you (or the firmware) can verify. InterGenOS signs the shim chain, GRUB, and every kernel UKI.
- Enforced — the firmware refuses to run anything whose signature does not validate. Enforcement requires UEFI Secure Boot to be on and the relevant key (Microsoft’s CA via shim, plus your MOK) to be trusted.
On a default install of the current fleet, the chain is signed but not firmware-enforced, because Secure Boot is disabled and no MOK is enrolled. What that gives you today:
- Verifiable install media. The live ISO and install images are signed offline; you can verify them before you ever install.
- A sealed live image. dm-verity over the live ISO’s read-only squashfs means a tampered install medium cannot present itself as genuine.
- A signing path that is ready to enforce. Because every installed kernel is already built into a signed UKI, enabling Secure Boot on capable hardware (and enrolling the MOK) turns the existing signatures into enforced ones without re-architecting anything.
What it does not give you on a default install is a hardware-rooted guarantee that only signed code boots — that is what enabling Secure Boot adds.
The boot chain
flowchart TB
FW["Firmware (UEFI)"] -->|" trusts Microsoft 3rd-party CA <br/> (only when Secure Boot is ON) "| SHIM["Microsoft-signed shim<br/>the live ISO reuses Fedora's pre-signed shim"]
SHIM -->|" trusts the InterGenOS vendor cert <br/> loaded as your MOK "| GRUB["InterGenOS GRUB<br/>release-key-signed on the ISO + install media,<br/>MOK-signed for the GRUB written to your disk"]
GRUB -->|" verifies the UKI signature "| UKI["InterGenOS UKI<br/>vmlinuz + initramfs + cmdline, signed as one Authenticode binary"]
UKI -->|" kernel handoff "| US["InterGenOS userspace"]
A Unified Kernel Image (UKI) is a single signed file that bundles the kernel, the initramfs, and the kernel command line. Signing the UKI envelope signs all three at once; nothing inside can be swapped without breaking the signature. The chain above is enforced from the firmware downward only when Secure Boot is enabled; with it disabled, the same artifacts are present but the firmware does not gate on them.
The live ISO and install media use UKIs signed by the InterGenOS release subkey on an offline signing workstation. Once you install to disk, every kernel you install or upgrade is rebuilt into a UKI on your machine and signed with your machine’s MOK.
The GRUB menu
At boot, GRUB presents the default kernel entry along with retained older kernels and a recovery entry. GRUB is itself signed and is configured to verify the UKIs it loads.
How the live system image is sealed (dm-verity)
dm-verity applies to the live ISO, not to the installed root filesystem. Keeping that distinction straight matters.
When a release is assembled, the read-only system image (a squashfs) is built and a verified-integrity hash tree (dm-verity) is generated over it. The root hash of that tree is written into the signed kernel command line carried inside the live image’s UKI. Because the UKI signature covers the command line, the root hash is itself signed. The result is that the live medium cannot be tampered with and still present a valid signature.
When you install to disk, Forge lays down a conventional ext4 root filesystem, and the installed system boots with root=PARTUUID=… (or root=/dev/mapper/cryptroot on an encrypted install, unlocked by the FDE initramfs first). The installed root is not a dm-verity device; its integrity rests on the signed UKI (when Secure Boot is enforced) and on pkm’s per-file SHA-256 records, which pkm verify can re-check at any time.
Signing only appends a signature; it never alters the payload. Before each signing, the inputs are re-staged and their root hashes are re-checked against the freshly built system image, and the signed outputs are verified afterward.
What is a MOK?
A Machine Owner Key is a per-machine signing key, generated on your own machine, that firmware can be made to trust by enrolling it via MokManager. On a default (Secure-Boot-off) install it is generated and used to sign your UKIs; enrolling it via MokManager is what makes the firmware enforce it — see Enabling Secure Boot for the validated enrollment flow.
It exists for two reasons:
- Your machine signs the kernels you install. When you install a new kernel, InterGenOS rebuilds the UKI and signs it with your MOK. The InterGenOS release key never sees the kernels you install; it only signs the live ISO and install media that ship from InterGenOS.
- You can trust your own third-party drivers. If you build out-of-tree modules (for example, proprietary GPU drivers via DKMS), they can be signed by your MOK so that, on a Secure Boot system, they load without disabling enforcement.
The MOK is yours. It lives under /var/lib/intergen/mok/ on the installed system (mok.key, mok.crt, and mok.der). If you reinstall, Forge generates a fresh MOK.
The Forge install flow
When you run the Forge installer (TUI or GUI), the bootloader stage does the following without asking further questions:
- Generates a per-machine MOK keypair (RSA-2048, matching the kernel module-signing default):
/var/lib/intergen/mok/mok.key— the private key/var/lib/intergen/mok/mok.crt— a PEM-format X.509 cert, used bysbsignfor UKI signing/var/lib/intergen/mok/mok.der— a DER-format X.509 cert, the binary form MokManager wants for enrollment
- Ensures the UKI tooling is present —
ukify(from the systemd tooling) andsbsign(fromsbsigntool) are ordinary installed packages, so the kernel package’s post-install hook can build and sign UKIs at install or upgrade time. - Installs an initial UKI built from the kernel the installer just dropped on the system, signed with the freshly generated MOK, at
/boot/efi/EFI/Linux/intergenos-<kernel-version>.efi. - Configures a recovery boot entry that loads the bare vmlinuz with no UKI envelope, as a fallback path if a UKI ever fails to sign or boot.
On hardware where you intend to run with Secure Boot enabled, you additionally enroll the MOK via MokManager (below). On the default fleet configuration, Secure Boot is left off and that enrollment step is skipped.
For the full installer walkthrough, see the Forge installer guide.
Enabling Secure Boot
Secure Boot has been validated on InterGenOS end to end, in a UEFI virtual machine that enforces it: with the boot chain complete, the system boots under enforced Secure Boot, anchored to your own Machine Owner Key, with the kernel in integrity lockdown and refusing unsigned modules. It has been validated in the strictest configuration as well — with full-disk encryption active, so the LUKS unlock prompt itself appears under enforced Secure Boot, the encrypted root and the signature gate working together. You can see that proof — mokutil --sb-state: enabled, the enrolled CN=InterGenOS Machine Owner Key, sig_enforce=Y, a LUKS2-encrypted root — on the Security Verification page.
Two practical notes on availability:
- The chain Secure-Boots natively. The Microsoft-signed shim InterGenOS reuses requires every component it loads to carry an SBAT revocation record. The UKI already carried one; GRUB now carries its SBAT record too, so the signed chain boots under enforced Secure Boot with no hand-patching. That SBAT gate is exactly what makes Secure Boot mean something: a GRUB that predates the record is refused at the shim stage rather than silently allowed — fail-closed enforcement you can watch happen, not just a checkbox. (Some firmware, especially on OEM laptops, makes the Secure Boot toggle read-only outside Setup Mode; InterGenOS runs fine with it off, and enabling it is optional.)
- Enabling it is a one-time enrollment. Forge stages your MOK and a one-time enrollment password during install (with Secure Boot off). On the next boot the firmware runs MokManager so you can enroll that key; once enrolled, you turn Secure Boot on in firmware and the chain validates.
Enrolling your key with MokManager
MokManager is a small blue-on-black firmware utility. The sequence:
-
Perform MOK management → Enroll MOK.

-
View the key, then Continue — review the certificate about to be trusted; its subject reads
CN=InterGenOS Machine Owner Key.
-
Enroll the key(s)? → Yes, then enter the one-time password Forge set during install.

-
Reboot. The menu returns with your key enrolled — choose Reboot.

After enrollment, with Secure Boot enabled in firmware, UKIs signed with your key load without further prompts, and unsigned or wrong-key images are refused. Until you enroll and enable Secure Boot, the system boots the signed UKI without firmware enforcement.
Proof: booted under enforced Secure Boot
This is the whole chain working under enforced Secure Boot — the branded login, reached only after the shim verified GRUB, GRUB verified the signed UKI, and (on an encrypted install) the LUKS prompt unlocked the root, with the firmware refusing anything unsigned at every step:

Enforcement here is real, not nominal. A GRUB that predates the SBAT record is rejected by the shim under enforced Secure Boot — the firmware refuses to run it rather than booting it anyway:

Same firmware, same enforcement, two outcomes: an earlier GRUB without the SBAT record is correctly refused (a 0x1A Security Violation); the current chain, with GRUB carrying its SBAT record and signed by your MOK, is trusted and boots. That difference is what a working Secure Boot looks like — it has to be able to say no.
The same chain boots encrypted or plain
Secure Boot was validated on both install types, because the signed boot path is the same either way: GRUB reads its MOK-signed, SBAT-carrying image from the unencrypted ESP regardless of what the root filesystem is. The only difference is the disk topology — an encrypted install unlocks a LUKS2 root behind the passphrase prompt; a plain install mounts an ordinary ext4 root directly. Both reach the desktop under enforced Secure Boot with the identical green matrix (sig_enforce=Y, integrity lockdown, a clean pkm verify --all).

A plain (unencrypted) install reaching its first-run welcome under enforced Secure Boot — captured in a VM so you can reproduce it yourself. The encrypted leg is identical at this point; only the root volume differs.
Kernel install and upgrade
When you install or upgrade a kernel via the package manager (or any package whose post-install hook touches the kernel), the kernel package’s post_install hook does the following on your machine, with no key material from the InterGenOS release infrastructure:
- Reads the kernel, the standard initramfs (and an additional full-disk-encryption initramfs if your system is LUKS-encrypted — see below), and the canonical command line for your system.
- Runs
ukify buildto bundle them into a single UKI in the systemd-stub envelope. - Runs
sbsign --key /var/lib/intergen/mok/mok.key --cert /var/lib/intergen/mok/mok.crtto sign the UKI. (sbsignreads PEM-format certificates; the.derform generated alongside is for MokManager enrollment only, not signing.) - Writes the signed UKI to
/boot/efi/EFI/Linux/intergenos-<kernel-version>.efi. - Updates the GRUB menu so the new kernel is the default boot entry.
- Retains a configurable number of old kernels (default: 2) and their UKIs as fallback entries.
The InterGenOS release signing key, used on the offline workstation, is never asked. It physically does not exist on your machine.
If signing fails (corrupt key file, full ESP, and so on), the hook falls back to writing the kernel and initramfs out separately for GRUB to load directly. You do not end up with a system that has a half-installed kernel.
ESP sizing
Because every kernel you install becomes a UKI in /boot/efi, the ESP needs headroom for several generations of kernel. A typical UKI is 80–150 MB depending on the initramfs payload. Forge creates a fixed 1 GiB EFI System Partition during partitioning, which leaves room for several kernels plus their fallbacks.
If your ESP fills up, kernel install fails. The hook prints a clear message; you can clean up old kernels by removing the older kernel package with the package manager to free space.
Composition with LUKS encryption
If you choose the encrypted-install option, Forge installs a small full-disk-encryption initramfs alongside the kernel: busybox plus cryptsetup, just enough to prompt for your LUKS passphrase and unlock the root volume before the kernel hands off to userspace.
That FDE initramfs is bundled into the same UKI as the kernel. The UKI signature covers it, just as it covers the kernel and the command line. There is one signature; verifying the UKI signature verifies the entire boot path including the LUKS unlock prompt.
If you opt for TPM2-sealed unlock (an experimental v1.0 feature), the same UKI envelope holds the additional bits that talk to your TPM. The unlock path is still inside the signed envelope.
For non-encrypted installs, the UKI’s bundled initramfs is minimal — typically only CPU microcode — because all storage and filesystem drivers are built into the kernel.
See Disk encryption for the full LUKS setup walkthrough.
Recovery
Most of the time you will never think about any of this. When something goes wrong, you have several recovery paths.
“A new kernel won’t boot”
GRUB retains the previous kernels and a bare-vmlinuz recovery entry. Pick a known-good entry from the GRUB menu to get back into a working system, then reinstall or roll back the kernel package with pkm.
“I need to regenerate the MOK”
The MOK material lives under /var/lib/intergen/mok/. Reinstalling with Forge generates a fresh MOK; a subsequent kernel install or upgrade rebuilds the UKIs with it. (There is no separate recovery wrapper command — UKI signing is handled entirely by the kernel package’s post-install hook.)
“I want to run an unsigned kernel for testing”
On a default install (Secure Boot off) nothing stops you, but the supported path is to build your kernel, sign it with your MOK using sbsign, and install it through the package manager like everything else, so the machinery stays consistent for the day you enable Secure Boot.
See Recovery for the broader recovery toolkit.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| New kernel installs but won’t boot | UKI signing failed, or (with Secure Boot on) the MOK is not enrolled | Boot the previous kernel or recovery entry from the GRUB menu; inspect /var/log/intergen-kernel-postinstall.log. |
| GRUB menu shows only the recovery entry, no UKI entries | UKI signing has been failing silently | Inspect /var/log/intergen-kernel-postinstall.log. A full ESP and a missing MOK key file are the two common causes. |
ukify or sbsign is missing | The UKI tooling packages were removed | Reinstall the systemd tooling and sbsigntool with the package manager and re-run the kernel post-install hook for the current kernel. |
| Secure Boot toggle in firmware is greyed out | Some firmware (especially OEM laptops) makes Secure Boot read-only outside Setup Mode | See your hardware vendor’s documentation. InterGenOS runs fine with Secure Boot off; enabling it is optional. |
Where this fits in the build
The signed boot chain is not bolted on at the end. The candidate build runs its phases with the boot-chain artifacts produced and sealed in the late stages: the bootloader phase, the image and squashfs phases, and the UKI/verity phase that bundles and integrity-seals the kernel images before the ISO is assembled. The build halts once for a hardware-token signing step; one signing covers the bootloader and all of the unified kernel images.
A candidate is never trusted on the strength of a clean build alone. Pre-install evaluation boots the ISO on real hardware and examines the signed chain and the live image’s integrity before any install is attempted. Verification you can check yourself is the standard the boot chain is held to.
This is the v1.0-dev (build id v1.0-dev1) boot model. The desktop that ships today is GNOME 49 on Wayland.
Per-Device Install Notes
This page collects hardware-specific notes for installing InterGenOS on named devices and common device classes. It exists because firmware behavior, not InterGenOS itself, is the usual source of install friction: how a given board exposes Secure Boot, how it stages a Machine Owner Key (MOK), and what its UEFI menus call things vary by vendor.
InterGenOS builds a fully signed boot chain, but it does not require UEFI Secure Boot — the default fleet install runs with Secure Boot off. The notes below help you get a specific machine installed, and, if you want firmware-enforced verification, into a state where MOK enrollment works.
If your exact device is not listed, the general flow in Verified Boot & Secure Boot and the FORGE Installation Guide applies unchanged. The device-class notes here are additions, not replacements.
Before you start: what every device needs
Regardless of make and model, a successful install needs the firmware in this state:
- UEFI mode, not legacy/CSM/BIOS-compatibility boot. This is the one hard requirement.
- The signed shim boots either way. InterGenOS boots through a Microsoft-signed shim — Fedora’s pre-signed shim, which the firmware trusts via the Microsoft third-party CA — so most off-the-shelf machines boot the live ISO without any firmware change — whether Secure Boot is on or off.
- (Optional) the ability to enroll a MOK, only if you want Secure Boot enforcement. FORGE generates a per-machine MOK during install; on hardware where you enable Secure Boot, MokManager enrolls it at the next reboot using a single-use password. The default fleet install leaves Secure Boot off and skips this step.
You do not need Setup Mode for normal operation.
OEM laptops with a greyed-out Secure Boot toggle
Some firmware, especially on OEM laptops, makes the Secure Boot setting read-only unless the machine is in Setup Mode. This shows up as a greyed-out Secure Boot toggle in the firmware menu.
You generally do not need to change anything: InterGenOS installs and runs whether Secure Boot is on or off, so a greyed-out toggle in either state is fine. If you want Secure Boot enforcement and the toggle is greyed out in a disabled state, consult your hardware vendor’s documentation for entering Setup Mode. InterGenOS does not require Setup Mode itself.
Machines where MokManager does not appear
On the first boot after install, the firmware should detect the pending MOK enrollment request and run MokManager (a small blue-text-on-black utility) before continuing. If MokManager never appears and a freshly installed kernel will not boot, the system falls through to a recovery boot entry that loads the bare kernel directly. From there you can re-enroll or regenerate the MOK. The full symptom-to-fix walkthrough is in Verified Boot & Secure Boot.
The recovery boot entry exists precisely so that a missed enrollment never leaves you with an unbootable machine.
UEFI System Partition (ESP) sizing
This is hardware-adjacent rather than device-specific, and it matters most on machines with small or pre-partitioned ESPs. Every kernel you install becomes a Unified Kernel Image (UKI) in the ESP, and a typical UKI is 80–150 MB. FORGE creates a fixed 1 GiB ESP during partitioning, leaving room for several kernel generations.
If you are installing alongside an existing OS and reusing its small ESP, expect kernel installs to fail once it fills. The cleaner path is to let FORGE create an ESP at its minimum size or larger.
Encrypted installs
The encrypted-install option works the same across devices: FORGE folds a small full-disk-encryption initramfs (the LUKS unlock prompt) into the same signed UKI as the kernel, so one signature covers the entire boot path including the unlock step. See Disk Encryption & LUKS for the full flow.
TPM2-sealed unlock is an experimental v1.0 feature. If your device has a TPM2 and you opt into sealed unlock, the bits that talk to the TPM live inside the same signed UKI envelope. The TPM is not a way to skip Secure Boot verification.
Graphics and out-of-tree drivers
InterGenOS ships GNOME 49 on Wayland today. Open-source graphics drivers built into the signed kernel need no extra steps.
If your device needs out-of-tree modules (for example, proprietary GPU drivers via DKMS) and you are running with Secure Boot enabled, the firmware will not load them unsigned. Sign them with your own MOK and install them through the standard package-manager flow, the same mechanism that signs your kernels. See the out-of-tree-module discussion in Verified Boot & Secure Boot and the Per-GPU Driver Notes.
Reporting a device
If you install InterGenOS on a device not covered here and hit a firmware-specific snag (or confirm a clean install), that information is worth capturing so the next person with the same hardware has a head start. See the FAQ for where to take questions and reports.
See also
- Verified Boot & Secure Boot — the full boot-chain model, MOK enrollment screens, kernel signing, and recovery paths.
- FORGE Installation Guide — the end-to-end installer flow.
- Disk Encryption & LUKS — encrypted-install details.
- Recovery & Reinstall — recovering a machine that will not boot.
- FAQ — common install questions.
Installing in a Virtual Machine
A virtual machine is the fastest way to try InterGenOS — to see the boot chain, the FORGE installer, and the desktop — without touching your hardware. The install is the same verified FORGE flow you would run on bare metal: the integrity gate still checks every package against the signed release manifest before anything is written to the virtual disk. A VM changes where the disk lives, not whether the system is trustable.
InterGenOS is a built-from-source Linux distribution where security is not first. It is only. That holds in a VM exactly as it does on metal — a machine you understand, can modify, and can trust.
The one setting people miss: InterGenOS is UEFI-only. It boots through a signed
systemd-stubUnified Kernel Image, and there is no legacy-BIOS path. You must enable EFI in the VM’s firmware settings or it will not boot. The per-hypervisor sections below call out exactly where.
This guide covers VirtualBox and VMware — a full FORGE install is verified on both.
VirtualBox
Verified on VirtualBox 7.x. The InterGenOS live ISO boots, the graphical FORGE installer renders, and a full install completes out of the box with the settings below.
Create the VM
In the VirtualBox New wizard and the machine’s Settings:
- Type / Version: Linux / Other Linux (64-bit).
- Firmware — EFI is required. Open Settings → System → Motherboard and tick Enable EFI (special OSes only). InterGenOS will not boot in legacy BIOS/CSM mode — the boot chain is a signed UKI with no BIOS fallback.
- Memory: at least 4 GB; 8 GB recommended for a comfortable live GNOME session and installer.
- Processors: 2 cores or more.
- Disk: a 30 GB or larger VDI is plenty (the live squashfs is roughly 10.7 GB). A SATA-attached disk works fine.
- Optical drive: attach the InterGenOS ISO as the virtual optical drive, and set the boot order optical first so the installer media boots.

A known-good VirtualBox display configuration — System → Motherboard: UEFI enabled (Secure Boot off); Display → Screen: VMSVGA controller, 256 MB video memory, 3D Acceleration on. This is the VMSVGA alternative; for the native auto-resizing path, pick the VBoxSVGA controller instead — see Graphics, below.
Graphics — important
VirtualBox offers two display controllers, and InterGenOS now ships in-tree kernel drivers for both. Pick one of these:
- VBoxSVGA +
vboxvideo— the native path. InterGenOS compiles VirtualBox’s own native display drivervboxvideo(CONFIG_DRM_VBOXVIDEO=y) directly into the kernel. Select the VBoxSVGA graphics controller under Settings → Display → Screen and the guest bindsvboxvideo: it exposes a proper EDID and auto-resizes to the VirtualBox window with no manual resolution step — and with nothing out-of-tree. This is the native VirtualBox path; if you want resize-to-window behaviour, use it. - VMSVGA +
vmwgfx— the alternative. VirtualBox’s default controller is VMSVGA, which the kernel’svmwgfxdriver binds. That combination works — the installer and desktop render — butvmwgfxis VMware’s driver, not VirtualBox’s: on VirtualBox it produces journal noise and does not auto-resize (on a 4K host the guest can render at full 4K, so the window shows only the top-left corner). If you stay on VMSVGA, configure it deliberately:- Video Memory: raise VRAM to at least 128 MB (256 MB on a 4K host) under Settings → Display → Screen. The 16 MB default is too low.
- 3D Acceleration: turn it ON — it cuts the
vmwgfxlog noise by roughly two orders of magnitude and gives a smoother session. - Set the resolution in the guest: because VMSVGA does not auto-resize, after first boot open GNOME Settings → Displays and pick a fixed resolution such as 1920×1080. The choice persists per user, and it avoids the oversized-render / clipped-window effect on a 4K monitor.
Do not install Oracle’s VirtualBox Guest Additions. They are a proprietary vendor blob that builds out-of-tree kernel modules, and InterGenOS’s locked-down kernel enforces module signatures — it rejects unsigned out-of-tree modules by design. You do not need them: the in-tree drivers — vboxvideo (display), plus vboxguest and vboxsf (shared folders), all compiled in — provide guest integration with nothing out-of-tree.
(The settings screenshot under “Create the VM,” above, shows the VMSVGA alternative — VMSVGA, 256 MB, 3D Acceleration on. For the native path, simply pick the VBoxSVGA controller instead; vboxvideo handles auto-resize.)
Secure Boot in VirtualBox
VirtualBox’s EFI firmware boots InterGenOS with Secure Boot disabled (Setup Mode) out of the box, and the install works fully without it — kernel integrity lockdown stays engaged regardless of Secure Boot state, so you are not running an unprotected kernel.
The full signed-boot chain (shim → GRUB → UKI) is provisioned at install regardless of the firmware’s Secure Boot state. Turning Secure Boot enforcement on is a one-time Machine Owner Key (MOK) enrollment performed at first boot — that flow is now validated end to end and walked through in Verified Boot & Secure Boot. It is not required for a working install, and measured boot additionally relies on a TPM, which VirtualBox does not provide by default.
Networking
The VirtualBox default NAT adapter works out of the box. The live installer and pkm have outbound network access — DNS resolution and a default route are present with no extra configuration. You do not need to change networking to install.
What you see when it boots
- The themed GRUB boot menu appears — Try InterGenOS, Install InterGenOS (Graphical), Install InterGenOS (Text), and Advanced options.
- The default entry boots the graphical FORGE installer: a GNOME greeter, then the FORGE wizard (Identity, Region, Disk, packages, and so on).
- You reach the “Review your choices” screen before anything is committed. Nothing is written to the virtual disk until you click Install.

The boot menu is identical in a VM. Select “Install InterGenOS (Graphical)” to follow the installer guide.
From here, the wizard is the same screen-by-screen flow documented in the FORGE Installation Guide — follow it through to first login.

FORGE running inside VirtualBox — the VirtualBox window frame is visible around it. Here it is at Phase 1 of 13, the integrity gate that validates the live ISO and package availability before any disk write.
A note on journal warnings
In a VM’s live (“Try InterGenOS”) session, vmwgfx can flood the system journal with a cosmetic framebuffer error — failed to create vmw_framebuffer: -22. The display works regardless — the desktop renders fully; this is log noise, not a boot or display failure. It appears in the live session on both VirtualBox and VMware (it is not specific to either), and it has not been observed on an installed system — even when the installed desktop is driven to 4K. The trigger of the live-session flood is still being investigated; the display is unaffected either way. On VirtualBox you may also see “unsupported hypervisor” messages — those are VirtualBox-specific, because vmwgfx is VMware’s driver and VirtualBox’s SVGA emulation is not its native target. Enabling 3D Acceleration reduces the VirtualBox volume, and the in-tree vboxvideo driver — now shipping; select the VBoxSVGA controller — removes it on VirtualBox entirely (it does not use vmwgfx).
VMware
InterGenOS ships the VMware paravirtual guest drivers built into the kernel — vmwgfx (display), VMWARE_PVSCSI (paravirtual disk), and VMXNET3 (paravirtual network), all compiled in (=y). A full FORGE install on VMware Workstation Pro is verified end to end: InterGenOS boots, the graphical installer deploys every package, the signed boot chain is provisioned (MOK-signed UKI, shim/GRUB, UEFI boot entry), and you reach a healthy GNOME desktop with the local assistant running. Create the VM with EFI firmware enabled, the VMware SVGA display, and a NAT network adapter. (VMware Workstation Pro is the current product and is free for personal use; the older Workstation Player has been discontinued.)
Secure Boot has been validated end to end: with the MOK enrolled, InterGenOS boots under enforced Secure Boot through the signed shim → GRUB → UKI chain, with the kernel in integrity lockdown and refusing unsigned modules — the single-frame proof is on the Security Verification page. The installed GRUB now carries the SBAT record the signed shim requires, so the chain Secure-Boots natively — the earlier 0x1A Security Violation when enabling Secure Boot is resolved. Enabling enforcement is a one-time Machine Owner Key (MOK) enrollment at first boot (walked through in Verified Boot & Secure Boot); it is not required for a working install, and measured boot additionally relies on a TPM, which VMware does not provide by default.

The branded boot menu inside VMware Workstation Pro — the VMware window frame confirms it is running as a guest.

The greeter inside VMware, correctly scaled out of the box. VMware’s SVGA exposes a proper EDID, so GNOME derives the display DPI and scales the session on its own — no manual resolution step, unlike the VirtualBox case above.
For guest integration (dynamic resize, time sync, graceful shutdown), the InterGenOS path is open-vm-tools — the open-source VMware guest tools (vmtoolsd), built from source — not the bundled “VMware Tools” installer. That bundled installer is a vendor package that builds out-of-tree modules the locked-down kernel rejects (the VMware analog of VirtualBox’s Guest Additions).
On the display log, see the note above: the cosmetic vmwgfx -22 flood appears in the live session (on both hypervisors), was not observed on the installed system, and does not affect the display.
See also
- FORGE Installation Guide — the screen-by-screen installer walkthrough the VM boots into.
- Verified Boot & Secure Boot — the MOK and signed-boot model, including enrolling Secure Boot.
- Per-Device Install Notes — bare-metal hardware guidance.
- Troubleshooting: Boot & Graphical Issues — if the VM does not reach the installer.
Recovery & Reinstall
This page covers the paths back to a working system when something goes wrong: a boot that drops to a recovery shell, a kernel upgrade that breaks the signed-boot chain, a corrupted LUKS header, or a forgotten passphrase. It also covers when the right answer is simply to reinstall.
InterGenOS is built to be a machine you understand, can modify, and can trust. That extends to recovery: the paths are deliberately minimal, transparent, and free of any hidden back channel.
Most of the time you will never need this page. When you do, work top to bottom — the paths are ordered roughly from “least invasive” to “reinstall.”
Before you start: back up
The single most important recovery measure is a backup you made before the failure. InterGenOS holds no escrow, no master key, and no remote recovery service. If your system uses full-disk encryption and you lose the passphrase, the data is unrecoverable by design. Back up early and often.
If you use full-disk encryption, also back up the LUKS header to a separate, offline medium. A damaged header makes the payload unrecoverable even with the correct passphrase. See Back up and restore the LUKS header below.
Reinstall with Forge
A clean reinstall is the most reliable recovery path when the installed system is too damaged to repair in place, or when you have decided to start fresh.
Boot the InterGenOS live ISO and run Forge, the installer. Forge offers two frontends that behave identically:
- A GTK4 / libadwaita GUI, a multi-screen wizard (welcome, keyboard and locale, disk, user, packages, confirm, progress, done).
- A
dialog-based TUI, suited to SSH-based installs, headless machines, or keyboard-driven setups.
Before any disk write, Forge runs a supply-chain integrity gate: it computes the SHA-256 hash of every package archive to be deployed and verifies each against the cryptographically signed release manifest. A mismatch halts the install before partitioning begins. Overriding that halt requires typing an override phrase in full — paste, drag-and-drop, and the right-click menu are disabled on that field, so the override is a deliberate, conscious act.
A reinstall wipes the target disk. Anything not backed up is lost. For the full walkthrough, see the FORGE Installation Guide.
Recovering an encrypted system
If your system uses LUKS2 full-disk encryption, the recovery paths below apply. For the full encryption model, see Disk Encryption & LUKS.
Boot drops to the FDE recovery shell
Three failed passphrase attempts — or a missing /etc/crypttab, or a LUKS volume that does not appear — drop you into a minimal busybox recovery shell with cryptsetup available. This shell has no network and writes no logs; it is intentionally bare.
From the recovery shell you can:
-
Retry the unlock manually, then continue the boot:
cryptsetup open /dev/disk/by-uuid/<uuid> cryptroot mount /dev/mapper/cryptroot /newroot exec switch_root /newroot /sbin/init -
Inspect what the disk exposes:
ls /dev/disk/by-uuid/ -
Inspect the unlock config:
cat /etc/crypttab -
Reboot:
reboot -f(the standardrebootis not available this early in boot)
If /etc/crypttab is empty, encryption was never enabled on this install and the recovery shell is a symptom of a different problem — boot a live ISO and reinstall.
Every passphrase attempt fails
The most common cause is a keyboard-layout mismatch. The FDE unlock prompt uses the US-QWERTY layout by default. If your passphrase contains layout-sensitive characters, type the QWERTY-position equivalents. If the layout is correct and the passphrase still fails, see the forgot-passphrase path.
“LUKS volume not found after 30s wait”
The disk did not enumerate in time. Causes include a failing drive, USB-attached storage, or a slow-initializing RAID controller. From the recovery shell, run ls /dev/disk/by-uuid/ to see what is visible. If the volume appears, retry cryptsetup open manually. If it does not appear, the disk itself is the problem.
EXPERIMENTAL unlock fell through to the passphrase prompt
TPM2-sealed unlock and FIDO2-token unlock are EXPERIMENTAL v1.0 sub-options. Both compose alongside the passphrase slot — the passphrase is never replaced, so it is always the fallback.
-
TPM2 fell through: a measured-boot value changed — typically PCR0 (firmware update) or PCR7 (Secure Boot reconfiguration, or a shim/MOK update). Enter the passphrase to boot. Re-enrolling TPM2 against the new state restores automatic unlock. Diagnose with:
journalctl -b | grep '\[EXPERIMENTAL TPM2\]' -
FIDO2 did not detect the token: plug the token in before boot — the initramfs waits up to 30 seconds for it to enumerate. A dead token battery means falling back to the passphrase. Diagnose with:
journalctl -b | grep '\[EXPERIMENTAL FIDO2\]'
More broadly, all FDE-unlock messages carry a [fde-init] prefix and can be reviewed post-boot with journalctl -b | grep fde-init.
I forgot my passphrase
Your data is gone. There is no master key, no recovery-key escrow, and no back door. This is intentional: a recovery channel that the project could use is a channel an attacker could use.
Boot a live ISO and reinstall. A backup made earlier is the only mitigation.
Add or remove a key slot
LUKS2 supports up to eight key slots. From a running, unlocked system, as root:
# Add a second passphrase (prompts for an existing one first)
cryptsetup luksAddKey /dev/disk/by-uuid/<uuid>
# Remove a slot (prompts for the passphrase belonging to that slot)
cryptsetup luksRemoveKey /dev/disk/by-uuid/<uuid>
Adding or removing one slot never affects the others. If luksAddKey reports “No key available with this passphrase,” the passphrase you entered matches no existing slot — try others, and if none work, you are in the forgot-passphrase case above.
Back up and restore the LUKS header
The LUKS header holds the encryption metadata. If it is corrupted — disk damage at the wrong offset, or an accidental dd to the wrong device — the payload is unrecoverable even with the correct passphrase. Back it up to offline media:
cryptsetup luksHeaderBackup /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
To restore:
cryptsetup luksHeaderRestore /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
Anyone with the header backup and your passphrase can decrypt the disk. Treat the backup with the same care as the disk itself.
Recovering a broken signed-boot chain
InterGenOS boots a signed UKI: a single file bundling the kernel, the initramfs, and the kernel command line, signed with your machine’s Machine Owner Key (MOK). On an encrypted install, that bundled initramfs is the FDE initramfs, so the unlock prompt lives inside the signed envelope and cannot be substituted by an attacker.
A kernel upgrade rebuilds and re-signs the UKI. If that signing step fails, you can be left unable to boot the normal path.
UKI signing failed on a kernel upgrade
The kernel post-install hook preserves a GRUB-loads-vmlinuz path as a recovery fallback. From the GRUB recovery entry you can boot the bare vmlinuz, supply the FDE initramfs with an initrd= argument, and unlock as normal.
Before retrying the post-install hook, check the underlying signing-failure messages:
cat /var/log/intergen-kernel-postinstall.log
The ESP filled up and the new UKI was not written
When the ESP runs out of space during a kernel upgrade, UKI generation logs the condition and skips writing the new UKI; the previous kernel’s UKI remains the default, so the system still boots. To recover space and write the current kernel’s UKI, remove an old kernel and re-run the post-install hook:
pkm remove linux-kernel-<old-version>
Then re-run the post-install hook for the current kernel. The same log file records the underlying messages.
For the full signed-boot model and MOK enrollment, see Verified Boot & Secure Boot.
What recovery never includes
InterGenOS recovery has hard boundaries by design:
- No remote recovery service and no escrowed key. The project cannot decrypt your disk for you.
- No telemetry in the recovery paths. The FDE recovery shell has no network and writes no logs.
- No silent overrides. The Forge integrity gate cannot be bypassed by accident; the override phrase must be typed in full, with paste disabled.
These are not limitations to work around. They are the point: a recovery channel that exists for your convenience also exists for an attacker’s.
When in doubt, reinstall from a known-good ISO
If you cannot trace a failure to one of the paths above, the safest move is to back up what you can, verify your live ISO, and reinstall with Forge. The integrity gate ensures the packages deployed match the signed manifest, so a reinstall returns you to a known-good state.
See also
- FORGE Installation Guide — the full install walkthrough.
- Disk Encryption & LUKS — the complete encryption and unlock model.
- Verified Boot & Secure Boot — the signed-boot chain that wraps the encrypted root.
- FAQ — common install and boot questions.
The AI Assistant
InterGenOS ships with InterGen, a local AI assistant that runs entirely on your own machine. It answers questions about your system, helps with shell, configuration, and code tasks, and never sends your data off the box by default. There is no cloud account, no API key, and no telemetry.
InterGen is a system assistant. Its strength is knowing your machine, not the
whole world. You open it from the Applications menu or from any terminal with
the intergen command.

InterGen answering a disk-usage question: it runs the underlying command, then reads the result back in plain English.
What it does
You talk to InterGen in plain language. It recognizes intent, runs the right command, and reports back. Typical requests:
- “How much free space is on my root partition?” — runs the right
dfinvocation and summarizes the answer. - “What’s my current IP address?” — a direct
iplookup plus a plain-English summary. - “Write me a systemd timer that runs
backup.shevery Sunday at 03:00.” — drafts the unit and timer files, then asks before installing. - “Why did sshd fail to start after I edited the config?” — reads the relevant
journalctloutput, summarizes the error, and suggests a fix. - “Install htop” — recognizes the intent and asks you to confirm before
running the install through
pkm, the InterGenOS package manager.
Local-first by design
Every model InterGen uses runs on your own CPU and GPU. Nothing about your prompts, your files, your configuration, or your machine identity leaves the machine by default. This is the InterGenOS posture in one feature: a machine you understand, can modify, and can trust.
The trade-offs are stated honestly:
- Local models are smaller than frontier cloud models, so answers on the hardest tasks are less sharp.
- First use downloads the model (roughly 1.5 to 21 GB depending on your hardware tier). After that, no network is needed.
- If you ask about brand-new software the model has not seen, it tells you so rather than guessing.
For cases where you want the depth of a frontier model, the optional Phone-A-Friend (Frontier/Cloud Escalation) path lets you opt in to a cloud provider on a per-request basis. It is off by default and never silent: InterGen asks before reaching out, and the outbound payload is scanned first.
How it scales to your hardware
InterGen inspects your RAM and GPU and picks a model tier automatically. The shipping tiers all use Qwen models:
- Tier 1 (~1.5 GB model) — machines with under 8 GB of RAM. Good for system queries, command lookups, and summarizing logs. Not built for writing code from scratch.
- Tier 2 (~5.5 GB model) — machines with 8 to 15 GB of RAM. The daily-driver tier: coding, configuration drafts, and multi-step reasoning. A Tier 2 machine without a discrete GPU falls back to the smaller model to keep latency usable.
- Tier 3 (~21 GB model) — machines with 16 GB or more of RAM and a discrete GPU. Deep, multi-file code analysis and complex architectural reasoning. A 16 GB+ machine without a discrete GPU stays on the Tier 2 model.
A small embedding model ships alongside every tier to power the assistant’s semantic-matching layer.
If your hardware changes, InterGen picks up the upgrade and switches tiers on the next start.
What it can and can’t do (the safety chain)
Every action InterGen proposes is classified before it runs:
- AUTO — read-only operations like
ls,df, andjournalctl. Run immediately, with the result shown to you. - CONFIRM — anything that changes state, such as
systemctl restart, apkm install, or editing a config file. InterGen pauses and shows exactly what it intends to do. Nothing runs until you approve it. - BLOCKED — destructive or security-bypass operations such as
rm -rf /or reformatting the root disk. InterGen refuses and explains why.
The classifier is conservative by design. Nothing that changes the system runs without explicit approval, and the most dangerous commands cannot run at all. See Constraining the assistant for how the safety chain is configured, and Privacy for the data boundaries.
InterGen Sentinel

InterGen Sentinel is the pluggable security scanner that guards InterGen’s interactions with the outside world. It inspects content crossing two boundaries: data returned from external and MCP tools (ingress) and content about to be sent off-device (egress). Both surfaces are scanned by default.
The default configuration runs two local stages: a fast local-rules pass and an optional deep pass backed by a small local Qwen classifier. For deeper analysis you may opt in to a cloud scanner backed by one of six providers — Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), or DeepSeek. No cloud provider is configured by default, so the default install scans entirely on-device.
Other apps can talk to it
InterGen exposes a narrow D-Bus interface, so the text editor, the terminal, the system settings panel, and third-party apps can request code completion, log summarization, or semantic search over IPC. Only a small set of vetted interfaces is exposed, which keeps a local unprivileged application from driving arbitrary code execution.
InterGen is also a Model Context Protocol (MCP) client. It can connect to local MCP servers to acquire new capabilities while preserving the boundary between the assistant’s core runtime and the tool-execution environment.
Turning it on or off
InterGen is off by default. You opt in at install time through the assistant toggle in Forge, the InterGenOS installer, or at any time later by running:
intergen setup
This downloads the model, enables the intergen.service unit globally, and starts
the assistant. To opt out:
systemctl --global disable intergen.service
The model files stay on disk under /var/lib/intergen/models/ in case you want
to re-enable later without re-downloading.
In this section
- Overview — how InterGen fits the rest of the system
- Explanations — how the assistant reasons about your machine
- Teaching mode — learning alongside the assistant
- Constraining the assistant — tightening the safety chain
- Privacy — the data boundaries, in detail
Overview & Boundaries
InterGen is the AI assistant built into InterGenOS. It runs entirely on your machine, helps you administer, configure, and write code on that machine, and sends nothing about your prompts, files, or system anywhere outside the box. There is no cloud account, no API key, and no telemetry in the default install.
This page covers what InterGen does, the boundaries it operates within, and the two features that govern how it touches the outside world: InterGen Sentinel and Phone-A-Friend (Frontier/Cloud Escalation).
How it fits together
InterGen runs locally, and everything that crosses the machine boundary is screened first by one gate — its Sentinel scanner. The whole shape in one view:
flowchart TD
You(["You"]) -->|" prompt "| IG["InterGen<br/>local Qwen model, auto-sized to your hardware<br/>Tier 1 ~1.5 GB to Tier 3 ~21 GB, on-device"]
IG -->|" anything crossing the machine boundary "| S
subgraph S["InterGen Sentinel"]
direction TB
R["Local-Rules<br/>always on, no model, no network"] --> Q["Local-Qwen<br/>optional, on-device classifier"] --> C["Cloud scanner<br/>opt-in, OFF by default"]
end
S --> V{"verdict?"}
V -->|" ALLOW "| W(["External tools · MCP servers<br/>Phone-A-Friend, opt-in cloud"])
V -->|" FLAG / BLOCK "| H(["held for review, or refused"])
C:::off
classDef off stroke-dasharray:5 4;
On a default install, no cloud provider is configured for either Sentinel or Phone-A-Friend, so everything above runs entirely on your machine. Cloud help — a stronger scanner, or a frontier model via Phone-A-Friend — is opt-in per request, never the default, and any outbound payload is screened by Sentinel’s egress policy before it leaves.

InterGen answering a disk-usage question: it ran the read-only command, then summarized the result in plain English.
What InterGen does
InterGen is a chat-style system assistant. You open it from the Applications menu or with the intergen command in any terminal, and you ask it about your machine. Its strength is knowing your system, not the whole world. Typical requests:
- “How much free space is on my root partition?” — it runs the right
dfinvocation and reads back the answer. - “What’s my current IP address?” — a direct
ipcommand plus a plain-English summary. - “Write me a systemd timer that runs
backup.shevery Sunday at 03:00.” — it drafts the unit and timer files, then asks before installing. - “Why did sshd fail to start after I edited the config?” — it reads
journalctl -u sshd, summarizes the error, and suggests a fix. - “Install htop” — it recognizes the intent and asks you to confirm before running
sudo pkm install htop.
InterGen is not a replacement for a general chat tool. If you ask about brand-new software the model has not seen, it tells you so rather than guessing.
How it scales to your hardware
InterGen inspects the host’s RAM and GPU and selects an appropriately sized local model automatically. The shipping tiers all run Qwen models served locally:
- Tier 1 (~1.5 GB model) — machines with under 8 GB of RAM. Handles system queries, command lookups, and log summaries. Not built for writing code from scratch.
- Tier 2 (~5.5 GB model) — machines with 8 to 15 GB of RAM. The daily-driver tier: coding, configuration drafts, and multi-step reasoning. On a Tier 2 machine without a discrete GPU, InterGen falls back to the smaller model to keep latency usable.
- Tier 3 (~21 GB model) — machines with 16 GB or more of RAM and a discrete GPU. Deep, multi-file code analysis and complex architectural reasoning. A 16 GB+ machine without a discrete GPU stays on the Tier 2 model.
If your hardware changes, InterGen picks up the upgrade and switches tiers on the next start. A small embedding model ships alongside every tier to power semantic matching in the router.
The boundaries: fully local, zero telemetry
Every model InterGen uses runs on your own CPU and GPU by default. Nothing about your prompts, files, configuration, or machine identity leaves the local network. The trade-offs are honest:
- The local models are smaller than frontier cloud models, so answers on hard tasks are less sharp.
- First use downloads the model (roughly 1.5–21 GB depending on your tier). After that, no network is needed.
The trade-off you do not make is data exposure. When you want the depth of a frontier model, the optional Phone-A-Friend (Frontier/Cloud Escalation) feature lets you opt in on a per-request basis, off by default and never silent.
This is the InterGenOS posture in practice: a machine you understand, can modify, and can trust.
What it can and can’t do: the safety chain
Every action InterGen proposes is classified before it runs:
- AUTO — read-only or harmless operations such as
ls,df, andjournalctl. They run immediately and the result is shown to you. - CONFIRM — anything that changes state, such as
systemctl restart,pkm install, or editing a config file. InterGen pauses, shows exactly what it intends to do, and runs nothing until you approve. - BLOCKED — destructive or security-bypassing operations such as
rm -rf /, formatting the root disk, or disabling Secure Boot from inside the running system. InterGen refuses and explains why.
The classifier is conservative by design. Nothing that changes the system runs without explicit approval, and the most dangerous commands cannot run at all. This is what keeps you in control.
InterGen Sentinel
InterGen Sentinel is the pluggable security scanner that guards InterGen’s interactions with the outside world. It inspects content crossing two boundaries: data returned from external and MCP tools (ingress, an injection risk) and content about to be sent off-device (egress, an exfiltration risk). Both surfaces are scanned by default.
Sentinel runs a layered scan and returns one of three verdicts: ALLOW, FLAG (hold for human review), or BLOCK (refuse). When verdicts disagree, the most severe one wins, and any scanner that errors fails closed to FLAG rather than silently allowing content through.
The default configuration runs two stages, both fully on-device:
- Local-Rules — an always-on deterministic floor of pattern and heuristic rules. No model, no network. This is the minimum guarantee on every interaction.
- Local-Qwen — an optional deeper pass backed by a small on-device Qwen classifier. Richer judgement than the rules floor, still no network.
For the strongest analysis you may opt in to a cloud scanner backed by one of six providers: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), or DeepSeek. No cloud provider is configured by default, so the default install scans entirely on-device.
Sentinel also enforces a signed never-list: a manifest of paths the assistant may never perform a destructive operation on, including its own configuration. The scan policy is in the protected set the assistant itself can never edit, and turning scanning off requires a human-authenticated path.
Phone-A-Friend (Frontier/Cloud Escalation)
Phone-A-Friend (Frontier/Cloud Escalation) is the optional, consent-first path for handing a request to a more capable frontier model in the cloud when the local assistant cannot satisfy it. It is off by default: no provider is configured out of the box, and the feature only acts after you have explicitly set one up.
When a request exceeds local capability, InterGen offers to escalate and asks before reaching out. A consent modal shows you the full outbound payload before anything is sent, so your consent is informed. The same six providers available to Sentinel can be configured here, with API keys stored in the system keyring rather than in plain configuration.
Every outbound payload is scanned by Sentinel’s egress policy first, so a blocked send keeps sensitive content from leaving the machine. This preserves InterGen’s local-first posture: cloud assistance is available when you ask for it, never imposed.
Turning InterGen on or off
InterGen is off by default. You opt in either at install time (the “Enable the InterGen AI assistant?” toggle in Forge’s package-selection screen) or later by running:
intergen setup
That downloads the model, enables the intergen.service unit, and starts the assistant. Because the installer enables the unit globally (systemctl --global enable intergen.service), opting back out means undoing that global enablement — run systemctl --global disable intergen.service, or use the in-app toggle. A per-user systemctl --user disable does not undo the installer’s global enable, so reach for the global disable or the toggle instead.
The model files stay on disk under /var/lib/intergen/models/ in case you want to re-enable later without re-downloading. To free that space, remove the directory as root.
Where to go next
Reading “What I Did and Why”
InterGen, the local assistant in InterGenOS, does not act silently. Every action it takes or proposes carries an explanation: what it intends to do, which part of your system it touches, and the outcome the permission model assigned to that action. This page explains how to read that surface so you always know why the assistant did what it did, and why it sometimes refuses.
The principle behind all of it is simple: this is a machine you understand, can modify, and can trust. The assistant’s job is to be legible, never to be a black box.
The two questions behind every action
InterGen evaluates every action on two separate axes, decided by two separate mechanisms. Keeping them apart is what keeps the explanations honest.
- Privilege — “Would a person at this terminal need
sudofor this, and what does it touch?” This is the permission gate. It decides whether an action runs freely, asks for your authorization, or is refused. - Content trust — “Does data crossing a boundary carry an injection attempt coming in, or leak a secret going out?” This is handled independently by the scanner and provenance layer (InterGen Sentinel), not by the privilege gate.
The two never get conflated. The privilege axis treats a read as free; the content axis independently watches what that read returns. When you read an explanation, knowing which axis is speaking tells you why a given action was treated the way it was.
Zones: what the action touches
The permission gate mirrors the operating system’s real privilege model. A person at a terminal can freely touch their own files and needs sudo or PolicyKit for system things. InterGen inherits that exact model rather than inventing a new one, so the rules already match what you understand about your own machine. Actions are classified by the zone they touch:
- Z1 — User space. Your own things: your home directory and everything under it, your user services, your files. No
sudoneeded to change them. - Z2 — System config and state. Root-owned, ordinary administration: most of
/etc,/usr,/opt,/var, system services, installed packages. A person needssudoto write here. - Z3 — System-critical and trust anchors. Root-owned files that underpin the boot and security trust chain (
/boot, the EFI partition and signed kernel images, Secure Boot keys, dm-verity hashes, LUKS headers,/etc/shadow,/etc/sudoers, and similar), plus InterGen’s own code and configuration.
Operations: what kind of action it is
Each action is also one of three kinds:
- R — Read or inspect. Status, list, view a file. No change to the system.
- W — Write or modify. Edit, create, or delete a file; change a config.
- X — Execute or state-change. Run a command, start or stop a service, install or remove a package, reboot.
The three outcomes
The zone and the operation together produce exactly one of three outcomes. This is the heart of what “what I did and why” means.
- FREE — InterGen does it immediately, with no prompt. This covers every read of non-secret data and everything in your own user space. Asking “what’s my disk space?” or “list the installed packages” returns an answer directly. A read being free is the point: the assistant should never refuse to tell you the state of your own machine.
- AUTH-PROMPT — The action changes something in system space (Z2). InterGen triggers the operating system’s real authorization, PolicyKit, and asks you plainly: for example, “InterGen wants to restart Bluetooth. That needs admin rights. Authorize?” Your password is the gate, and the OS enforces it. You will not see an opaque card of internal checks; you see a plain-language request and the actual system authorization dialog.
- FORBIDDEN — The action would write to or change a system-critical Z3 file, or InterGen’s own code. InterGen will not do it, and it tells you so openly. It states what it will not do and why, and confirms that you can still do it yourself with
sudoif you intend to.
The full mapping is small enough to hold in your head:
| Z1 User space | Z2 System config/state | Z3 Critical / InterGen-self | |
|---|---|---|---|
| Read | FREE | FREE | listing FREE; secrets AUTH-PROMPT |
| Write | FREE | AUTH-PROMPT | FORBIDDEN |
| Execute | FREE | AUTH-PROMPT | FORBIDDEN |
Reading a secret (your shadow file or key material) is AUTH-PROMPT, not forbidden, because a person can sudo cat their own shadow file. InterGen does not pretend to be stricter than the OS. Whether that content may then leave the machine is the separate content-trust axis.
Why the assistant will not edit itself
The one category InterGen refuses absolutely, even with your authorization, is changing its own substrate: its code, its model pins and signatures, its daemon units and PolicyKit policy, and its verified model store. These are classified as Z3.
This is deliberate, and it is the keystone of the design. The whole game of a capable adversary is to talk an assistant into rewriting its own gate, manifest, or guardrails. If InterGen’s own files are write-forbidden to InterGen, then even a flawless prompt-injection attempt cannot make InterGen weaken InterGen. Only you, acting manually and outside the assistant, can. When you see InterGen refuse to touch its own files, that refusal is the protection working, not a malfunction.
Reading a transparent refusal
A refusal is never silent and never hidden behind jargon. InterGen states plainly what it will not do and why, in terms of protecting the trust chain that keeps the machine yours, and it hands control back to you. You will not see phrases like “blocked by the safety layer” or references to internal tiers. You will see something like:
“I won’t modify the system’s boot and security files. That’s the trust chain that keeps this machine yours. It’s your machine, so you can do it yourself with
sudoif you intend to; I just won’t be the one to touch it.”
If you ever see a refusal that hides its reason or fails silently, that is a bug to report, not the intended behavior.
How a request is resolved before it reaches the model
The explanation surface is also shaped by how InterGen routes a request. It does not hand every prompt straight to the model. A priority-ordered chain tries the cheapest, most predictable method first:
- Decomposition — splits a compound request (“update the system, then restart the web server”) into sub-tasks.
- Keyword match — fast pattern matches for common queries dispatch directly to a built-in tool, no model involved.
- Semantic match — a lightweight embedding search dispatches a high-confidence match to a built-in tool.
- Tool calling — the model selects a system tool and arguments, and the router executes the call.
- Free response — the fallback, where the model answers conversationally from its own knowledge.
This is why a simple query like “what’s my IP?” returns a direct, deterministic answer rather than a model paraphrase: it was resolved at the keyword stage. When you read what the assistant did, the routing stage explains how it arrived at the action, and the zone-and-operation outcome explains whether it was allowed to run.
Where escalation fits
If a request exceeds what the local assistant can do, InterGen may offer Phone-A-Friend (Frontier/Cloud Escalation), a consent-first path to a more capable cloud model. It is off by default and acts only when you have explicitly configured a provider. Before anything leaves the machine, Sentinel’s egress policy scans the outbound payload. An escalation is always something you are asked about and agree to, never something the assistant does on its own.
See also
Teaching Mode
InterGen, the local AI assistant in InterGenOS, is built to help you learn the machine you are running, not just operate it. It explains what it is about to do before it does it, shows you the exact commands it would run, and walks through errors in plain language. This page covers how to use InterGen as a teaching tool: asking it to explain rather than execute, working through a problem step by step, and keeping yourself in control of every change.
The goal is a machine you understand, can modify, and can trust.
Explain instead of execute
InterGen’s safety classifier sorts every proposed action into one of three levels before anything runs:
- AUTO — read-only or harmless operations (for example
ls,df,journalctl,systemctl status). These run immediately and the result is shown to you. - CONFIRM — anything that changes state, such as
systemctl restart,pkm install, or editing a configuration file. InterGen pauses, shows you exactly what it intends to do, and waits for your approval. Nothing runs until you say yes. - BLOCKED — destructive or security-bypassing operations such as
rm -rf /or reformatting the root partition. InterGen refuses and explains why.
This is what makes InterGen useful for learning: the CONFIRM step is a natural pause where you can read the command, ask why, and decide whether to run it yourself. The classifier is conservative by design. If a command looks dangerous, you will be asked.
Asking InterGen to teach
InterGen is a chat-style assistant. Open it from the Applications menu or run
the intergen command in any terminal. To use it as a learning aid, ask it to
explain rather than to act. Examples drawn from its documented capabilities:
- “Why did sshd fail to start after I edited the config?” — InterGen reads
journalctl -u sshd, summarizes the error, and suggests a fix. - “Explain what this Python error means.” — it returns the traceback with context, in plain language.
- “Write me a systemd timer that runs
backup.shevery Sunday at 03:00.” — it drafts the unit and timer files and shows them to you, then asks before installing. You can read the draft and learn the syntax before committing. - “What’s my current IP address?” — it runs the right
ipcommand and gives a plain-English summary alongside the raw output.
InterGen is a system assistant. Its strength is knowing your machine, so it teaches best when the question is about your system: services, configuration, shell commands, logs, and your own code.
The hardware tier sets the depth
How much teaching InterGen can do depends on the model tier it selects for your hardware. It inspects RAM and GPU at startup and picks automatically:
- Tier 1 (~1.5 GB model) — under 8 GB of RAM. Good for system queries, command lookups, and summarizing logs. Not built for writing code from scratch.
- Tier 2 (~5.5 GB model) — 8 to 15 GB of RAM. The daily-driver tier: coding, configuration drafts, and multi-step reasoning.
- Tier 3 (~21 GB model) — 16 GB or more of RAM and a discrete GPU. Deep code analysis across multiple files and complex architectural questions.
Every tier runs a Qwen-family model served locally, with a small embedding
model alongside it for memory and retrieval. You can confirm the tier InterGen
detected, and the exact model it chose, by running intergen tier.
For step-by-step walkthroughs and multi-file code explanations, a Tier 2 or Tier 3 machine gives sharper answers. On Tier 1, lean on InterGen for command lookups and log summaries rather than from-scratch code generation.
Stays on your machine
Every model InterGen uses runs on your own CPU and GPU. Nothing about your prompts, files, configuration, or machine identity leaves the local network. There is no cloud account, no API key, and no telemetry. When the local model has not seen a brand-new piece of software, it tells you so rather than guessing, which is the honest behaviour you want from something you are learning with.
If a question genuinely exceeds local capability, the optional Phone-A-Friend (Frontier/Cloud Escalation) path can hand that single request to a frontier cloud model of your choice. It is off by default, asks before reaching out, and scans the outbound payload before anything leaves the machine. Cloud help is available when you ask for it, never imposed.
Turning InterGen on
InterGen is off by default. Enable it at install time with the “Enable the InterGen AI assistant?” toggle in Forge’s package-selection screen, or at any time afterward by running:
intergen setup
This downloads and verifies the model for your tier (and the embedding model), then enables and starts the assistant.
To opt back out, use the InterGen toggle in the Applications menu. Because the unit is enabled globally, the equivalent command is:
systemctl --global disable intergen.service
Related pages
- Meet InterGen — the introductory tour of the assistant.
- Frequently asked questions
- Installing with Forge
Privacy & Data Locality
InterGenOS is built so that the data on your machine stays on your machine. The AI assistant, InterGen, runs locally by default and sends nothing off the box unless you explicitly opt in, on a single request, to a cloud provider you have chosen. There is no cloud account, no API key, no telemetry, and no background “improve the service” exfiltration. Security is not first. It is only.
This page documents the data-locality guarantees that hold today in InterGenOS 1.0-dev (build id v1.0-dev1).
The guarantee in one sentence
Every model InterGen uses runs on your own CPU and GPU, and nothing about your prompts, your files, your configuration, or your machine identity ever leaves the local network unless you deliberately escalate a single request to a cloud provider.
Local-only by default
InterGen is the system assistant that ships with InterGenOS. It is hardware-detected, offline-first, and runs entirely on the local machine using Qwen models. Its job is to know your machine, not the whole world.
- No cloud account. InterGen requires no sign-in, no license server, and no remote identity to function.
- No API key. The default assistant needs no credentials to a remote service.
- No telemetry. InterGen does not phone home with usage statistics, crash reports, prompt contents, or machine fingerprints.
- No silent escalation. There is no “we just send it to improve the service” loophole. Off-box communication only happens through one explicit, opt-in path, described below.
After the first-run model download, no network connection is needed for InterGen to work. The model is fetched once (roughly 1.5 to 21 GB depending on your hardware tier) and then runs offline.
The tiered models are selected automatically from your RAM and GPU. Smaller tiers serve machines with less memory; larger tiers unlock on machines with more RAM and a discrete GPU. Tier selection is a local hardware inspection — it sends nothing anywhere.
InterGen is off by default
InterGen does not run until you turn it on. You opt in either at install time, through the “Enable the InterGen AI assistant?” toggle in Forge’s package-selection screen, or at any later time by running:
intergen setup
This downloads the model and enables intergen.service, which ships enabled globally (system-wide via systemctl --global enable), then starts the assistant. To opt out, use the InterGen toggle in the desktop, or disable the unit globally:
systemctl --global disable intergen.service
A per-user systemctl --user disable does not undo the global enable, so use the global disable above or the in-app toggle.
The model files remain on disk under /var/lib/intergen/models/ in case you want to re-enable later without re-downloading. To reclaim that space, remove the directory as root:
sudo rm -rf /var/lib/intergen/models/
See the Forge installation guide for the install-time toggle, and the assistant overview for a wider tour of InterGen.
The one path off the box: Phone-A-Friend (Frontier/Cloud Escalation)
For the cases where you want the depth of a larger frontier model, InterGen offers an optional feature called Phone-A-Friend (Frontier/Cloud Escalation). It lets you opt in to a cloud provider of your choice on a per-request basis. It is off by default and never silent. You decide, for that single request, that the prompt may leave the machine. Nothing is sent without that explicit choice, and what leaves is scoped to that request — your current prompt and the context you give it for it, not your files, your wider conversation history, or your machine identity.
This is the only mechanism by which any prompt or data leaves the local network, and it is entirely under your control.
A jurisdiction note, stated plainly: the available providers — Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek — are operated by companies subject to the laws of their home jurisdictions; most are US-based and can receive lawful data requests. Phone-A-Friend never sends anything on its own, but once you escalate a request, that provider’s privacy policy and legal jurisdiction govern what you sent. For sensitive material, keep the request local.
Two separate axes: privilege and content trust
InterGen evaluates every action on two independent axes, kept deliberately separate.
| Axis | Question it answers |
|---|---|
| Privilege | Would a human need sudo for this, and what does it touch? |
| Content trust | Does data crossing a boundary carry an injected instruction (inbound) or leak a secret (outbound)? |
The privilege axis decides whether InterGen acts freely, asks for authorization, or refuses. The content-trust axis independently watches what the data carries — inbound scanning for injected instructions, outbound scanning to keep secrets from leaking. The pluggable scanner that handles content trust is InterGen Sentinel, which defaults to Local-Rules plus a Local-Qwen model. Its cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek) are opt-in only.
Keeping the two axes separate matters for privacy. A read of your own files is free on the privilege axis, while the content axis independently governs whether anything from that read may then leave the machine.
Reads are free; your data is not pre-shared
InterGen mirrors the privilege model the operating system already has. A read of non-secret data — your status, your file listings, most of /etc — runs immediately and locally, with no prompt and no off-box transmission. Reading is a local operation; the answer is computed on your machine.
Secrets such as /etc/shadow or key material are treated the way the OS treats them. Because a user can sudo cat their own shadow file, InterGen reading a secret triggers the OS’s real authorization prompt (pkexec/PolicyKit) rather than being forbidden. Whether the content of such a read may then leave the machine is governed separately by the content-trust axis. InterGen never pretends to be stricter than the OS, and it never pre-shares your data as a side effect of reading it.
InterGen cannot rewrite its own restraints
InterGen’s own files — its code, its panel extension, its model pins and signatures, its verified model store, its daemon units and PolicyKit policy, and its signing and provenance state — are treated as system-critical. InterGen may read them but may never modify them. Only you, acting manually and outside the assistant, can change them.
This closes a direct attack on your privacy: by design, a prompt injection cannot make InterGen rewrite its own gate, scanner, or guardrails, because those files are root-owned and write-forbidden to the unprivileged assistant. This is a deliberate defense-in-depth control, not a claim of perfect immunity — it removes the most direct coercion path (talking the assistant into weakening itself), so an assistant that will not edit its own restraints will not quietly open a channel off your machine either.
The local trust chain underneath
The data-locality guarantees rest on integrity guarantees that InterGenOS provides at the system level. The system ships with a signed Secure Boot chain, dm-verity integrity protection, and UKI signing, so the software making these promises is itself verified. Software is installed through the pkm package manager and the system is installed with Forge, the native installer. Together these give you a machine you understand, can modify, and can trust.
What this means in practice
- Your prompts, files, configuration, and machine identity stay local.
- The assistant is off until you enable it, and it can be fully disabled again.
- The only way anything leaves the box is a deliberate, per-request Phone-A-Friend (Frontier/Cloud Escalation) escalation that you initiate.
- No telemetry, no account, no API key, no silent channel.
See also
Disabling & Constraining the Assistant
InterGenOS exists to give you a machine you understand, can modify, and can trust. The assistant, InterGen, is a tool in service of that goal, not a condition of it. You decide how much of it runs, what it is allowed to touch, and whether it is ever permitted to reach beyond your machine. Nothing here is on by default that sends data off the device.
This page covers three things: how InterGen already constrains itself, how you constrain or disable it, and how to configure Phone-A-Friend (Frontier/Cloud Escalation) if you want optional cloud assistance.
How InterGen constrains itself
Before you change anything, it helps to know what the assistant already will and will not do. InterGen does not invent its own permission system. It inherits the one the operating system already has: you can freely touch your own files, and you need sudo or a PolicyKit prompt for system things. The assistant mirrors that exact model.
Every action is judged on two independent axes that are never conflated:
- Privilege — would a human need
sudofor this, and what does it touch? - Content trust — does data crossing a boundary carry an injection (inbound) or leak a secret (outbound)?
The privilege axis sorts your filesystem into three zones:
| Zone | What it is | Examples |
|---|---|---|
| User space | Owned by you | ~/ and below, your user services and files |
| System config / state | Root-owned, ordinary administration | most of /etc, /usr, /opt, /var, system services, installed packages |
| System-critical / trust anchor | Root-owned and part of the boot and security trust chain, plus InterGen’s own files | /boot, EFI/UKIs, Secure Boot keys, kernel and initramfs, dm-verity hashes, LUKS headers, /etc/shadow, /etc/sudoers, /etc/pam.d, and InterGen’s own code and data |
Combined with the operation (read, write, execute), each action resolves to one of three outcomes:
- Free — done immediately, no prompt. All reads of non-secret data, and everything in your own space.
- Auth-prompt — InterGen triggers the operating system’s real authorization (PolicyKit/pkexec) in plain language: “InterGen wants to restart Bluetooth. That needs admin rights. Authorize?” Your password is the gate; the OS enforces it.
- Forbidden — InterGen will not do it and says so transparently, confirming that you can do it yourself.
Two properties matter most for control:
- The assistant cannot modify its own restraints. InterGen’s own code, models, signing material, daemon, and PolicyKit policy are treated as system-critical. Writing to them is forbidden to the assistant — they are root-owned and the assistant runs unprivileged. By design, a prompt injection therefore cannot talk InterGen into rewriting its own gate, manifest, or guardrails; this is a deliberate defense-in-depth control, not a claim of perfect immunity. Only you, acting manually outside the assistant, can change them.
- A signed never-list protects survival-critical paths with no config option, ever. An OpenPGP-signed manifest enumerates paths the assistant may never destroy: boot and credential integrity, the system itself, and InterGen’s own configuration directories. This list is not user-tunable by design. It is the floor that stays in place no matter how the rest of the assistant is configured.
When InterGen refuses a system-critical action, it states plainly what it will not do and why, and confirms the machine is yours to change with sudo if you intend to. There is no silent failure and no hidden refusal.
The governance controls
The Operations panel exposes InterGen’s posture in one place. Open it from the InterGen panel and select the Governance tab.

The Governance tab: current autonomy posture, signed-config status, and the destructive-policy never-list at a glance.
From here you can see the current autonomy posture and the integrity status of the assistant’s signed configuration, and re-verify it on demand. The autonomy setting only ever modulates how many auth-prompt actions InterGen offers to take on your behalf. It never blocks a read, and it never expands what the assistant is forbidden to do.
Constraining the assistant
You constrain InterGen along the same two axes it already respects.
Limit what it can do without asking. Lower the autonomy posture so that more actions require an explicit auth-prompt. At the most conservative setting, system changes always route through a PolicyKit password prompt that the operating system itself enforces.
Limit what it can reach. InterGen is offline-first and local by default. It uses hardware-detected local models (Qwen) and sends no telemetry. The separate security scanner, InterGen Sentinel, also runs entirely on-device by default (a deterministic local-rules floor plus a local Qwen classifier). No part of this requires a network. If you never configure a cloud provider, nothing the assistant does can leave the machine.
Keep the never-list intact. You do not need to do anything to keep the signed destructive-policy protections. They are not configurable and remain in force regardless of any other setting.
Disabling the assistant
Because InterGen runs as an ordinary system service and a desktop panel extension, you turn it off the way you turn off any other service on a machine you control, using the OS’s real mechanisms rather than relying solely on an in-app toggle. The assistant runs as the systemd unit intergen.service, which is enabled globally (system-wide, via systemctl --global enable) and writes its log to /var/log/intergen/intergen.log.
- Stop it for the session by stopping
intergen.service. InterGen will not act while its daemon is not running. - Disable it from starting by disabling the unit globally with
systemctl --global disable intergen.service, so it does not come back on the next boot. Because the unit is enabled globally, a per-usersystemctl --user disabledoes not undo the global enable — disable it globally, or use the in-app toggle. - Remove it entirely with the package manager:
pkm remove intergen. The assistant ships as theintergenpackage in theaitier — a small, separable part of the system (pkm info intergenshows exactly what it placed on disk).
Each of these is a system-level (auth-prompted) change you make as the administrator. That is deliberate: the assistant is not permitted to disable, re-enable, or reinstall itself, so the on/off switch stays in your hands alone.
Phone-A-Friend (Frontier/Cloud Escalation)
Phone-A-Friend (Frontier/Cloud Escalation) is the assistant’s optional path to a more capable cloud (“frontier”) model. It is consent-first and off until you configure it. With no provider set up, escalation cannot run at all; offers simply degrade to a note suggesting you configure one. InterGenOS ships local-only and ready.
This feature is distinct from the local quality fallback. Phone-A-Friend is consent-first assistance: when the assistant recognizes that a task is multi-step, sensitive, or slightly outside its local scope, it offers to reach your configured frontier model and sends nothing without your explicit agreement.
Escalation modes
You choose how eagerly InterGen offers to escalate:
| Mode | Behavior |
|---|---|
| Never | Fully offline. Never offers, never sends. |
| Fallback | Escalates only when the local model fails its own quality gate. |
| Ask (default) | Offers when it recognizes a fitting task; you consent before anything is sent. |
| Auto | Decides by confidence without prompting each time. |
You can also invoke escalation yourself at any time with the “Ask my frontier model” affordance (GUI button, with command-line parity), which bypasses the recognition heuristic because you have already asked.
Two safety guarantees on every send
- Show-before-send. A consent modal displays the full outbound payload, scrollable in its entirety, before anything leaves the machine, so your consent is informed.
- Egress scanning on derived sends. The one initial payload you explicitly authorize is trusted at source. Every subsequent outbound message in the flow (anything derived or agentic that you did not individually approve) is scanned by the same Sentinel policy that guards the tool chokepoint. A blocking verdict refuses the send, so secrets are not shipped to the cloud behind your back.
Configuring a provider
Open the InterGen panel, go to the Providers tab, and add a provider.

The Providers tab: choose a built-in provider or a custom endpoint, set the model, and store the API key. Configuration applies only when you opt in.
The cloud substrate is vendor-neutral. No provider is privileged, and every adapter speaks plain HTTPS with no vendor SDK. Built-in providers cover the major frontier vendors, plus a custom adapter for any OpenAI-compatible endpoint. The current set is:
- Claude (Anthropic)
- ChatGPT (OpenAI)
- Gemini (Google)
- Copilot (Microsoft)
- Grok (xAI)
- DeepSeek
- Custom (any OpenAI-compatible endpoint)
Your API key is read from the system keyring per call and is never cached in the process, and a request is refused over any non-TLS transport. The same vendor-neutral substrate also powers Sentinel’s optional cloud scan tier, which is likewise off unless you opt in.
Because these settings live in InterGen’s own configuration directory, which the signed never-list protects, the assistant cannot quietly rewrite your provider choices or escalation mode. Changes are yours to make.
Related pages
Building from Source & Package Management
InterGenOS is built from source. Every package that ships in the system was compiled from upstream code in an isolated build environment, recorded with content hashes, and deployed by a package manager that can later prove each file on disk is exactly what was installed. This section explains how that pipeline works and how you can inspect, rebuild, or extend it yourself.
This is the practical expression of the project’s posture: a machine you understand, can modify, and can trust.
The two halves of the system
InterGenOS package handling splits cleanly into a factory and a consumer:
igos-buildis the factory. It constructs packages from source code in an isolated environment and produces binary archives (.igos.tar.gz).pkmis the consumer. It runs against the live filesystem, installing, removing, querying, and verifying those archives. It records every deployed file in a database that doubles as an audit trail.
igos-build compiles source and generates the initial file list and hashes. pkm is the command-line tool end users run to download and install the resulting archives, and to confirm at any later time that nothing on disk has drifted from what was installed.
See The Transparent Package Manager for pkm in depth, and Building Packages from Source for the build side.
How the system is assembled: the build tiers
The full system is organized into six tiers, built in dependency order. As of this writing (1.0-dev, build id v1.0-dev1), the live package counts derive roughly as follows. These numbers drift as packages are split, added, or merged, so derive the live count from the package definitions rather than treating any figure as permanent.
| Tier | Role | Approximate count |
|---|---|---|
toolchain | Bootstrap compiler and core build tools | ~28 |
core | Essential system libraries and utilities | ~272 |
base | Base userland on top of core | ~23 |
desktop | Graphical environment and desktop applications | ~420 |
extra | Additional applications and tooling | ~112 |
ai | Local assistant components | ~2 |
That totals roughly 857 packages across the six tiers today. To derive the current figure, count the package definitions per tier rather than quoting this table.
The build pipeline
A full image build runs through 20 phases in fixed order, with an optional publish step at the end:
validateverify-sourcessetuptoolchainchroot-prepchroot-toolscoreconfigcore-extrabasekerneldesktopaiextrabootloaderimagemanifestsquashfsukis-verityiso
Source verification happens before any compilation. Image, manifest, squashfs, UKI/verity, and ISO assembly happen after the package tiers are built, so the final artifact carries an integrity chain from the verified sources through to the bootable image.
What this gives you
Because the package manager records a SHA-256 hash for every file it deploys, you can ask the system to re-verify itself at any time. The pkm verify command recalculates the hash of every installed file on disk and compares it against the expected hash, detecting both accidental corruption and unauthorized modification. Package state lives in a SQLite database for fast queries and, alongside it, human-readable text manifests for direct inspection. The same record-keeping that makes the system fast makes it auditable.
Upgrades use a “supersede” model rather than blind overwrites, so package splits (for example, separating a tool’s core utilities from its extras) happen without orphaning files or breaking dependencies. Configuration files under /etc/ are tracked separately and preserved across changes, so your local modifications are not silently discarded.
What ships today
pkm, the package manager described above.- Forge, the system installer. See the FORGE Installation Guide.
- A signed Secure Boot chain, dm-verity integrity over the read-only system image, and UKI signing, covered in Verified Boot & Secure Boot.
- GNOME 49 on Wayland as the desktop environment.
- InterGen, a tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry. See The AI Assistant.
- InterGen Sentinel, a pluggable security scanner defaulting to Local-Rules and Local-Qwen, with six opt-in cloud providers available via “Phone-A-Friend” (Frontier/Cloud Escalation): Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek.
KDE/Plasma and Qt6, switchable desktops, and dedicated application campaigns (for video, graphics, CAD, finance, virtualization, and similar) are planned and not part of the current system. This section documents only what ships today.
In this section
- The Transparent Package Manager — how
pkminstalls, removes, queries, and verifies the live system. - Building Packages from Source — the
igos-buildfactory and how to compile a package yourself. - Repositories, Mirrors & Self-Hosting — where archives come from and how to serve your own.
- Reproducibility & Verification — confirming a build matches its sources and that installed files match the record.
- Package & Config Reference (generated) — the generated catalog of packages and tracked configuration.
The Transparent Package Manager
InterGenOS manages installed software with its own package manager, pkm. It installs, updates, queries, removes, and verifies pre-compiled binary archives (.igos.tar.gz) on the live filesystem. pkm is built to be fast, predictable, and auditable: a machine you understand, can modify, and can trust.
The Model
pkm operates on the live root filesystem. (Its sibling, the build system, constructs packages from source in an isolated environment and never touches a running install.) pkm itself is written in Python, and its source lives in the pkm/ directory of the InterGenOS source tree.
It uses a deliberate hybrid data model so that speed never costs you transparency:
- A SQLite database at
/var/lib/igos/pkm.dbis the primary source of truth, used for fast queries and transactional installs. - Plain-text manifests at
/var/lib/igos/packages/are generated alongside every database record. They are human-readable, so you can inspect exactly what a package put on your disk without any special tooling.
The SQLite schema tracks installed packages, a per-file map (every deployed file recorded against its owning package, with its SHA-256 checksum and whether it is a config file), runtime dependencies, a cache of the synced remote index, and an append-only history log of every install, removal, and supersede for audit trails.
Trust by Verification
pkm earns trust by checking, not by assuming. Every interaction holds to the same principles:
- Trust by verification. pkm fetches the repository index from the official mirror, cryptographically verifies its signature against the release-signing keys pinned in the source, and hashes every downloaded archive before it is installed.
- Silence is golden. pkm does not phone home: no telemetry, no usage analytics, and we do not know what packages you install. It never installs or upgrades software on its own — the system changes only when you run it. The single background task it ships is an opt-out daily update check that counts available upgrades and notifies you; it downloads and installs nothing (see Update notifications).
- Explicit consent. A small number of packages don’t ship the software themselves — they download proprietary, vendor-supplied software that requires accepting a vendor EULA (End User License Agreement). For those, pkm pauses, names the vendor license, and waits for your explicit consent before downloading anything. pkm never accepts a license on your behalf, and refuses to proceed at all in a non-interactive session.
The Trust Chain
The trust model runs end to end:
- The repository index is signed by a release-signing subkey held on a hardware token (a Nitrokey). That subkey is certified by the offline InterGenOS master key, which never signs releases itself — it only certifies the subkeys.
- The expected subkey fingerprints are pinned locally in the source as
pkm/release-keys.json. - When you sync the index, the signature is checked. If it fails, pkm halts immediately.
- When you install an archive, its SHA-256 hash is checked against the verified index. A mismatch is a hard rejection, not a warning.
This index-signing model is one piece of a wider integrity story on InterGenOS: a signed Secure Boot chain, dm-verity integrity, and UKI signing all protect the system below the package layer.
Provenance: Where Every File Came From
Because pkm records the owning package and a SHA-256 hash for every file it deploys, provenance is always answerable on a live system.
- Content-hash verification. Verifying a package recalculates the SHA-256 hash of each installed file on disk and compares it to the expected hash in the database. This detects accidental corruption and unauthorized modification alike.
- Archive verification. Before installation, an incoming archive’s hash is checked against the trusted index synced from the central repository, under a configurable archive-trust mode.
- Content vs. config. pkm tracks config state for files under
/etc/, storing each one’s original deployed hash. When an upgrade ships a new config file, pkm attempts a safe merge or leaves a.newfile rather than silently overwriting a configuration you have changed.
Installs Are Atomic
The install pipeline follows a strict, inspectable sequence. The archive is first extracted to a staging directory using hardened tar flags (--no-same-owner, --no-same-permissions). Its manifest is parsed for the file list, any supersede declarations, and embedded hashes. pkm then runs invariant checks (for example, refusing to let a package replace a critical symlink with a directory, and confirming superseded predecessors are present and correctly ordered) before deploying to the root filesystem. Hardened deploy flags drop setuid/setgid bits, which are then explicitly restored only where the archive metadata calls for them.
The database is updated inside a single transaction: the installed record, the per-file hashes, any supersede ownership transfer, and the history entry all commit together or not at all. The text manifest is generated last, reflecting the final committed state.
The Supersede Model
Upgrades are handled as a “supersede” transaction rather than a remove-then-install. When package B supersedes package A, files present in both are overwritten on disk and their ownership is transferred to B with updated hashes; files unique to A are left in place under A’s historical record; and A’s record is timestamped as superseded. This makes fine-grained package splits possible without orphaning files or breaking dependencies, and it means an interrupted operation (a failure or a power loss) never leaves the system half-installed.
Removal
Removals are cautious. Config files under /etc/ are preserved unless you force their removal. Regular files are unlinked; if a file’s on-disk hash differs from the recorded hash, pkm warns that it was modified post-install but still proceeds. Directories are removed only when they become completely empty. pkm also identifies and cleanly removes orphaned dependencies no longer required by anything else on the system.
Daily Commands
These are the commands you will reach for most. Operations that change the system require sudo; queries against the local index do not.
sudo pkm sync # fetch and verify the latest index (does not install)
pkm search <term> # search the local synced index (no network needed)
sudo pkm install <pkg> # download, verify, and install (pulls prerequisites)
sudo pkm upgrade # install newer versions for what you already have
sudo pkm remove <pkg> # uninstall, plus clean orphaned dependencies
pkm list installed # list everything installed (the default for bare `pkm list`)
pkm info <pkg> # version, dependencies, architecture, license
sudo pkm verify <pkg> # re-hash installed files against recorded hashes
sync only refreshes the index; upgrade is the command that actually changes what is on disk. Searching is fast and offline because it queries your local copy of the index.
Natural-Language Aliases
pkm accepts the command names you would naturally reach for from other distributions, and resolves each to its canonical command so the behavior is identical regardless of which you type:
| Canonical | Aliases |
|---|---|
update | sync, refresh |
remove | uninstall |
search | find |
info | show |
list | ls |
files | contents |
depends | deps |
Running pkm --help shows each alias next to its canonical name.
Maintenance & Housekeeping
Beyond the daily set, pkm carries the commands you reach for when auditing, pinning, or cleaning up:
pkm provides /path/to/file # which installed package owns a file
pkm history # append-only log of every install/remove/supersede
pkm depends <pkg> # show a package's runtime dependencies
sudo pkm autoremove # remove orphaned dependencies nothing else needs
sudo pkm hold <pkg> # pin a package — excluded from `pkm upgrade --all`
sudo pkm unhold <pkg> # release a hold
sudo pkm reinstall <pkg> # re-fetch and reinstall (repair a modified install)
sudo pkm cache clean # prune the download cache under /var/cache/pkm/
pkm keeps two caches under /var/cache/pkm/: packages/ holds downloaded archives (an older one stays after each upgrade) and rollback/ holds a pre-upgrade snapshot so a failed upgrade can be reverted. pkm cache clean prunes the download cache by policy; pkm cache clean --rollback targets the rollback cache instead. Nothing in the cache is required for a working system — it exists for re-installs and rollbacks.
What pkm Does NOT Do
- No unattended upgrades. pkm never downloads or installs software on its own. Your system stays exactly as it is until you command a change with
pkm upgrade,pkm install, orpkm remove. - No telemetry. No anonymous reporting of what you install or run.
- No phoning home. The only network endpoint pkm contacts is the package mirror you configured, and only when you sync or install. It reports nothing about you or your machine.
Update Notifications (opt-out)
InterGenOS ships exactly one background package task: a daily update check. A systemd timer, pkm-check-updates.timer, is enabled by default and once a day runs pkm check-updates, which compares your installed packages against the index you last synced and writes a small summary to /var/lib/pkm/available-updates.json. Two surfaces read that file — the GNOME tray shows an “updates available” indicator (the intergen-pkm-notifier shell extension), and tty/SSH logins print a single N package update(s) available line in the login message (silent when there are none).

The daily check found one update and the GNOME tray indicator says so — nothing was downloaded or installed. The indicator hands you the safe preview, pkm upgrade --all --dry-run; applying the update is still your own explicit sudo pkm upgrade --all. The terminal confirms a stock InterGenOS 1.0-dev “Revival” system.
It is strictly informational and stays true to a machine you control:
- It never downloads or installs anything — it only counts. You still run
sudo pkm upgradeyourself to apply updates. - The check compares against your locally-synced index rather than fetching a new one, so it does not reach the mirror on its own; the count is as current as your last
sudo pkm sync. - It is opt-out:
sudo systemctl disable --now pkm-check-updates.timerturns it off completely, and pkm behaves as if it were never there.
How pkm Compares
pkm borrows familiar concepts but makes its own security trade-offs:
| Feature | pkm (InterGenOS) | apt (Debian/Ubuntu) | pacman (Arch) | dnf (Fedora) |
|---|---|---|---|---|
| Trust model | Signed index | Signed index (InRelease) | Signed index / per-package sigs | Signed metadata / per-package sigs |
| Auto-updates | Never | Configurable | Configurable | Configurable |
| Telemetry | None | Popcon (opt-in) | None | countme (configurable) |
| Proprietary downloads | Pauses for vendor-EULA consent | Repo separation (non-free) | User discretion | Repo separation |
The Catalog
The InterGenOS catalog is built from source across six tiers (toolchain, core, base, desktop, ai, and extra). The package count drifts as the catalog grows; derive the live figure from the synced index rather than relying on a fixed number. The desktop tier ships GNOME 49 on Wayland today. The ai tier carries the local, offline-first InterGen assistant — which includes a built-in security scanner, InterGen Sentinel — and the llama.cpp inference engine it runs on.
Further Reading
- The Repository Trust Model goes deeper on signing and provenance.
- New to the system? See the Getting Started guide.
Building Packages from Source
InterGenOS is built from source. Every package that ships in the system is compiled from upstream code in a controlled environment, recorded with declared file paths, and verified before it ever reaches an image. This page explains how that build works, and how you can author a new package recipe and integrate it into the build.
This is the workflow behind the distribution itself. If you only want to install pre-built packages on a running system, see The Package Manager (pkm). If you want to understand how the whole system is assembled and signed, see Reproducibility.
Building from source is part of that posture: the goal is a machine you understand, can modify, and can trust, with no opaque binaries arriving from elsewhere.
How the system is built
InterGenOS (currently 1.0-dev, build id v1.0-dev1) is assembled in a sequence of build phases that run in order, each consuming the output of the ones before it. The phases are, in order:
validateverify-sourcessetuptoolchainchroot-prepchroot-toolscoreconfigcore-extrabasekerneldesktopaiextrabootloaderimagemanifestsquashfsukis-verityiso
An optional publish step follows when the resulting packages are being pushed to the repository.
The early phases build a clean toolchain and a temporary set of tools, enter an isolated build root, then build the system tier by tier. The later phases assemble the image, generate an integrity manifest, build the live filesystem (squashfs), sign the unified kernel image and set up dm-verity integrity, and produce the final ISO.
Packages and tiers
A package is a recipe directory. Recipes are grouped into six tiers, each with a distinct role in the build:
| Tier | Role |
|---|---|
toolchain | The compiler and core build tools used to build everything else |
core | Foundational system libraries and utilities |
base | The base userland on top of core |
desktop | The graphical desktop and its applications |
ai | The local AI runtime |
extra | Servers, developer tooling, browsers, and additional system utilities |
The number of packages in each tier drifts as the system grows. As of 2026-06-15, the build spans roughly 857 packages across the six tiers (toolchain 28, core 272, base 23, desktop 420, extra 112, ai 2). Treat these as a live count, not a fixed figure; derive the current numbers from the package tree rather than relying on a number written here.
The desktop that ships today is GNOME 49 on Wayland.
The ai tier holds two packages: InterGen, the tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry; and llama.cpp, the inference engine it runs on. InterGen includes a security-scanner subsystem, InterGen Sentinel, that defaults to Local-Rules plus a local Qwen model and offers six opt-in cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek). Escalating a check to one of those providers is the “Phone-A-Friend” (Frontier/Cloud Escalation) path, and it is always opt-in.
Two builders
Which tool builds a package depends on its tier. A package is reachable by exactly one of the two builders, never both:
- Core and base are built from static lists in shell scripts. Each of these phases enumerates the exact packages it builds.
- Desktop, ai, and extra are built by the Python tier driver. It walks the tier’s recipe directory, sorts packages by their declared dependencies, and builds everything reachable.
This split matters when you wire a new package in: the tier you choose determines where (and whether) you need to register it.
Anatomy of a package recipe
A recipe lives in a directory named for its tier and package name and contains:
package.yml required: metadata + verify_paths
build.sh required for custom builds; optional for autotools/meson/cmake
patches/ optional, applied by build.sh
<name>.1 optional manpage
package.yml
The metadata file declares what the package is, where its source comes from, what it depends on, and which files it must install. A representative shape:
name: <name>
version: "<version>"
release: 1
description: <one-line description, no trailing period>
license: <SPDX-identifier>
homepage: https://<upstream-homepage>
tier: <core|base|desktop|extra|ai>
build_style: <custom|autotools|meson|cmake|cargo|python>
source:
- url: https://<mirror-or-upstream>/<name>-<version>.tar.<ext>
sha256: <expected-sha256-of-tarball>
dependencies:
build: []
host: []
runtime:
- <dep1>
- <dep2>
verify_paths:
- /usr/bin/<name>
- /usr/lib/lib<name>.so
- /etc/<name>/<name>.conf
The verify_paths block is the package’s promise about what it installs. Pick two or three paths that prove the package actually landed: the primary binary (/usr/bin/<name> or /usr/sbin/<name>), the primary library (/usr/lib/lib<name>.so*) for library-only packages, or a canonical data or config directory for data packages. Each path must be absolute and have at least three segments (for example /usr/bin/x). After the build, an audit checks that every declared path is present before the image is assembled. If a path is missing, the build halts there rather than shipping a broken package.
build.sh
For a custom build style, build.sh defines three functions that the build runs in sequence inside the build root: configure, build, and do_install. An optional post_install runs after the package is registered, for tasks like rebuilding a library cache. A typical skeleton:
#!/bin/bash
# <name> <version> — <one-line description>
configure() {
set -e
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
}
build() {
set -e
make -j"$(nproc)"
}
do_install() {
set -e
make DESTDIR="${DESTDIR}" install
# Post-install fixups go here if needed.
}
Stubs are not allowed. A configure that does nothing and a do_install that installs nothing is forbidden. If the package has source to compile, the recipe must compile it. The only exception is a deliberate metapackage with no source, which must say so explicitly in a header comment and only write configuration in do_install.
Pin a specific version rather than tracking “latest”, and add a short comment justifying the pin.
Patches
There are two patch paths and they are not interchangeable. A downstream patch carried in the recipe’s own patches/ directory is applied by hand inside build.sh. The separate patches: key in package.yml is for patch files staged alongside a fetched upstream tarball and is auto-applied. Do not list the same patch in both places, and dry-run any patch against a fresh extraction before committing it.
Adding a new package
The end-to-end flow for landing a new recipe:
-
Create the recipe directory and
package.yml. Choose the tier by role: foundational utilities go tocoreorbase; graphical apps todesktop; servers, developer tooling, and browsers toextra; the AI runtime toai. -
Author
build.shif the build style is custom, following the skeleton above and the no-stub rule. -
Wire it into the right builder. For
coreorbase, add the package’s exactname-versionliteral to the static list in the matching phase script. Use the exact literal, not a greedy prefix, or the list can silently swallow an unrelated package whose name shares the prefix. Fordesktop,extra, orai, no script edit is needed: thetier:field is the entry point, and the Python builder picks it up automatically. -
Confirm reachability. Run the builder-coverage check. It reports any recipe that exists in the tree but is reachable by neither builder. Such an orphan will never build, and the failure surfaces late. Fix an orphan by registering it with the correct builder.
-
Dry-run the build. Build just the new package inside the build root before committing to a full tier rebuild. The toolchain lives only inside the build root, so the build must run there, not on the host.
-
Commit and push. A pre-push check refuses a new
package.ymlthat lacks bothverify_paths:and apending_acquisition:declaration. If it blocks, add theverify_pathsblock. Use a conventional commit message describing what the package is and why the system ships it. -
Verify with a full rebuild. A complete rebuild is the definitive proof. The package builds as part of its phase, the pre-squashfs audit confirms its declared paths are present, and its archive appears in the post-build archive manifest.
When a package can’t be acquired yet
If a package legitimately cannot be obtained yet because it is blocked on an external dependency, replace the verify_paths block with a pending_acquisition: field stating the reason. The audit skips packages marked this way. This is only for genuinely blocked-on-external cases, not a workaround for not wanting to write the recipe.
From source to installed: the handoff to pkm
The from-source build is the factory; the package manager is the consumer.
The build compiles source and produces a signed binary archive (.igos.tar.gz), generating the file list and SHA-256 hashes during a tracking phase. On a running system, pkm is the tool that downloads and installs those archives. It records every file and its hash in a database at /var/lib/igos/pkm.db, alongside human-readable text manifests under /var/lib/igos/packages/ for inspection.
That recorded state is what makes integrity verification possible. pkm verify recalculates the hash of every installed file and compares it against the stored value, detecting both accidental corruption and unauthorized modification. Combined with the signed Secure Boot chain, dm-verity integrity, and UKI signing established during the build, the result is a system whose contents you can check, all the way from upstream source to the files on disk.
See also
- The Package Manager (pkm) — installing and verifying packages on a running system
- Reproducibility — how the build produces verifiable, repeatable results
- Repositories — where built packages are published and fetched from
- Package Reference — the package catalog
- Forge: the installer — installing InterGenOS to disk
- Verified Boot — the signed boot chain and dm-verity integrity
Repositories, Mirrors & Self-Hosting
InterGenOS installs software from signed binary packages. This page explains how
the package repository is structured, how the client (pkm) trusts it, how the
official mirror is published, and how to host your own.
Every trust decision in the repository chain is reproducible by hand, with no opaque steps. The goal is a machine you understand, can modify, and can trust.
For how pkm installs and verifies packages once they reach your disk, see
Package Management. For the build pipeline that produces
packages, see Building from Source.
What a repository is
A package archive is a single file with the extension .igos.tar.gz. Each archive
carries its file list and per-file SHA-256 hashes inside its manifest. A repository
is a directory of these archives plus a single index that names every archive and
records its SHA-256.
The index file is InterGenOS.db (gzipped JSON, the format pkm/repo.py parses).
It is generated by pkm.repo.generate_index() over an archive directory for a given
architecture (x86_64). Alongside it sits InterGenOS.db.sig, a detached GPG
signature over the index.
The packages themselves are organized into six build tiers — toolchain, core,
base, desktop, extra, and ai. As of mid-2026 a full set is roughly 857
packages across those tiers; derive the live count from the index rather than
trusting a fixed number, since tier contents drift between builds.
The trust model
The integrity boundary is the GPG signature on InterGenOS.db, not TLS. TLS protects
the transport, but trust in what you downloaded rests entirely on the signature and
the per-package hashes it commits to.
The chain works in two layers:
-
The signature on the index.
InterGenOS.db.sigis verified against a trusted public key shipped on the system at/etc/pkm/trusted.gpg. The index is signed by a release subkey held on a hardware token; that subkey is certified by an offline master key that never touches the mirror host. The master public key is published so anyone can verify the chain end to end. -
The hash on each package. Once the index is trusted, every package install verifies the archive’s SHA-256 against the entry in that index. A tampered archive fails this check even if it was served over a valid TLS connection.
This means a compromised mirror cannot hand you a modified package: it would have to forge a signature for a key it does not hold. The signing keys live on hardware tokens, and the master is kept offline.
Verify the chain by hand
Nothing about the trust chain is hidden. You can reproduce the verification the client performs with standard tools:
curl -O https://repo.intergenos.org/x86_64/current/InterGenOS.db
curl -O https://repo.intergenos.org/x86_64/current/InterGenOS.db.sig
gpg --verify InterGenOS.db.sig InterGenOS.db # signed by a release subkey, certified by the master
# then check any archive against its SHA-256 entry in the index
sha256sum <package>.igos.tar.gz
Using the official mirror
The official binary mirror is repo.intergenos.org. Client configuration lives in
/etc/pkm/repos.conf. The two everyday commands are:
pkm sync # fetch the index, GPG-verify InterGenOS.db.sig, cache per-package metadata
pkm install <pkg> # download an archive, verify its SHA-256 against the trusted index
pkm sync fetches InterGenOS.db, verifies its signature against
/etc/pkm/trusted.gpg, and refreshes the local cache of available packages. From
that point an install trusts the per-package hashes the verified index commits to.
Source archives
The mirror also serves the upstream source tarballs used to build each package, under
https://repo.intergenos.org/sources/. Because InterGenOS is built from source, the
source set is published alongside the binaries so the build is reproducible by anyone.
See Reproducibility for what that buys you.
How the official mirror is published
The repository is published by a signed-publish process. The canonical script is
scripts/publish-repo.sh, which is also wired into the build pipeline as an optional
publish phase (the build itself runs 20 phases, from validation through ISO; publish
is the optional step after). The flow is:
- Pre-checks. The chosen signing subkey must be present in the local keyring, and the archive directory must exist and be non-empty.
- Generate the index.
generate_index()writesInterGenOS.dbwith each package’s SHA-256. - Sign the index. A detached, armored GPG signature is written to
InterGenOS.db.sigusing the release subkey. The hardware token prompts for PIN and touch on the workstation. This is the human-in-the-loop step; signing material never sits unattended on the mirror. - Rsync to staging. The signed tree (and the source archives, unless skipped) is copied into a per-publish, timestamped staging directory under the architecture path.
- Atomic promote. The live
currentsymlink is swapped to the new staging directory in a single atomic operation. The prior target is archived. There is no 404 window: in-flight clients finish against the old target or restart against the new one, and no web-server restart is needed. - Transparency-log append. The signed index is appended to an append-only transparency log, giving cold-read auditability of every publish.
A dry run (scripts/publish-repo.sh --dry-run) validates the key, generates the index
in place, and prints the rsync and promote it would perform without writing to the
mirror. Run it before every real publish to confirm the archive count and staging path.
First-publish client switch
On a fresh image, /etc/pkm/repos.conf ships with signature verification commented
off, so a brand-new install’s first pkm sync against an empty mirror does not fail
closed. Once the first signed index is live, the verify default is turned on
(gpg_verify = true) so all subsequent syncs require a valid signature.
Ongoing verification
The mirror host runs a verification pass on a schedule: it checks the index signature, walks every file’s SHA-256, and scans for stray files, alerting on any drift. The same check can be run by hand right after a publish to confirm the live set verifies.
Self-hosting your own repository
Because the format and the publish path are plain files and standard tools, you can host your own repository — a private mirror inside an air-gapped network, a team repo of in-house packages, or a full clone of the official set.
The minimum a repository needs is:
- A directory of
.igos.tar.gzarchives. - An
InterGenOS.dbindex generated over that directory for your architecture, viapkm.repo.generate_index(). - A detached GPG signature
InterGenOS.db.sigover that index, made with a key you control. - A static web server (or any HTTP server) exposing those files under an
x86_64/current/path. - The signing key’s public half distributed to your clients’
/etc/pkm/trusted.gpg, and the repository URL set in/etc/pkm/repos.conf.
The publish script’s design — generate, sign, rsync to a timestamped staging
directory, then atomically swap a current symlink — is worth copying even for a
small repo. It gives you reproducible, no-downtime promotes and a clean rollback (the
previous target is kept), all with ln, mv, and rsync.
Use your own signing key, not the official one. The whole point of the trust model is that signatures are non-transferable: clients trust a repository only because they hold the matching public key. If you run a private repo, you are the trust root for that repo, and your clients should carry your public key — not the official master.
Related pages
- Package Management — installing, removing, and verifying packages on a live system.
- Building from Source — the build pipeline that produces the archives a repository serves.
- Reproducibility — why the source archives ship alongside the binaries.
Reproducibility & Verification
InterGenOS is built from source, and the build is designed so that what you install can be checked rather than taken on faith. This page explains what the system verifies today, what reproducibility means here, and how you can confirm an install is the artifact it claims to be.
The guiding posture is simple: security is not first. It is only. A reproducible, verifiable build is what lets you run a machine you understand, can modify, and can trust.
This page describes InterGenOS 1.0-dev (build id v1.0-dev1). Some of the reproducibility work below is shipped today; the full byte-identical-rebuild milestone is a stated goal of the 1.x series and is marked as such throughout. Nothing here is presented as finished unless it is.
What “verification” covers today
A from-source distribution earns trust in layers. These are the verification properties InterGenOS ships now:
- Pinned, checksum-verified sources. Every upstream source is pinned to a specific version and verified against a recorded SHA-256 before it is used. A source that does not match its recorded hash stops the build; it is never silently substituted.
- A signed Secure Boot chain. The bootloader and the unified kernel images (UKIs) are signed at a hardware-token signing step. Signing only appends a signature; it never alters the payload, and the signed outputs are verified after signing.
- dm-verity integrity for the system image. A verified-integrity hash tree is generated over the read-only system image. Each kernel image’s command line carries the verity root hash of that image, so with Secure Boot enabled, a tampered system image cannot boot under a validly signed kernel.
- A signed package index. Packages are published to the mirror with a fully signed index. Every publish regenerates and re-signs the complete index, and clients verify the entire index against one signature. Data transfer is incremental, but the signed index is never partial, and the live repository is promoted by an atomic swap so clients never see a half-published state.
Together these mean a booted InterGenOS system can prove its boot chain is signed, its system image is integrity-checked, and its packages came from a signed index — without trusting the network path they arrived over.
The build pipeline, and where trust is established
The image is produced by an ordered pipeline of phases. It is worth seeing where in that pipeline each trust property is actually established, because the answer is “at a specific, named phase, with a fail-closed check” rather than “somewhere in a large opaque build.” Sources are hash-checked before anything is compiled; the package index is signed before the image is sealed; the system image’s integrity hash is sealed into the signed kernel image; and only then is a bootable ISO emitted.
flowchart TB
SRC[Upstream sources<br/>each pinned to a version] --> VS{verify-sources}
VS -.->|" hash mismatch "| HALT[Build halts]
VS ==>|" SHA-256 matches "| TIERS["Build from source in a clean chroot<br/>six tiers, built in order:<br/>toolchain → core → base → kernel → desktop → ai → extra"]
TIERS --> BL[bootloader<br/>signed GRUB + shim chain + SBAT]
BL --> IMG[image<br/>assemble the root tree]
IMG --> MAN[manifest<br/>index signed by the release key]
MAN --> SQ[squashfs<br/>read-only system image]
SQ --> UV[ukis-verity<br/>dm-verity root hash sealed into the signed UKI]
UV --> ISO[(Signed ISO image)]
The dashed branch is the point of the whole design: a source that does not match its recorded hash does not get patched around or downloaded from a fallback — the build stops. The same fail-closed posture runs through the sealing phases, where a missing signature or a verity mismatch halts the release rather than shipping it.
A worked example: the boot anchor’s bill of materials
The Secure Boot shim is the binary the entire boot chain is verified through, so its provenance is published as a concrete, inspectable artifact rather than described only in prose. The source tree carries an SPDX 2.3 JSON SBOM for the shim under docs/sboms/, generated by scripts/shim-sbom-gen.py. It records the exact inputs that go into shimx64.efi: the pinned upstream shim source at a specific commit, the digest-pinned base build image and its package snapshot, the embedded InterGenOS Secure Boot CA certificate (in both DER and PEM form), the SBAT vendor entry, and the shim binary’s own SHA-256 and size.
Two properties make it evidence rather than a label:
- It is deterministic. The generator reads the repo-resident inputs from the committed git tree — not the working copy — and emits byte-identical SPDX JSON for an unchanged input set. Anyone can re-run it and diff the result against the published file; a match confirms the recorded provenance, and a mismatch is a real signal. The generator can additionally emit a detached signature at release time, anchored to the hardware signing key.
- It is inspectable. It is plain SPDX 2.3 JSON, readable with ordinary tools, listing every input alongside its hash — no special tooling required to audit what the boot anchor is built from.
Coverage today is the shim specifically: the root of trust the rest of the chain depends on, recorded as a machine-readable artifact you can read and reproduce.
What reproducibility means here
A reproducible build means that starting from the same source code, the same toolchain, and the same documented build environment, two independent builders produce byte-identical output: bit-for-bit identical package archives and, ultimately, a bit-for-bit identical filesystem image, with cryptographic hashes that match exactly.
Why this matters: a reproducible build is a security primitive. If an independent party fetches the published source, applies the published recipes, and rebuilds, they should get an archive byte-identical to the one on the mirror. If it does not match, then either the published recipe does not describe the real build, the infrastructure was tampered with, or there is a non-determinism bug. All three are findable with reproducibility and invisible without it. This is the shift from “we signed the binary” to “the binary is independently verifiable from source.”
The InterGenOS commitment, stated precisely
Reproducibility is layered, and the layers land on different timelines:
- Per-package archives (1.x target). Given the same pinned source, the same compiled toolchain, and the same build environment (same chroot, same source date, same locale and timezone), two builders produce byte-identical package archives — same content, same modes, owner and group normalized to root, normalized timestamps, normalized archive metadata.
- The signed index (follows from per-package). Given the same archive set, the published index is byte-identical across builders, because the index generator is already deterministic.
- The ISO image (later 1.x target). A byte-identical final ISO layers on top of the above and additionally requires deterministic system-image compression and bootable-image metadata. This is scoped now so the per-package work does not preclude it, and it is a later 1.x target rather than an initial 1.0 claim.
- Bootstrap toolchain (separate, longer effort). Making the build toolchain itself reproducible is a bootstrap problem addressed as its own separate effort beyond the per-package work. The posture is that every package above the bootstrap layer is reproducible, while the bootstrap is held fixed at known-good versions and verified by hash.
Current state, honestly
The build is reproducible by construction in its design — a fixed source date and deterministic phase ordering are part of the lifecycle — and pinned, checksum-verified sources are enforced today. Full byte-identical per-package output across independent builders is the documented 1.x goal and is partially in place:
- Source-date handling is honored in the manifest path.
- The cargo vendoring pipeline already produces reproducible vendor tarballs using the standard normalized-tar recipe, which demonstrates the technique works in this tree.
- The general package-archive emitter and full source-date propagation into the build environment are the remaining work for the per-package milestone.
The reproducibility recipe
InterGenOS follows the well-established reproducible-builds approach (the same envelope used across the major distributions), because third-party verifiers already know what to look for. The work that is specific to InterGenOS is the integration layer — where these settings enter the pipeline and what the audit checks validate. The recipe suppresses every input that varies between builders:
- A canonical source date consumed by build systems and compilers, so embedded build timestamps do not leak live clock values.
- Normalized archives — sorted entries, owner and group set to root, normalized timestamps, and a long-path-safe archive format — with the compression layer written so it carries no embedded filename or timestamp.
- Build-path normalization so absolute build paths do not get baked into binaries, debug info, or assertion messages.
- Pinned locale and timezone so locale-dependent ordering and timezone-shifted timestamps cannot vary.
- Deterministic link order, which most modern build systems and linkers already provide, confirmed per package by audit rather than assumed.
The principle behind all of it: the recipe declares the inputs that should matter, and everything else is pinned, normalized, or stripped.
How a build proves itself
Reproducibility is one half of trust; the other half is that a candidate is never trusted on the strength of a clean build alone. A build whose packages all compiled is not a build that is known-good. The defects that matter most in a from-source distribution compile fine, package fine, and only surface when the artifact is installed and booted on real hardware — a locked-down service unit with no writable path, a directory missing from a package’s file list, a wrong hardware-detection heuristic, a first-boot timing race.
So the path to a trusted release always runs the full chain: build the candidate, sign the boot chain, assemble the ISO, boot the live image on real hardware, install it, reboot into the installed system, and read every log on every boot for failed units and a clean trust record. A fix is finished only when it lives in the source tree and a clean from-scratch build reproduces the corrected behavior with zero manual steps. A fix that works only because of a hand edit on a running box is a note about a fix, not a fix.
A candidate becomes a stable, golden release only when a full from-scratch cycle runs end to end with zero triggers — nothing required a fix — validated on representative lower-end hardware, with timing-sensitive items cleared over several consecutive cold boots.
Verifying your own install
What you can check today on a running or freshly installed system:
- Confirm the boot chain. The system boots through a signed bootloader and signed kernel images under Secure Boot, with the system image’s integrity root hash carried in the signed kernel command line.
- Confirm package provenance. Packages come from a mirror whose entire index is signed; the package manager (pkm) verifies the index signature before trusting any entry.
- Confirm a clean boot. A trusted install shows zero failed units and a clean integrity record on every boot.
What is coming with the per-package reproducibility milestone: the planned local build-from-source mode lets you rebuild a package on your own machine and bit-compare the result against the published hash for that package. Until per-package reproducibility is verified, that mode is advisory — it proves the source compiles, not that it produces the identical artifact a trusted builder would. Once reproducibility lands, a matching hash means your local rebuild is byte-equivalent to the published binary, and you have independently confirmed the recipe produces it — without trusting the build infrastructure at all.
Related pages
- The InterGenOS package manager (pkm)
- Building from source
- Repositories and the signed mirror
- Forge, the installer
- Verified boot
Package & Config Reference
This page is the reference for what InterGenOS ships and how to inspect it: the package tiers, the on-disk state that pkm records, and the commands that answer “what is installed, at what version, owning which files?” directly from the live system.
Because a hand-maintained package table drifts the moment a package is added, split, or superseded, this reference does not reproduce a frozen catalog of every package. Instead it tells you how the package set is structured and how to derive the authoritative, current answer from the machine in front of you.
Why the live system is the source of truth
A wiki table written once quietly falls out of step with the packages actually built, the versions actually shipped, and the files actually deployed. Once that happens the documentation stops being trustworthy, and a document you cannot trust is worse than no document.
InterGenOS treats documentation drift as a defect, not an inconvenience. The trustworthy reference is derived from the same sources that build the system — the package definitions and the recorded install state — so that what you read matches what is on disk. That is part of the wider posture of the distribution: a machine you understand, can modify, and can trust. You cannot trust a system you cannot accurately describe.
The two sources of truth are:
- The package definitions. Each package is described by a definition under the package tree, grouped into build tiers.
- The installed-state database. On a live system,
pkmrecords every installed package, its version and tier, and every deployed file with its SHA-256 hash. See the package manager reference for the data model.
Reconciling these is what makes the reference trustworthy: the definitions say what should be built, and the database records what was installed.
What the reference covers
Per tier, the package set is described by:
- Package name, version, and tier.
- Short description.
- Declared runtime dependencies.
- Supersede relationships (which package replaces which), since InterGenOS upgrades packages by a supersede model rather than in-place replacement.
- Tracked configuration files: the
/etc/entries thatpkmmanages specially to preserve user modifications.
See the package manager reference for supersede semantics and the configuration-file handling these fields are drawn from.
Build tiers
InterGenOS organizes packages into six tiers, built in order during the image build: toolchain, core, base, desktop, ai, and extra. The tier counts shift continuously as packages are added, split, or superseded, so any number printed in a wiki page is a snapshot rather than a contract.
Derive the live counts from the package tree or from pkm on a running system rather than treating a written number as permanent. For example, to count packages per tier from a checkout of the source tree:
for tier in toolchain core base desktop ai extra; do
printf '%-12s %s\n' "$tier" "$(find packages/$tier -name package.yml | wc -l)"
done
The build itself runs as a sequence of phases. The package-building phases produce the tiered packages; the surrounding phases handle source verification, environment and chroot setup, kernel and bootloader, image assembly, manifest generation, squashfs, UKI/dm-verity, and ISO creation.
Querying the real system
The authoritative live answer comes from the package manager itself. pkm keeps a SQLite database at /var/lib/igos/pkm.db and human-readable text manifests under /var/lib/igos/packages/, so the installed state is both fast to query and directly inspectable. The text manifests can be read with ordinary tools, no database client required.
Common queries against the live state:
pkm list— list installed packages.pkm info <package>— show a package’s version, tier, and details.pkm files <package>— list the files a package deployed.pkm provides <path>— find which package owns a file.pkm depends <package>— show declared dependencies.pkm verify— recompute the SHA-256 hash of every installed file and compare it against the recorded hash, detecting both corruption and unauthorized modification.
That same hash data is what describes deployed files. For the full data model, operations, and integrity behavior, see the package manager reference.
Notes on scope
This reference describes what the distribution ships today, not what is planned. The shipped desktop is GNOME 49 on Wayland. The shipped local assistant is InterGen, which includes a built-in security-scanner subsystem, InterGen Sentinel; InterGen and the llama.cpp inference engine are the two packages in the ai tier. Planned components, such as switchable desktops or additional application campaigns, are not part of the package tree until they are built, so they do not appear in the installed-state database until then.
This reference exists so that the packages and configuration on your machine can always be described accurately, and therefore audited.
Related pages
- Package manager — data model, install/remove/supersede, verification.
- Build from source — how packages are produced.
- Reproducibility — deterministic builds and the manifest.
- Forge installer guide — installing InterGenOS.
GPU Compute & AI Workloads
This section covers how InterGenOS uses the GPU: the graphics backends it can target, the compute stacks used for machine-learning work, and how the built-in AI assistant detects and scales to the hardware it finds on your machine.
InterGenOS is built from source and aligned on a single principle. That posture shapes the GPU stack the same way it shapes the rest of the system: you get a machine you understand, can modify, and can trust, with no opaque vendor blobs running outside your knowledge or consent.
InterGenOS is at version 1.0-dev (build id v1.0-dev1). The pages below describe the shipping system. Where a backend, command, or package is not yet documented in detail, the page says so plainly rather than guessing.
What ships today
The desktop is GNOME 49 on Wayland. GPU acceleration for the desktop session runs through that stack.
For compute and AI work, the system pairs a vendor-neutral default with opt-in vendor stacks. The individual pages in this section document each backend; the high-level shape is:
- A vendor-neutral default backend that works across GPUs without committing you to a single vendor’s toolchain. See Vulkan (default, vendor-neutral).
- AMD compute via a from-source ROCm path. See ROCm for AMD (automated from-source).
- NVIDIA compute via an opt-in CUDA path. See CUDA for NVIDIA (opt-in mirror).
For the per-vendor specifics — which driver lands, how it is selected, and the exact commands — read:
- Overview & Backend Selection
- PyTorch / TensorFlow / JAX
- Language-Runtime Foundations
- Per-GPU Driver Notes
How the GPU feeds the AI assistant
The clearest consumer of GPU compute in InterGenOS is InterGen, the local AI assistant. InterGen is offline-first and runs inference on local hardware by default, so your data stays on your machine. It carries zero telemetry.
InterGen is hardware-tiered. It probes the host’s RAM and GPU and selects an appropriately sized model automatically, then serves it locally over an HTTP API backed by llama.cpp. The shipping tiers use Qwen models (the qwen35 model architecture is the one InterGen’s bundled llama.cpp is built to load).
The detector reports the tier level, the detected RAM and GPU, and the recommended model and quantisation for that tier. You can see the result for your own machine with intergen tier. The tiers are:
| Tier | Hardware | Model |
|---|---|---|
| Tier 1 | < 8 GB RAM, no or integrated GPU | Qwen3.5-2B (Q4_K_M, ~1.5 GB) |
| Tier 2 | 8–15 GB RAM with a GPU | Qwen3.5-9B (Q4_K_M, ~5.5 GB) |
| Tier 3 | 16 GB+ RAM with a discrete GPU | Qwen3.5-35B-A3B MoE (Q4_K_M, ~21 GB) |
InterGen’s bundled llama.cpp is a CPU-only build (an AVX2 instruction-set floor, no GPU offload), so the model that actually runs is governed by what the CPU can handle at a usable response latency, not by GPU acceleration. A machine without a discrete GPU — including most integrated-graphics laptops — is served the Tier 1 (2B) model even when its RAM would otherwise place it in Tier 2, because the 9B is too slow to run on CPU alone. The exception is a sufficiently powerful CPU (for example, a modern high-core-count or AI-class processor), which can carry the larger model without offload.
A small embedding model (nomic-ai/nomic-embed-text-v1.5) ships alongside the assistant to power its semantic-matching layer.
The full assistant architecture — the priority router, the AUTO/CONFIRM/BLOCKED safety classifier, D-Bus and MCP integration, and memory — is documented in the assistant section.
Security scanning and cloud escalation
Two related features sit alongside the local assistant. Both are local-by-default and consent-first.
InterGen Sentinel is a pluggable security scanner that inspects content crossing the device boundary: data coming in from external and MCP tools, and content about to be sent off-device. Its default configuration runs entirely on-device — a fast local-rules pass plus an optional deeper pass backed by a small local Qwen classifier. For deeper analysis you may opt in to a cloud scanner backed by one of six providers: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), or DeepSeek. None is configured by default.
Phone-A-Friend (Frontier/Cloud Escalation) is an optional path for handing a request to a more capable frontier model when the local assistant cannot satisfy it. It is off by default, asks before reaching out, stores API keys in the system keyring, and scans every outbound payload through Sentinel’s egress policy first. Cloud assistance is available when you ask for it, never imposed.
The rest of the platform
InterGenOS ships its own package manager (pkm), its own installer (Forge), a signed Secure Boot chain, dm-verity integrity, and UKI signing. The system is assembled across six package tiers (toolchain, core, base, desktop, ai, extra) through a 20-phase build pipeline. The package total runs to roughly 850 as of this writing; these counts drift as the system grows, so treat any figure as a snapshot rather than a fixed total.
For installation and the GPU-relevant steps of setup, see the Forge installer guide.
Where to go next
- New to the GPU stack? Start with Overview & Backend Selection.
- Running ML frameworks? See PyTorch / TensorFlow / JAX.
- Specific card behaving oddly? Check Per-GPU Driver Notes.
Overview & Backend Selection
InterGenOS runs local AI inference on the hardware in front of it. The local assistant, InterGen, detects the host’s RAM and GPU at startup and selects an appropriately sized model, then serves it through a llama-server subprocess from llama.cpp over a local HTTP API. The compute backend that subprocess uses to talk to your GPU is the subject of this page.
The guiding principle is the same one that runs through the rest of the system: a machine you understand, can modify, and can trust. The default backend is chosen to work on the widest range of hardware without a vendor-specific driver stack. Vendor-tuned backends are available, but they are opt-in.
Why a vendor-neutral default
A default that pulls in a large proprietary driver stack expands the trusted surface of every install, whether or not that hardware is present. A vendor-neutral backend keeps the default install small, inspectable, and portable across GPUs from different vendors.
For this reason InterGenOS ships with a Vulkan-based compute backend as the default. Vulkan is supported across AMD, Intel, and NVIDIA GPUs through their respective open drivers, so the same default image runs accelerated inference on a broad range of machines without requiring a vendor SDK at build or install time.
See Vulkan (default) for details on the default backend.
Opt-in vendor backends
Two vendor-tuned backends can be enabled when the matching hardware and toolkit are present:
- ROCm for AMD GPUs. See ROCm (AMD).
- CUDA for NVIDIA GPUs. See CUDA (NVIDIA).
These typically deliver higher throughput than the vendor-neutral path on their respective hardware, at the cost of pulling in a vendor-specific runtime. Because that runtime enlarges the trusted surface, neither backend is enabled by default. You choose to add it.
How a backend is selected
At a high level, backend selection follows the same local-first, hardware-detected philosophy as model selection:
- The host’s GPU and RAM are probed at startup.
- The default Vulkan backend is used unless a vendor backend has been explicitly enabled.
- If a vendor backend (ROCm or CUDA) is configured and the matching hardware is present, inference is routed through it.
This keeps the out-of-the-box experience predictable and vendor-neutral while leaving the higher-performance path one deliberate step away for users who want it.
Relationship to model tiers
Backend selection is independent of, but interacts with, the model tier InterGen picks for your hardware. InterGen scales the model to the detected RAM and GPU: a smaller model on low-memory systems, a larger one where a discrete GPU and ample RAM are present. The compute backend determines how that model is accelerated; the tier determines which model runs. A faster backend does not change the tier, but a discrete GPU influences both.
For the model catalog and tier thresholds, see the InterGen assistant documentation. For per-GPU notes, see Per-GPU guidance.
What this is not
This page covers the local inference backend only. It is unrelated to optional cloud features:
- InterGen Sentinel, the pluggable security scanner, runs entirely on-device by default (a fast local-rules pass plus an optional local Qwen classifier). Cloud scanning, backed by one of six opt-in providers, is configured by you and off by default.
- Phone-A-Friend (Frontier/Cloud Escalation) is an optional, consent-first path that hands a request to a frontier model in the cloud. It is off by default; no provider is configured out of the box.
Neither feature depends on the GPU backend, and neither is enabled out of the box. The default install runs and reasons entirely on your own hardware.
See also
Vulkan (default, vendor-neutral)
Vulkan is the default GPU path on InterGenOS. It is vendor-neutral: a single API that runs across AMD, Intel, and NVIDIA hardware through each vendor’s installable client driver (ICD), without committing your machine to one vendor’s proprietary compute stack. This keeps the system understandable and portable. You can read your graphics setup, reason about it, and move the same workloads between machines with different GPUs.
For the vendor-specific compute stacks layered alongside Vulkan, see ROCm for AMD and CUDA for NVIDIA. For how InterGenOS chooses a backend, see Overview & Backend Selection.
Why Vulkan is the default
A from-source distribution favors the path that works everywhere over the path that is tuned to one vendor. Vulkan gives that:
- One API, every GPU. The same Vulkan code runs on AMD, Intel, and NVIDIA.
- Open by default. The Mesa-based drivers (RADV for AMD, ANV for Intel) are open source and integrate with the rest of the from-source build, so there is no opaque binary blob in the default path.
- No vendor lock-in. Choosing Vulkan does not commit you to a proprietary compute runtime. ROCm and CUDA remain available as deliberate, opt-in choices when a specific workload needs them.
Defaulting to an open, vendor-neutral graphics path is part of giving you a machine you understand, can modify, and can trust.
What Vulkan is used for
- Desktop and display. InterGenOS ships GNOME 49 on Wayland today. The compositor and accelerated applications draw through the GPU’s Vulkan/Mesa stack.
- Local AI inference. The built-in InterGen assistant
detects the host’s RAM and GPU and selects a model tier accordingly. Its
inference engine (
llama-server, from llama.cpp) can use a Vulkan backend to accelerate inference on GPUs from any vendor, which is what makes the vendor-neutral path useful beyond the desktop.
Drivers in the default path
Vulkan support is provided by per-vendor ICDs:
- AMD — RADV (the Mesa Vulkan driver for Radeon hardware).
- Intel — ANV (the Mesa Vulkan driver for Intel graphics).
- NVIDIA — Vulkan is supported through NVIDIA’s driver. The open Mesa path (NVK) and NVIDIA’s proprietary driver differ in maturity and packaging; see CUDA for NVIDIA and Per-GPU Driver Notes for the NVIDIA specifics.
InterGenOS is built from source across six package tiers (toolchain, core, base, desktop, ai, and extra). The graphics and Vulkan components live in the build rather than being pulled from an external binary repository at install time. The exact tier placement and package names are part of the build manifest.
Checking your setup
Standard upstream Vulkan tooling is the vendor-neutral way to inspect what your machine reports.
# List the Vulkan ICDs, layers, and device(s) the loader can see
vulkaninfo --summary
# Quick visual smoke test that a device renders
vkcube
If these tools are not present, install them through pkm, the InterGenOS package manager. Confirm the exact package name on your install rather than assuming it.
When to step beyond Vulkan
Vulkan covers graphics and a growing range of compute. For workloads that target a vendor’s dedicated compute runtime, InterGenOS keeps those as explicit choices:
- AMD compute — ROCm for AMD, built from source.
- NVIDIA CUDA — CUDA for NVIDIA, opt-in.
These do not replace the Vulkan default; they sit alongside it for workloads that require them. The vendor-neutral path remains the baseline so that the system behaves predictably regardless of which GPU is installed.
See also
- Overview & Backend Selection
- Per-GPU Driver Notes
- ROCm for AMD
- CUDA for NVIDIA
- GPU Compute & AI Workloads
ROCm for AMD (automated from-source)
ROCm is AMD’s open compute stack: the runtime, the HIP programming layer, and the math and acceleration libraries that let AMD Radeon and Instinct GPUs run compute workloads. On InterGenOS, ROCm is the opt-in vendor-tuned backend for AMD hardware, the higher-throughput alternative to the vendor-neutral Vulkan default for local AI inference.
The InterGenOS approach to ROCm is the same approach that runs through the rest of the system: build it from source, pin and checksum every input, and ship something you can verify rather than a vendor binary you have to trust on faith. This page describes the intent of automated ROCm-from-source enablement and the state of AMD GPU support today. Concrete versions, package names, and commands for the compute stack are pending and are flagged as such below; this page will state them as current only once they ship in a build.
Status. This is InterGenOS 1.0-dev (build id
v1.0-dev1). Automated ROCm-from-source is the AMD compute backend we are building toward, not part of a current release. What ships today for AMD hardware is the graphics and diagnostics stack described under What ships today. Do not read the compute sections as describing installed software.
Why from source
A precompiled compute stack is exactly the kind of opaque shortcut InterGenOS rejects. ROCm is large, it reaches deep into the kernel driver interface, and a binary drop hides how it was built and against what. Building it from source serves the two things that matter here: it keeps the user in control of a machine they understand, can modify, and can trust; and it removes a class of silent failure, because every input is pinned, checksum-verified, and built in deterministic order rather than taken on a vendor’s word.
The same discipline that governs the rest of the build applies. When a compute component fails to build, the cause is fixed in the source tree, not worked around: no disabling a feature to dodge a missing dependency, no stub that pretends to work, no package quietly moved to a different tier to sidestep a wiring problem. A component is trusted only when a clean build reproduces it with zero manual steps, and validation happens on real AMD hardware that reproduces the behavior, never on a hand-patched development box.
What “automated” means
Automated enablement is the goal that a user with supported AMD hardware does not hand-assemble a compute toolchain. The system detects the GPU, and the ROCm backend is made available through the standard package path — the same pinned, reproducible, signed-mirror path every other package takes — without manual driver surgery. The ambition is that enabling AMD compute is a deliberate install action, not a build project the user has to run themselves.
Because a vendor runtime enlarges the trusted surface of an install, this backend is opt-in and off by default. The default install reasons on the Vulkan backend, which runs across AMD, Intel, and NVIDIA open drivers without a vendor SDK. You choose to add ROCm; you do not have to remove it.
The kernel side of AMD support is already in place. The amdgpu kernel driver and
AMD firmware ship in the base image, so the hardware is driven from first boot. The
compute stack layers on top of that foundation.
What ships today for AMD GPUs
AMD graphics support is current and on by default. The amdgpu kernel driver and
AMD firmware are part of the base image, and Mesa provides the radeonsi OpenGL
driver and the radv Vulkan driver for GCN-generation hardware and newer.
Beyond the baseline, InterGenOS provides an amdgpu meta-package (in the extra
tier) that pulls in the user-facing AMD diagnostic and translation tools Mesa does
not install on its own:
- VA-API capability reporting (
vainfo) - Vulkan capability reporting and a test renderer (
vulkaninfo,vkcube) - Live GPU monitoring (
radeontopandamdgpu_top) - VDPAU-to-VA-API translation for legacy applications (
libvdpau-va-gl)
This meta-package is a single, transparent install surface for AMD graphics tooling. It does not provide ROCm; the compute stack is a separate concern and is the subject of the rest of this page.
How to read versions and counts
Package counts and tier contents drift between builds. As of 2026-06-15 the tree spans six tiers — toolchain, core, base, desktop, ai, and extra — for roughly 857 packages in total. Treat any number here as a snapshot derived live from the tree, not a permanent figure, and check the current release notes for the authoritative state.
How it is built
The build of the AMD compute stack follows the same lifecycle as every other InterGenOS artifact: pinned, checksum-verified sources compiled in an isolated, reproducible environment, in a fixed phase order, with no silent failures and no stubs. The contributor-facing mechanics of the compute build live in the ROCm-from-Source Build Pipeline reference.
Verification
When the compute stack ships, it inherits the trust properties of every InterGenOS artifact: pinned and checksum-verified sources, a reproducible build, delivery through a signed package mirror whose index is signed as a whole, and a system image sealed by a signed Secure Boot chain with integrity verification. You verify the software you are running rather than trusting an unverified claim about it.
See also
- Overview & backend selection
- Vulkan (default backend)
- CUDA for NVIDIA (opt-in)
- Per-GPU guidance
- ROCm-from-Source Build Pipeline
- Forge installer guide
- FAQ
CUDA for NVIDIA (opt-in mirror)
NVIDIA GPU support on InterGenOS is mirror-only and opt-in. The driver
never ships on the ISO and never installs without an explicit action on your
part. This page covers what the nvidia package provides, how the CUDA
runtime fits in, and how to install it on a machine that has NVIDIA hardware.
The design here follows the same standard as the rest of the system: a machine you understand, can modify, and can trust. Every default in this package is chosen so that the fewest things run, the signing chain is enforced, and every load-bearing flag is visible at an obvious location you can audit.
What ships and what does not
The nvidia package (production branch 580.159.04) bundles two pieces:
- The open GPU kernel modules (
open-gpu-kernel-modules), dual-licensed GPLv2/MIT. These are shipped as source to/usr/src/, then built and signed against your installed kernel on your own machine at install time. - The closed-source NVIDIA userspace libraries extracted from the official
NVIDIA
.runinstaller, including the GLX/EGL vendor libraries and the CUDA driver runtime that ships inside the driver package.
This package is the GPU driver, which includes the CUDA driver runtime and the userspace tooling NVIDIA bundles with it:
nvidia-smi— device query and monitoringnvidia-settings,nvidia-xconfignvidia-modprobe(installed setuid root so it can create/dev/nvidia*device nodes on first access)nvidia-cuda-mps-controlandnvidia-cuda-mps-server— the CUDA Multi-Process Service control planenvidia-debugdump,nvidia-bug-report.shprime-run— the PRIME offload wrapper for hybrid laptops
The CUDA Toolkit (the nvcc compiler, the math libraries, the samples) is
a separate component and is not part of this package today. The driver provides
the CUDA runtime that compiled CUDA programs link against at execution time.
Hardware floor and install gate
NVIDIA support requires Turing (RTX 20xx / GTX 16xx) or newer. The open
kernel modules depend on GSP firmware, which is only available on Turing and
later silicon. Pre-Turing cards fall back to the in-kernel nouveau driver,
which is already shipped.
Installation is gated on hardware. The package declares a PCI vendor
requirement of 10de (NVIDIA), and the installer (Forge) and TUI skip it
unless a display controller with that vendor ID is present on the target. This
gate is fail-closed: if the GPU vendor cannot be detected, the package is
skipped rather than installed. This prevents the driver from landing on a
machine that cannot use it, which would otherwise break the desktop session.
You can always add it later by hand once you know your hardware qualifies.
Installing the driver
On a machine with qualifying NVIDIA hardware:
sudo pkm install nvidia
Two things happen during install that are specific to this package:
-
EULA acceptance. The NVIDIA closed userspace is covered by NVIDIA’s license. Before the install proceeds,
pkmruns an EULA helper that checks the system-wide marker at/var/lib/intergen/eula/nvidia-userspace.accepted. If the marker is missing, the helper fetches, presents, and asks you to accept the license, or to decline and abort the install. -
Build and sign on your machine. The post-install hook compiles the open kernel modules against your running kernel, then signs each
nvidia*.kowith your per-machine Machine Owner Key (MOK). This is a DKMS-style flow wired directly intopkmhooks rather than relying on thedkmstool. The same rebuild runs automatically on every kernel upgrade, chained from the kernel package’s own post-install hook.
The kernel enforces CONFIG_MODULE_SIG_FORCE=y: every loadable module must
carry a valid signature from a trusted key or it is rejected. NVIDIA’s modules
are not exempt. The MOK that signs them is generated by Forge at install time
and enrolled at the firmware level on first boot through MokManager. See
Verifying the install for the recovery path if the
MOK is not enrolled.
CUDA runtime and Unified Memory
CUDA workloads depend on the nvidia-uvm kernel module, which provides Unified
Memory support through Heterogeneous Memory Management (HMM). HMM is enabled by
default:
options nvidia-uvm uvm_disable_hmm=0
Disable HMM only if you have hit a specific HMM-related bug. CUDA Unified Memory requires it.
For compute hosts that run long-lived CUDA jobs, the persistence daemon keeps driver state resident so the GPU does not tear down and re-initialize between jobs:
-
nvidia-persistenced.serviceis shipped disabled by default. It runs as a system user but holds persistent/dev/nvidiactlhandles, so desktop users do not need it. Compute users opt in:sudo systemctl enable --now nvidia-persistenced.service
The CUDA Multi-Process Service (MPS) control tools
(nvidia-cuda-mps-control, nvidia-cuda-mps-server) are installed for users
who run multiple CUDA processes that need to share a single GPU context.
Kernel cmdline and Wayland
The package ships /etc/kernel/cmdline.d/40-nvidia.conf with:
nvidia-drm.modeset=1 nvidia-drm.fbdev=1
nvidia-drm.modeset=1enables Kernel Mode Setting, which Wayland compositors require. GDM reads/sys/module/nvidia_drm/parameters/modeset; with this set it picks Wayland rather than falling back to X11.nvidia-drm.fbdev=1provides a kernel framebuffer device, required on Linux 6.11 and newer. InterGenOS ships kernel 6.18.10, so this is non-negotiable.
These flags live on the kernel cmdline rather than in modprobe.d so they are
auditable at the most discoverable place:
cat /proc/cmdline
The fragments under /etc/kernel/cmdline.d/ are merged into the signed UKI
.cmdline section at UKI rebuild time. The desktop shipped today is GNOME 49
on Wayland.
To add your own kernel parameters, drop a file such as
/etc/kernel/cmdline.d/90-user.conf, then trigger a UKI rebuild:
sudo pkm reinstall linux-kernel
Modprobe-layer policy
Boot-affecting flags live on the cmdline; modprobe.d is reserved for
module-load policy. The package ships
/etc/modprobe.d/nvidia-nouveau-blacklist.conf:
blacklist nouveau
options nouveau modeset=0
This belt-and-suspenders pattern blocks nouveau from loading and from
attaching via the early-KMS auto-detect path, so it cannot fight NVIDIA for the
framebuffer.
Optional module options go in a file like /etc/modprobe.d/nvidia-extras.conf.
The most common is the GSP-firmware workaround for Ampere mobile (RTX 30xx)
laptops whose GSP firmware prevents the open modules from loading:
options nvidia NVreg_EnableGpuFirmware=0
Do not use this on desktop Ampere or any Ada/Blackwell hardware; those need GSP. Driver 580 has working GSP firmware for Ada and Blackwell laptops.
Hybrid graphics (laptops)
Most NVIDIA laptops are dual-GPU (“Optimus” / hybrid): an Intel iGPU for power-efficient desktop work and an NVIDIA dGPU for heavy workloads. The package supports all three BIOS GPU modes (hybrid, iGPU-only, dGPU-only).
By default the package installs /etc/environment.d/91-nvidia-wayland.conf,
which routes the system-wide compositor and OpenGL/GLX apps to NVIDIA. This is
the right default for users who installed the driver because they want the
dGPU active, but it keeps the dGPU awake whenever the display is on, which
costs battery.
To run the desktop on Intel and use NVIDIA only on demand, remove that file and launch GPU-heavy apps through the offload wrapper:
sudo rm /etc/environment.d/91-nvidia-wayland.conf
# log out and back in, then:
prime-run <application>
GNOME 49 also exposes this in the GUI: right-click a .desktop entry and
choose “Launch using Discrete Graphics Card.”
Suspend, resume, and hibernate
Three services are shipped enabled because lid-close/lid-open is expected to work on a laptop and NVIDIA suspend/resume otherwise breaks graphics:
nvidia-suspend.service— saves VRAM before suspendnvidia-resume.service— restores VRAM after resumenvidia-hibernate.service— saves VRAM to swap at hibernate
On a desktop tower that never suspends, or to keep running daemons to a minimum (fewer services is fewer attack surfaces), you can disable any or all of them:
sudo systemctl disable --now nvidia-suspend.service
sudo systemctl disable --now nvidia-resume.service
sudo systemctl disable --now nvidia-hibernate.service
Verifying the install
After install and reboot, confirm the modules are loaded, signed, and that
nouveau is absent:
cat /sys/module/nvidia_drm/parameters/modeset # expect: Y
cat /sys/module/nvidia_drm/parameters/fbdev # expect: Y
lsmod | grep -E 'nvidia|nouveau' # nouveau should be absent
modinfo -F signer /lib/modules/$(uname -r)/extra/nvidia/nvidia.ko
# expect: InterGenOS Machine Owner Key
nvidia-smi # device query
A clean module load is silent in the kernel log. The failure case to watch for is:
nvidia: module verification failed: signature and/or required key missing
which means the MOK is not enrolled. Re-stage enrollment, reboot, and accept it at the MokManager prompt:
sudo mokutil --import /var/lib/intergen/mok/mok.der
You can confirm Secure Boot and MOK state at any time:
mokutil --sb-state # is Secure Boot on?
mokutil --list-enrolled # is the InterGenOS MOK enrolled?
Removing the driver
sudo pkm remove nvidia
Removal stops the NVIDIA services, unloads the modules, purges the built .ko
files, removes the shipped cmdline and modprobe fragments, and triggers a UKI
rebuild so the signed .cmdline section no longer carries the NVIDIA
parameters. On the next boot, nouveau is the active GPU driver again.
See also
PyTorch / TensorFlow / JAX
This page covers the blessed path for running the major Python machine-learning frameworks (PyTorch, TensorFlow, JAX) on InterGenOS, and how that path relates to the GPU acceleration stack the system already provides.
InterGenOS is a built-from-source distribution. The guiding principle holds here as everywhere else: you should end up with a machine you understand, can modify, and can trust. ML tooling is no exception, and nothing on this page bypasses the system’s signed Secure Boot chain, dm-verity integrity, or the safety posture of the local assistant.
What ships today
InterGenOS 1.0-dev (build id v1.0-dev1) is assembled across six package tiers (toolchain, core, base, desktop, ai, extra) in a 20-phase build. The ai tier is small and focused: it carries the components of the InterGen local assistant rather than a general-purpose data-science stack.
The shipping AI layer is the local assistant stack:
- InterGen is a tiered, hardware-detected, offline-first local assistant built on Qwen models with zero telemetry. It probes RAM and GPU on the host and selects an appropriately sized model. Inference is served locally over an HTTP API by a
llama-serversubprocess from llama.cpp. - InterGen Sentinel is a pluggable security scanner. Its default configuration runs entirely on-device: a fast local-rules pass plus an optional deep pass backed by a small local Qwen classifier. Six cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), DeepSeek) are opt-in only; none is configured by default.
This matters for ML work because the assistant’s inference path (llama.cpp serving a quantized Qwen model) is independent of the Python framework stack you would use for training or general tensor compute. Running PyTorch, TensorFlow, or JAX does not interfere with InterGen, and InterGen does not depend on them.
The blessed path
The supported, repeatable way to run these frameworks on InterGenOS is to install them into a project-local Python virtual environment rather than into the system Python. This keeps framework dependencies out of the verified system image, leaves the integrity-checked base untouched, and makes each project reproducible and disposable.
The general shape of the path is:
- Confirm your GPU is detected and the acceleration runtime is present (see the other GPU pages in this section).
- Create a per-project virtual environment.
- Install the framework build that matches your accelerator into that environment.
- Verify the framework can see the GPU before you rely on it.
Each framework distributes accelerator-specific builds. You install the build that matches the GPU and runtime on your machine; a CPU-only build will run but will not use the GPU.
GPU detection vs. framework GPU support
A working desktop GPU under GNOME 49 on Wayland (the desktop InterGenOS ships today) is not the same thing as a framework-visible compute device. Verify both layers:
- The system sees the GPU (kernel driver loaded, device present).
- The framework sees the GPU (its own device query reports the accelerator).
Use each framework’s built-in device check after installation:
- PyTorch exposes a runtime check for accelerator availability and device count.
- TensorFlow can list the physical compute devices it has registered.
- JAX reports the active backend and the devices bound to it.
If the system sees the GPU but the framework does not, the mismatch is almost always between the framework build you installed and the accelerator runtime on the host. Reinstall the framework build that matches your runtime rather than changing the system.
Staying inside the security posture
Two things to keep in mind:
- Frameworks pull large dependency trees from external indexes. That is content crossing into your machine. Treat third-party model weights and packages with the same care as any other untrusted download, and prefer pinned, hash-checked installs inside the project environment.
- InterGen’s safety classifier still applies to assistant-driven actions. If you ask the local assistant to set up or manage a framework environment, state-changing steps are surfaced for confirmation and destructive operations are refused outright. Having the assistant manage your environment does not weaken that boundary.
Related pages
Language-Runtime Foundations
InterGenOS ships a built-from-source toolchain and a set of language runtimes that the AI subsystem and other workloads run on. This page explains what those foundations are, where they come from, and how the local AI assistant uses them. The goal is the same one that runs through the whole system: a machine you understand, can modify, and can trust.
This is version 1.0-dev (build id v1.0-dev1). Package counts below are derived from the live package tree and drift over time; treat them as a snapshot, not a fixed contract.
Where runtimes come from
Everything is built from source through a staged pipeline rather than assembled from prebuilt binaries. The build runs in 20 phases:
validate → verify-sources → setup → toolchain → chroot-prep → chroot-tools → core → config → core-extra → base → kernel → desktop → ai → extra → bootloader → image → manifest → squashfs → ukis-verity → iso
A publish phase is optional and runs after the others.
The runtime foundations are laid early. The toolchain phase builds the compiler and core build tooling that every later phase depends on; the core and base phases bring in the system libraries and language runtimes that user-facing software links against; and the ai phase builds the assistant on top of those runtimes.
Packages are organized into six tiers. As of this writing the live tree holds roughly:
| Tier | Packages (approx.) |
|---|---|
| toolchain | 28 |
| core | 272 |
| base | 23 |
| desktop | 420 |
| extra | 112 |
| ai | 2 |
| Total | ~857 |
These numbers move as packages are added and consolidated. Derive the current counts from the package tree rather than quoting these as permanent.
The runtime the AI subsystem uses
The local assistant, InterGen, is a tiered, hardware-detected, offline-first local assistant with zero telemetry. It runs entirely on the local machine by default, with no cloud dependency, and selects a model sized to the hardware it detects.
InterGen has two distinct runtime layers, and separating them helps because they place different demands on the system:
-
The model-serving layer. InterGen serves its selected model through
llama-server, the HTTP server from llama.cpp, managed as a subprocess (intergen/llama_manager.py). This is the native, compiled inference runtime that does the heavy numeric work and is the component that benefits from GPU acceleration. It exposes the model over a local HTTP API. -
The orchestration layer. The router, safety classifier, hardware probe, model manager, memory store, D-Bus service, and MCP client are organized as modules (
intergen/router.py,intergen/safety.py,intergen/hardware.py,intergen/model_manager.py,intergen/memory.py,intergen/state_cache.py,intergen/dbus_daemon.py,intergen/mcp_client.py). These coordinate the assistant: deciding how to answer a request, classifying its safety, and managing state.
These orchestration modules run on the shipping Python runtime, which is Python 3.14 (3.14.3 in the current build).
The split matters for runtime planning. The orchestration layer is light and predictable. The model-serving layer is where memory and GPU capacity decide which model can run at all.
Hardware tiers and what they need
InterGen probes RAM and GPU at startup (intergen/hardware.py) and assigns a tier; the model catalog and selection live in intergen/model_manager.py. The shipping tiers are:
- Tier 1 (2B, Basic) — Qwen3.5-2B Q4_K_M, about 1.5 GB. Selected on systems with under 8 GB of RAM (GPU is not a factor at this RAM level). Handles semantic matching, system queries, and keyword extraction. Not used for complex code generation.
- Tier 2 (9B, Standard) — Qwen3.5-9B Q4_K_M, about 5.5 GB. Selected on systems with 8 to 15 GB of RAM. The default daily driver: coding, configuration, and reasoning. On a Tier 2 machine without a discrete GPU, InterGen falls back to the 2B model to keep response latency usable.
- Tier 3 (35B, Advanced) — Qwen3.5-35B-A3B Q4_K_M, a Mixture-of-Experts model, about 21 GB. Selected on systems with 16 GB or more of RAM and a discrete GPU. Used for deep multi-file analysis and complex architectural reasoning.
A small embedding model (nomic-embed-text, Apache-2.0) ships alongside every tier to power the router’s semantic-matching layer.
The GPU is what unlocks the larger tiers and keeps response latency usable: without a discrete GPU, a system that would otherwise reach Tier 2 falls back to the smaller model. For detecting and configuring the GPU and its compute backend, see the Overview & Backend Selection page.
How the runtime resolves a request
InterGen does not hand every prompt to the model. A priority-ordered router (intergen/router.py) tries to satisfy each request with the cheapest, most predictable method first and only escalates the runtime cost when it has to:
- Priority 0 (Decomposition) — splits compound requests into sub-tasks and routes each in turn.
- Priority 1 (Keyword/Regex Match) — fast pattern matches for common system commands, dispatched to a built-in tool without invoking the model.
- Priority 2 (Semantic Embedding Match) — lightweight embedding search against a precomputed capability catalog; a high-confidence match dispatches to a built-in tool.
- Priority 3 (LLM Tool Calling) — for Tier 2 and above, the query plus a tool schema goes to the model, which selects a tool and arguments for the router to execute.
- Priority 4 (LLM Free Response) — the fallback: the model answers conversationally from its own knowledge and the conversation context.
The practical effect is that most interactions never touch the model-serving runtime at all, which keeps the system responsive even on modest hardware.
Safety classification at the runtime boundary
Every action the router proposes passes through the classifier in intergen/safety.py, which sorts it into one of three tiers:
AUTO— read-only or harmless operations (for examplels,grep,systemctl status). Run immediately.CONFIRM— state-changing operations (for examplesystemctl restart,pkm install, or editing a config file). The assistant pauses and asks for approval first.BLOCKED— destructive or security-bypassing operations (for examplerm -rf /). Refused outright, with an explanation.
Nothing that changes the system runs without explicit approval, and the most dangerous commands cannot run at all.
Crossing the network boundary
Two features can take a request off-device, and both run only when you ask:
- InterGen Sentinel is a pluggable security scanner that inspects content crossing the ingress and egress boundaries. Its default configuration runs two local stages: a fast local-rules pass and an optional deep pass backed by a small local Qwen classifier. For deeper analysis you may opt in to one of six cloud providers: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), or DeepSeek. None is configured by default, so a default install scans entirely on-device.
- Phone-A-Friend (Frontier/Cloud Escalation) is an optional, consent-first path that hands a request to a more capable frontier model in the cloud when the local assistant cannot satisfy it. It is off by default; the same six providers can be configured, with API keys stored in the system keyring. Every outbound payload is scanned by Sentinel’s egress policy before it leaves the machine.
The rest of the platform
Beyond the AI subsystem, the same source-built foundations support the shipping system: pkm (the package manager), Forge (the installer), a signed Secure Boot chain, dm-verity integrity, and UKI signing. The shipping desktop is GNOME 49 on Wayland.
See also
Per-GPU Driver Notes
This page collects device-specific driver notes for the three GPU vendors InterGenOS supports: AMD, NVIDIA, and Intel. It covers what ships by default, where the vendor-specific configuration lives, and the device quirks worth knowing before you commit to a setup.
The guiding principle here is the same one that runs through the rest of the system: a machine you understand, can modify, and can trust. Every load-bearing driver flag lives somewhere you can read it back, and the proprietary paths are opt-in rather than baked into the default install. A default that pulls in a large vendor driver stack expands the trusted surface of every install whether or not that hardware is present, so the open, vendor-neutral path is the default and the vendor stacks are something you choose to add.
For backend selection (which compute path inference uses) see Overview & Backend Selection. This page is about the kernel-level GPU driver itself.
AMD
AMD GPUs run on the open in-kernel amdgpu driver that ships with the kernel. There is no separate proprietary kernel module to install, sign, or rebuild for graphics and Vulkan, so AMD is the lowest-friction path on InterGenOS: the default image drives the display and accelerates Vulkan inference out of the box.
For the ROCm compute stack used by the opt-in AMD inference backend, see ROCm (AMD) and the ROCm-from-Source Build Pipeline. ROCm is a userspace toolkit layered on top of the same in-kernel amdgpu driver; enabling it does not replace the graphics driver.
NVIDIA
NVIDIA support is provided by the opt-in nvidia package in the extra tier, built around NVIDIA’s open kernel modules. The package is the most involved of the three because the modules are out-of-tree and must be built and signed against your running kernel. It is mirror-only: it never lands on an ISO without explicit action, and it carries a hardware floor (Turing-class / RTX 20xx / GTX 16xx or newer); pre-Turing hardware falls back to the in-kernel nouveau driver.
What the package ships by default
- Kernel cmdline fragment at
/etc/kernel/cmdline.d/40-nvidia.confcarryingnvidia-drm.modeset=1 nvidia-drm.fbdev=1.modeset=1enables Kernel Mode Setting, which Wayland requires.fbdev=1provides a kernel framebuffer device, required on Linux 6.11 and later (InterGenOS ships kernel 6.18.10). These flags affect boot, so they live on the kernel cmdline rather than inmodprobe.d; the kernel post-install hook mergescmdline.dfragments into the signed UKI’s.cmdlinesection at UKI-rebuild time. - Nouveau blacklist at
/etc/modprobe.d/nvidia-nouveau-blacklist.confwith bothblacklist nouveauandoptions nouveau modeset=0. The two-line pattern is deliberate: the blacklist covers the modules-load and udev paths, andmodeset=0covers the early-KMS auto-detect path that would otherwise bring nouveau up to fight nvidia for the framebuffer. - Wayland environment defaults at
/etc/environment.d/91-nvidia-wayland.confsettingGBM_BACKEND=nvidia-drmand__GLX_VENDOR_LIBRARY_NAME=nvidia, routing the compositor and GL/GLX applications to NVIDIA’s libraries. prime-runwrapper for per-application PRIME offload on hybrid laptops.- VRAM save/restore services enabled by default to preserve VRAM contents across sleep transitions:
nvidia-suspend.service,nvidia-resume.service, andnvidia-hibernate.service. (nvidia-persistenced.serviceships disabled; compute users opt into it explicitly.)
Where these flags live, and why some sit on the kernel cmdline while others sit in modprobe.d, is split by mechanism: boot-time flags the kernel reads before modprobe runs go on the cmdline (auditable at cat /proc/cmdline); module-load policy and post-boot module options go in modprobe.d (auditable at lsmod and modinfo).
Module signing
The kernel ships CONFIG_MODULE_SIG_FORCE=y, so every loadable module must carry a signature from a key the kernel trusts. NVIDIA’s modules are not exempt. At install time the package signs each freshly built nvidia*.ko with the per-machine Machine Owner Key (MOK) that Forge generated during installation, using the kernel-native scripts/sign-file (PKCS#7); that MOK is enrolled at the firmware level on first boot through MokManager and chains through the kernel’s secondary trusted keyring under CONFIG_MODULE_SIG_FORCE=y.
If modprobe nvidia fails with “Required key not available” after install, the most common cause is that the MOK was never enrolled or enrollment was declined at the MokManager prompt. Quick check:
mokutil --sb-state # is Secure Boot on?
mokutil --list-enrolled # is the InterGenOS MOK enrolled?
Hybrid graphics (Optimus / MUX laptops)
Most NVIDIA laptops pair an Intel iGPU with an NVIDIA dGPU. The package supports the common BIOS configurations (hybrid, iGPU-only, dGPU-only). The shipped default routes the system-wide Wayland session to NVIDIA, which means the dGPU stays awake whenever the display is active. That is the right default for someone who installed the package specifically to use the dGPU, but it costs battery.
To run iGPU-default with NVIDIA on demand, remove the system-wide Wayland defaults and launch GPU-heavy apps through prime-run:
sudo rm /etc/environment.d/91-nvidia-wayland.conf
# log out and back in, then:
prime-run <application>
GNOME 49 exposes the same offload path in the GUI through “Launch using Discrete Graphics Card” on a .desktop entry’s right-click menu.
Device-specific notes
- Ampere mobile (RTX 30xx laptops): some parts have GSP firmware bugs that prevent the open kernel modules from loading. The workaround is to disable GSP firmware load by adding
options nvidia NVreg_EnableGpuFirmware=0to a file under/etc/modprobe.d/(any name modprobe reads, e.g.nvidia-extras.conf), then rebuilding the modules and rebooting. This costs a slightly larger driver memory footprint and disables some advanced features. Do not apply it to desktop Ampere or to Ada / Blackwell hardware, which need GSP. - Ada / Blackwell laptops: working GSP firmware in driver 580; no known issues with the default configuration.
- Hybrid battery savings:
options nvidia NVreg_DynamicPowerManagement=0x02powers the dGPU down to D3 when idle, reducing idle draw on Optimus systems. - Runtime MUX switching: InterGenOS does not currently expose a UI for live BIOS-level GPU swap. Use your laptop vendor’s tool or the BIOS menu.
For the opt-in CUDA inference backend, see CUDA (NVIDIA). CUDA is a userspace runtime layered on top of these kernel modules.
Intel
Intel integrated GPUs run on the open in-kernel i915 driver that ships with the kernel, the same driver that drives the display on NVIDIA hybrid laptops in their default hybrid BIOS mode. As with AMD, there is no proprietary kernel module to install or sign for graphics and Vulkan, and the default image accelerates Vulkan inference on Intel iGPUs through the open driver.
At a glance
| Vendor | Kernel driver | Ships by default | Signing required | Inference backend |
|---|---|---|---|---|
| AMD | amdgpu (in-tree) | Yes | No | Vulkan (default), ROCm (opt-in) |
| NVIDIA | open kernel modules (out-of-tree, nvidia package) | No (opt-in extra tier) | Yes (MOK) | Vulkan (default), CUDA (opt-in) |
| Intel | i915 (in-tree) | Yes | No | Vulkan (default) |
See also
- Overview & Backend Selection
- Vulkan (default)
- ROCm (AMD)
- CUDA (NVIDIA)
- Forge installer guide
- Verified Boot & Secure Boot
Security Handbook
Security is not first. It is only.
That sentence is the design constraint behind every default in this section. When a security control conflicts with convenience, the control wins. InterGenOS is built to be a machine you understand, can modify, and can trust, and the protections described here are enforced from the moment the system boots, not bolted on by a post-install hardening script.
This handbook is the reference spine for how InterGenOS protects you by default and how to reason about changes you make yourself. It is written for two audiences: end users who want to know what is guarding their machine, and contributors who need to verify those guarantees against the source tree.
What InterGenOS Enforces Out of the Box
InterGenOS does not rely on optional toggles or opt-out privacy menus. The baseline posture is:
- Signed boot chain. A Microsoft-signed shim validates the GRUB bootloader, which verifies the Linux kernel and Unified Kernel Images. Secure Boot enforcement is optional and off by default on the current fleet; with it enabled, unsigned kernel modules are not trusted. See Encryption, Keys & TPM2 and Verified Boot & Secure Boot.
- AppArmor in enforce mode. System daemons ship with profiles in enforce mode by default, not complain mode. See Sandboxing & Mandatory Access Control.
- Aggressive systemd sandboxing. System services run under extensive isolation directives (
NoNewPrivileges,ProtectSystem=strict,ProtectHome,PrivateTmp, syscall filtering, and more) to limit the blast radius of any single compromise. See Hardening Baseline. - Safe network binds. Server packages bind to localhost by default and never listen on a public interface unless you deliberately change their configuration. See Network Security & Firewalling.
- No default passwords. InterGenOS ships no services with blank or default credentials. Initial secrets are randomly generated or require setup during installation.
- A signed binary mirror.
pkm syncverifies the package index signature against a release-signing subkey held on a hardware token and certified by the offline master key, andpkmvalidates each package’s SHA-256 hash locally before installation. See Registry-Trust Boundary. - A from-source, verifiable build chain. Every package is built from source in an isolated build VM that is reset to a known-good snapshot before each build, with reproducible vendoring for Rust and Go and a deterministic SPDX 2.3 JSON SBOM published for the Secure Boot shim, the trust anchor of the boot chain.
The complete system is assembled from source across six package tiers (toolchain, core, base, desktop, ai, and extra) through a 20-phase build that ends in a signed, dm-verity-protected ISO image.
What InterGenOS Does Not Do
- No telemetry. Zero analytics, crash reports, or usage statistics are collected.
- No auto-updates. Software does not change behind your back. Upgrades happen only when you run
pkm upgrade. - No opt-out privacy. There is no toggle to stop data leaving your machine, because the data never leaves to begin with.
- No forced proprietary firmware in core. The core system uses open-source drivers and firmware. Proprietary blobs are available only if your hardware strictly requires them.
How This Section Is Organized
Each page below goes deep on one layer of the defense-in-depth model. Read them in order for a full picture, or jump to the layer you are auditing.
- Hardening Baseline — the system-wide defaults applied to every service and daemon.
- Attack-Surface Minimization — what is installed, what is reachable, and how that surface is kept small.
- Sandboxing & Mandatory Access Control — AppArmor enforce-mode profiles and systemd confinement.
- Kernel Hardening — kernel-level protections and tunables.
- Encryption, Keys & TPM2 — Secure Boot, the MOK enrollment flow, UKI signing, and disk encryption.
- Network Security & Firewalling — localhost-by-default binds and network controls.
- Auditing & Logging — what is recorded and how to review it.
- Registry-Trust Boundary — the signed mirror, index-only signature trust, and supply-chain protections.
- Self-Hosting Securely — running your own mirror or services without weakening the trust model.
The Security Tooling That Ships
InterGenOS includes InterGen Sentinel, a pluggable security scanner. By default it runs entirely on your machine using its Local-Rules engine and the local InterGen assistant (a hardware-detected, offline-first local model based on Qwen, with zero telemetry). Sentinel can also use Phone-A-Friend (Frontier/Cloud Escalation), an explicitly opt-in path to one of six cloud providers: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), or DeepSeek. Cloud escalation is never automatic and never the default; you choose it, per request, when you want a frontier model’s second opinion. The local-only posture is described in The AI Assistant: Privacy & Data Locality.
Reasoning About Changes You Make
Because InterGenOS gives you full control, you can relax any of these defaults. When you do, you own the consequences. Before changing a security default, read the page that documents it so you understand what protection you are trading away and how to compensate. The desktop that ships today is GNOME 49 on Wayland; security guidance in this section is written against that environment.
Where to Go Next
- New to the project? Start with the Threat Model & Security Philosophy.
- Installing now? See Install with FORGE and Verified Boot & Secure Boot.
- Building or verifying packages? See Reproducibility & Verification.
- Reporting a vulnerability or following the disclosure process? See the Security Review & Advisory Process and Security Advisories.
Hardening Baseline
InterGenOS is built on a single doctrine: security is not first. It is only. The goal is a machine you understand, can modify, and can trust. Where a security control conflicts with convenience, the control wins.
This page describes the hardening baseline that ships today in InterGenOS 1.0-dev (build id v1.0-dev1). Nothing here is an optional add-on or a post-install script. The environment is hardened from the moment the system boots.
At a glance
Out of the box, InterGenOS enforces:
- A signed boot chain through the bootloader, kernel, and Unified Kernel Images; Secure Boot enforcement is optional (off by default on the current fleet), so the signatures are present and verifiable, enforced by firmware where you turn it on.
- dm-verity integrity over the read-only system image.
- AppArmor profiles for system daemons in enforce mode.
- Extensive systemd sandboxing applied across system services.
- A package mirror with an end-to-end signed index.
- A strict zero-telemetry, zero-analytics, zero-auto-update privacy boundary.
Secure Boot, UKI signing, and dm-verity
The boot chain is signed end to end (Secure Boot enforcement is optional, off by default on the current fleet).
- The chain is anchored by a Microsoft-signed shim (the pre-signed shim from Fedora) that validates the InterGenOS GRUB bootloader, which in turn verifies the Linux kernel and Unified Kernel Images (UKIs). Unsigned kernel modules are not trusted.
- The InterGenOS release-signing key never leaves a hardware token under InterGenOS control.
- Installed systems regenerate and sign each kernel’s UKI with your machine’s local Machine Owner Key (MOK) at every kernel install or upgrade, so the same boot-time signature verification continues to apply to kernels installed after the original ISO image. Only the MOK that Forge generates on your own machine signs the kernels you install.
- If you need out-of-tree modules such as proprietary drivers, Forge walks you through enrolling a MOK on your first boot.
- The system image is protected by dm-verity, so tampering with the read-only root is detected at boot.
For a deeper walkthrough, see the Verified Boot and Secure Boot guide.
AppArmor in enforce mode
Many distributions leave mandatory access control in complain mode, or disabled for third-party packages. InterGenOS ships AppArmor profiles for system daemons in enforce mode by default.
Systemd sandboxing
System services are sandboxed to minimize the blast radius of a potential compromise. The baseline directives applied across system daemons include:
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
ProtectHostname=true
ProtectClock=true
ProtectProc=invisible
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true
MemoryDenyWriteExecute=true
RemoveIPC=true
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~@privileged @resources @mount @swap @reboot
MemoryDenyWriteExecute=true is relaxed only for packages that explicitly require a JIT. PostgreSQL is the documented example: its service unit sets MemoryDenyWriteExecute=false so the LLVM JIT compiler keeps working.
Network and credential defaults
- Safe network binds: Any server package shipped by InterGenOS binds exclusively to localhost (
127.0.0.1) by default. Services never listen on public interfaces unless you deliberately edit their configuration to allow it. - No default passwords: InterGenOS does not ship databases or services with blank or default “admin” passwords. Initial credentials are randomly generated or require manual setup during installation.
The signed binary mirror
When you install software, you pull from a signed mirror. The index is signed end to end to prevent tampering.
- Every time you run
pkm sync, your machine cryptographically verifies theInterGenOS.dbindex signature against a release-signing subkey held on a hardware token and certified by the offline InterGenOS master key. - When downloading a package, pkm validates the file’s SHA-256 hash locally before installation.
- InterGenOS enforces an index-only signature trust model for the 1.0 release, providing a centralized, verifiable source of truth.
For a deeper look at repository verification, see the Registry Trust Boundary.
The build chain
Every package is built from source in an isolated build VM that is reset to a known-good snapshot before each build. The build runs as 20 phases (validate, verify-sources, setup, toolchain, chroot-prep, chroot-tools, core, config, core-extra, base, kernel, desktop, ai, extra, bootloader, image, manifest, squashfs, ukis-verity, iso), with an optional publish step.
The resulting system is organized into six package tiers: toolchain, core, base, desktop, ai, and extra. The exact package count is derived live from the package definitions at build time and drifts as packages are added or updated. (The toolchain tier is used only to build the system and is not present on an installed machine.)
Supply-chain protections in the build chain include:
- Zero-PyPI methodology: To protect the supply chain during active attack windows targeting Python packages, InterGenOS sources critical dependencies from verified GitHub release tags rather than relying on PyPI. The maturin package definition (
packages/core/maturin/) is an example of this pattern. - Reproducible vendor pipelines: Rust and Go packages use a reproducible cargo-vendor (or equivalent) pipeline. Dependencies are fetched, verified, and packaged offline, so upstream ecosystem volatility cannot break the build or inject compromised code during a compile step.
- Software Bill of Materials (SBOM): InterGenOS publishes a deterministic SPDX 2.3 JSON SBOM for the Secure Boot shim — the boot chain’s trust anchor — detailing exactly which build inputs and source hashes comprise it.
The desktop
The shipped desktop is GNOME 49 on Wayland. The hardening baseline above applies underneath it: system daemons are confined and sandboxed regardless of the desktop session running on top.
AI assistants and the privacy boundary
InterGenOS ships two local-first AI components, both built around the same privacy boundary as the rest of the system.
- InterGen is a tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry. It runs on your machine; nothing is sent to the cloud by default.
- InterGen Sentinel is a pluggable security scanner. Its default backends are Local-Rules and Local-Qwen, which run entirely on-device. Six cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek) are available strictly opt-in, never on by default.
When Sentinel reaches a cloud provider, that escalation path is called Phone-A-Friend (Frontier/Cloud Escalation). It stays off until you turn it on, and it tells you when it is used.
What InterGenOS does not do
Silence is the default.
- No telemetry: InterGenOS collects zero analytics, crash reports, or usage statistics.
- No auto-updates: Your system will not update software behind your back. Upgrades happen only when you explicitly run
pkm upgrade. - No opt-out privacy: You do not have to flip toggles in a settings menu to stop your OS from sending data to the cloud. The data never leaves to begin with.
- No proprietary firmware in core: The core operating system relies exclusively on open-source drivers and firmware. Proprietary blobs are available if your hardware strictly requires them, but they are never forced on you.
Further reading
- New to the system? See the Forge installer guide.
- Have general questions? Check the Frequently Asked Questions.
- Curious how the repository is verified? Read the Registry Trust Boundary.
Attack-Surface Minimization
The most reliable way to defend a machine is to give an adversary fewer things to attack. InterGenOS treats every running service, every open port, every trusted key, and every package on disk as a liability to be justified rather than a default to be accepted. On a machine you understand, can modify, and can trust, the parts that are not present cannot be exploited.
This page describes the attack-surface posture InterGenOS ships today, and the principles behind it.
The principle
A from-source distribution has an unusual advantage: nothing is on the system unless it was deliberately compiled in and packaged. There is no vendor add-on layer, no pre-enabled “convenience” daemon, and no opaque firmware blob pulled in to make first boot smoother. Every component is the result of an explicit decision, run through the project’s lenses before it ships: does it eliminate silent failure, does it keep the machine transparent and under your control, and does it serve the actual goal of the work. A component that cannot pass those tests is not present to be attacked.
Minimization is therefore not a hardening pass applied after the fact. It is a property of how the system is built.
Locked by default
InterGenOS does not rely on post-installation hardening scripts. The environment is hardened from the moment the system boots, and the live ISO ships locked: no remote access enabled, and a default-deny firewall, out of the box.
- No listening on public interfaces. Any server package shipped by InterGenOS binds exclusively to localhost (
127.0.0.1) by default. Services never listen on a public interface unless you deliberately edit their configuration to allow it. - No remote access enabled. The shipped posture exposes nothing to the network until you turn it on yourself.
- No default or blank passwords. InterGenOS does not ship databases or services with blank or default “admin” credentials. Initial credentials are randomly generated or require manual setup during installation.
- No proprietary firmware in core. The core operating system relies exclusively on open-source drivers and firmware. Proprietary blobs are available if your hardware strictly requires them, but they are never forced on you.
Confinement and sandboxing
Reducing the count of running things is the first move. Containing what does run is the second. InterGenOS assumes any single component can be compromised and works to keep the blast radius small.
- AppArmor in enforce mode. Unlike many distributions that leave mandatory access control in complain mode or disabled for third-party packages, InterGenOS ships AppArmor profiles for system daemons in enforce mode by default.
- Aggressive systemd sandboxing. System services are confined with extensive isolation directives so that a compromised daemon cannot reach the rest of the system. The baseline applied across system daemons includes
NoNewPrivileges=true,ProtectSystem=strict,ProtectHome=true,PrivateTmp=true,PrivateDevices=true, theProtectKernel*family (tunables, modules, logs),ProtectControlGroups=true,ProtectProc=invisible,RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6,RestrictNamespaces=true,RestrictRealtime=true,RestrictSUIDSGID=true,LockPersonality=true,MemoryDenyWriteExecute=true(except for packages that genuinely require JIT),RemoveIPC=true,SystemCallArchitectures=native, and aSystemCallFilterrestricted to@system-servicewith privileged, resource, mount, swap, and reboot call groups denied.
Together these mean a service that is breached cannot trivially write outside its sandbox, escalate privileges, read other users’ files, load kernel modules, or open arbitrary network families. The full set of these defaults is covered in the Hardening Baseline.
A small, signed package set
The fewer packages on disk, the fewer code paths an attacker can reach. InterGenOS ships a deliberately scoped package set, organized into six build tiers (toolchain, core, base, desktop, ai, and extra). As of this writing the catalog totals on the order of 850 packages across those tiers; the exact counts drift as the catalog evolves, so derive the live figure from the build manifest rather than treating any single number as fixed.
Everything in that set is built from source in an isolated, snapshot-restored build environment, and the supply chain itself is treated as attack surface:
- Zero-PyPI methodology. To protect against attack windows targeting Python packages, InterGenOS sources critical dependencies from verified upstream release tags rather than relying on PyPI.
- Reproducible vendor pipelines. Rust and Go packages use a reproducible offline vendoring pipeline: dependencies are fetched, verified, and packaged ahead of time, so upstream ecosystem volatility cannot break the build or inject compromised code during a compile step.
- Software Bill of Materials. InterGenOS publishes a deterministic SPDX 2.3 JSON SBOM for the Secure Boot shim — the boot chain’s trust anchor — detailing exactly which build inputs and source hashes comprise it.
Software is installed with pkm, the InterGenOS package manager, which pulls from a signed binary mirror. Every pkm sync cryptographically verifies the repository index signature against a release-signing subkey held on a hardware token and certified by the offline master key, and every package download is validated against its SHA-256 hash locally before installation.
A verifiable boot and integrity chain
Attack surface is not only what runs after boot — it is also everything that decides what is allowed to run. InterGenOS closes that gap with a chain you can verify yourself.
- Signed boot chain. A Microsoft-signed shim validates the InterGenOS bootloader, which verifies the kernel and Unified Kernel Images (UKIs). Secure Boot enforcement is optional and off by default on the current fleet, so the chain is signed and verifiable but not firmware-enforced unless you enable it; with it enabled, unsigned kernel modules are not trusted.
- UKI signing on your own key. The InterGenOS release-signing key never leaves a hardware token under project control. On an installed system, each kernel’s UKI is regenerated and signed with a Machine Owner Key (MOK) that the Forge installer generates on your own machine, so boot-time signature verification keeps applying to kernels you install after the original ISO. If you need out-of-tree modules such as proprietary drivers, Forge walks you through enrolling that MOK on first boot.
- dm-verity integrity. The read-only system image is covered by a verified-integrity hash tree, and that root hash is sealed into the signed kernel command line. With Secure Boot enabled, a tampered system image cannot boot under a validly signed kernel. A whole-file checksum path backs this up, and both are asserted non-empty at build time and verified again at boot.
The full build process that produces this chain runs as 20 ordered phases, from source validation through toolchain, the package tiers, kernel, bootloader, image assembly, squashfs, the UKI and integrity step, and ISO assembly, with an optional publish to the signed mirror. See Verified Boot for the boot-time view of this chain.
What is deliberately absent
The strongest reduction of attack surface is the data and the network traffic that never exists.
- No telemetry. InterGenOS collects zero analytics, crash reports, or usage statistics.
- No auto-updates. Your system will not change software behind your back. Updates happen only when you explicitly run them.
- No opt-out privacy. You do not flip toggles to stop your OS from phoning home. The data never leaves to begin with.
This extends to the optional AI layer. InterGen, the tiered, hardware-detected local assistant, is offline-first and built on local Qwen models with zero telemetry. InterGen Sentinel, the pluggable security scanner, defaults to Local-Rules and a local Qwen model. Any escalation to a frontier model — the six opt-in cloud providers, surfaced as “Phone-A-Friend” (Frontier/Cloud Escalation) — is exactly that: opt-in, never a default, and never a path your data takes without your decision.
Further reading
- Hardening Baseline — the concrete confinement and sandboxing defaults enforced out of the box.
- Forge Guide — the installer, Secure Boot enrollment, and MOK setup.
- Verified Boot — the boot-time integrity and signature chain.
- Frequently Asked Questions — general questions about the system.
Sandboxing & Mandatory Access Control
InterGenOS confines what software can do, not just who is allowed to run it. Two layers work together: a mandatory access control (MAC) policy that constrains every system daemon regardless of its user, and per-service sandboxing that removes the kernel interfaces, file paths, and system calls a service has no legitimate need to touch.
Where a confinement directive conflicts with convenience, confinement wins. The goal is a machine you understand, can modify, and can trust: nothing here is hidden behind a vendor toggle or applied silently after the fact.
This page describes the behavior that ships today in InterGenOS 1.0-dev (build id v1.0-dev1). It is a companion to the Hardening Baseline, which covers the full default posture.
Hardened from boot, not after
InterGenOS does not rely on post-installation hardening scripts. The environment is confined from the moment the system boots. The controls described below are defaults baked into the system services and policies that ship in the image, not options you enable later.
Mandatory Access Control: AppArmor in enforce mode
InterGenOS uses AppArmor as its mandatory access control layer. An AppArmor profile describes, per program, which files a process may read or write, which capabilities it may use, and which network operations it may perform. The kernel enforces those rules even against root, so a compromised daemon is held to the boundaries its profile defines.
Many distributions leave MAC in complain mode (where violations are logged but allowed) or disable it for third-party packages. InterGenOS ships AppArmor profiles for system daemons in enforce mode by default. Violations are blocked, not merely recorded.
If you are authoring or adjusting a profile for your own software, enforce mode is the design point to target. AppArmor’s complain mode remains available as a development aid while you write a profile, but the shipped system daemons do not depend on it.
Per-service sandboxing with systemd
On top of the MAC layer, every system service is sandboxed using systemd’s isolation directives. These shrink the blast radius of a compromise: even if an attacker takes over a service, the service can no longer see most of the filesystem, gain new privileges, reach the kernel’s tunable interfaces, or issue system calls outside a tight allowlist.
The baseline directives applied across system daemons include:
| Directive | Effect |
|---|---|
NoNewPrivileges=true | The service and its children can never gain new privileges (blocks setuid escalation). |
ProtectSystem=strict | The entire filesystem is read-only to the service except explicitly allowed paths. |
ProtectHome=true | User home directories are inaccessible. |
PrivateTmp=true | The service gets a private, isolated /tmp. |
PrivateDevices=true | Only a minimal, virtualized set of devices is visible. |
ProtectKernelTunables=true | Kernel tunables (/proc/sys, /sys) are read-only. |
ProtectKernelModules=true | Loading and unloading kernel modules is denied. |
ProtectKernelLogs=true | The kernel log ring buffer is inaccessible. |
ProtectControlGroups=true | The cgroup hierarchy is read-only. |
ProtectHostname=true | The service cannot change the system hostname. |
ProtectClock=true | The service cannot change the system clock. |
ProtectProc=invisible | Other processes are hidden in the service’s /proc. |
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 | Only these socket address families are permitted. |
RestrictNamespaces=true | Creating new namespaces is denied. |
RestrictRealtime=true | Real-time scheduling is denied. |
RestrictSUIDSGID=true | Creating setuid/setgid files is denied. |
LockPersonality=true | The execution domain (personality) is locked. |
MemoryDenyWriteExecute=true | Memory pages cannot be both writable and executable. |
RemoveIPC=true | IPC objects owned by the service are cleaned up on exit. |
SystemCallArchitectures=native | Only native-architecture system calls are allowed. |
SystemCallFilter=@system-service | The system-call surface is reduced to the service allowlist. |
SystemCallFilter=~@privileged @resources @mount @swap @reboot | Privileged, resource-control, mount, swap, and reboot syscall groups are explicitly denied. |
MemoryDenyWriteExecute=true carries the one documented exception: packages that genuinely require a just-in-time (JIT) compiler are exempted, because W^X memory would otherwise break them. The shipped example is PostgreSQL, whose service unit sets MemoryDenyWriteExecute=false so the LLVM JIT compiler keeps working; operators who want the strict W^X posture can disable the JIT in the database configuration instead. The exemption is per-package and deliberate, not a blanket relaxation.
Network exposure is closed by default
Sandboxing the runtime is only half the story; the other half is not exposing the service in the first place. Any server package shipped by InterGenOS binds exclusively to localhost (127.0.0.1) by default. Services do not listen on public interfaces unless you deliberately edit their configuration to allow it.
There are also no default or blank credentials. InterGenOS does not ship databases or services with empty or stock “admin” passwords; initial credentials are randomly generated or require manual setup.
How this fits the rest of the trust chain
Sandboxing and MAC are the runtime confinement layer. They sit on top of an integrity-verified boot and software supply chain:
- A signed Secure Boot chain validates the bootloader, kernel, and Unified Kernel Images, and dm-verity protects the read-only system image. Installed systems re-sign each kernel’s UKI with a local Machine Owner Key (MOK) on every kernel install or upgrade. Forge, the installer, walks you through enrolling that MOK on first boot.
- The package manager (pkm) verifies a signed index and per-package SHA-256 hashes before anything is installed.
Together these mean a service is launched from verified bytes, then held inside an enforced policy and a stripped-down sandbox for its entire lifetime.
For the boot and signing side of this chain, see Verified Boot & Secure Boot.
Auditing it yourself
These are conventional, well-documented Linux mechanisms, which is the point: you can inspect them with standard tools rather than trusting a claim.
aa-statusreports which AppArmor profiles are loaded and which are in enforce versus complain mode.systemctl show <service>prints the effective sandboxing directives for any unit, so you can confirm a service runs with the hardening described above.systemd-analyze security <service>produces a per-service exposure report.
Confirm the defaults, change what you need to, and trust the result because you checked it.
See also
Kernel Hardening
InterGenOS hardens the kernel and its boot path from the moment the machine powers on, not through post-install scripts you have to remember to run. The kernel is the most privileged code on the system, so the controls below exist to keep that privilege verifiable and contained.
The goal is a machine you understand, can modify, and can trust, starting at the layer everything else depends on.
Verified Boot Chain
The kernel only runs after every link above it has been cryptographically validated.
- A signed boot chain (Secure Boot optional). The chain is built around a Microsoft-signed shim (the pre-signed shim from Fedora) that validates the InterGenOS GRUB bootloader, which in turn verifies the Linux kernel and Unified Kernel Images (UKIs). With Secure Boot enabled the firmware enforces this end to end; the current fleet ships with Secure Boot off, so the chain is present and verifiable but not firmware-enforced.
- Unsigned kernel modules are not trusted. If your hardware needs out-of-tree modules such as proprietary drivers, the Forge installer walks you through enrolling a Machine Owner Key (MOK) on first boot.
- Local UKI signing on every kernel change. Installed systems regenerate and sign each kernel’s UKI with your machine’s local MOK at every kernel install or upgrade, so boot-time signature verification continues to apply to kernels you install after the original ISO image.
- The release-signing key stays offline. The InterGenOS release-signing key never leaves a hardware token under InterGenOS control. Only the MOK that Forge generates on your own machine signs the kernels you install.
Image Integrity (dm-verity)
The shipped, read-only system image is protected by dm-verity, which provides block-level integrity verification. dm-verity uses a Merkle hash tree built with veritysetup (statically linked), with a whole-file SHA-256 check retained as a fallback for any image whose signed command line lacks the verity root hash; this lets tampering be detected at the granularity of individual blocks as they are read rather than silently executed, which keeps the trust established by the verified boot chain intact at runtime. The tree’s root hash is sealed into the signed UKI kernel command line, so the integrity anchor for each image is itself covered by the boot-chain signature. UKI signing and dm-verity are produced as dedicated phases of the build pipeline, so integrity protection is part of the image itself rather than something layered on afterward.
Kernel-Surface Protections for System Services
Beyond the boot path, InterGenOS narrows what the running kernel exposes to the userspace daemons that talk to it. System services are sandboxed with systemd isolation directives, and several of those directives specifically reduce the kernel attack surface available to a compromised service:
ProtectKernelTunables=true— services cannot modify kernel tunables under/proc/sys,/sys, and related paths.ProtectKernelModules=true— services cannot load or unload kernel modules.ProtectKernelLogs=true— services cannot read or write the kernel log ring buffer.ProtectControlGroups=true— the cgroup hierarchy is protected from modification.RestrictNamespaces=true— creation of new namespaces is restricted.RestrictRealtime=true— services cannot acquire realtime scheduling.LockPersonality=true— the execution-domain personality is locked.MemoryDenyWriteExecute=true— write-and-execute memory mappings are denied (except for packages that explicitly require a JIT).SystemCallArchitectures=native— only native-architecture syscalls are permitted.SystemCallFilter=@system-servicewith~@privileged @resources @mount @swap @reboot— privileged, resource-control, mount, swap, and reboot syscall groups are filtered out.
These sit alongside the broader service-sandboxing baseline (NoNewPrivileges, ProtectSystem=strict, PrivateDevices, ProtectProc=invisible, and others). The full default set is documented in Hardening Baseline.
Mandatory access control complements the syscall filtering: AppArmor ships in enforce mode for system daemons by default, so a service that steps outside its profile is denied rather than merely logged. See Sandboxing and MAC for how AppArmor and systemd confinement work together.
Why This Matters
A kernel you cannot verify is a kernel you cannot trust. By signing the kernel and its UKI at every change, refusing unsigned modules, verifying image integrity with dm-verity, and tightly scoping the kernel interfaces each service can reach, InterGenOS keeps the most privileged layer of the system auditable and contained. You remain in control: enrolling your own MOK and choosing which out-of-tree modules to trust are deliberate, owner-driven steps, not defaults imposed on you.
Further Reading
Encryption, Keys & TPM2
InterGenOS protects your machine on two axes that compose into one boot path: encryption at rest (your data is an unreadable blob to anyone without your passphrase) and a signed boot chain (every component the system boots is signed and verifiable). This page covers both — full-disk encryption with LUKS2, the experimental TPM2 and FIDO2 unlock methods, the per-machine signing key, and the boot chain, whose Secure Boot enforcement is optional and off by default on the current fleet.
The boot path is the most privileged code on any machine, and the data on the disk is yours. These features exist to give you a machine you understand, can modify, and can trust.
At a glance
- Full-disk encryption is opt-in, not default. The Forge installer asks; you choose. We recommend it for any portable device.
- The format is LUKS2 with a passphrase, AES-256 in XTS mode, and the
argon2idkey-derivation function. - TPM2-sealed unlock and FIDO2-token unlock are wired as EXPERIMENTAL v1.0 sub-options. They compose with the passphrase rather than replacing it — the passphrase slot is always retained as the unconditional fallback.
- Your passphrase is never written to disk outside the LUKS header slot, never logged, never sent anywhere. There is no recovery-key escrow and no master key. If you forget it, your data is gone by design.
- The boot chain is fully signed. Secure Boot enforcement is optional and off by default on the current fleet; the signatures are present and ready to enforce where you enable it.
- Every kernel you install after the original ISO is rebuilt into a Unified Kernel Image (UKI) and signed with your machine’s own Machine Owner Key (MOK). The release signing key never touches your machine.
Full-disk encryption with LUKS2
InterGenOS uses LUKS2 (Linux Unified Key Setup, version 2) as the on-disk encryption format. The tooling is cryptsetup, the cipher default is AES-256-XTS, and the key-derivation function is argon2id — memory-hard and resistant to GPU/ASIC brute-force.
A LUKS2 volume has three parts:
- A header at the start of the encrypted partition, holding the encryption metadata: the cipher choice, the master-key wrapping, and up to eight key slots.
- Key slots, each independently holding a wrapping of the master key by one passphrase (or by a TPM-sealed key, or by a FIDO2-derived key). Several unlock methods can be active at once; deleting one slot does not affect the others.
- The encrypted payload — your root filesystem.
The master key never leaves the LUKS header. Your passphrase unwraps a key slot, which yields the master key, which decrypts the payload. The passphrase itself is held only in volatile memory during the unlock and the buffer is zeroed when it finishes. There is no on-disk copy of your passphrase.
The Forge install flow
When you run Forge (TUI or GUI), the partitioning stage offers an Encrypt the root filesystem with LUKS2 checkbox. If you tick it:
- Forge prompts for a passphrase with a confirmation field. Both frontends enforce a non-empty value and a confirm-field match. Guidance is a soft warning, not a block: 8 characters is the floor below which the warning fires, and 12 characters with at least two character classes is the recommended baseline. You can accept a passphrase that fires the warning after confirming.
- Forge formats the target partition with LUKS2 using
cryptsetup luksFormat. Forge forces the argon2id KDF parameters (1 GB memory cost, 4 iterations, 4 threads) per RFC 9106’s recommendations for memory-hard KDFs, rather than relying on the hostcryptsetupdefaults. The cipher itself — AES-256 in XTS mode — is cryptsetup’s own default, which Forge leaves in place rather than overriding. They are calibrated to defeat GPU-accelerated brute-force without risking out-of-memory on 4 GB systems. - Forge writes
/etc/crypttabso the boot-time initramfs knows what to unlock. The entry is namedcryptrootand references the partition byUUID=. - Forge writes
/etc/fstabwith the unlocked device-mapper node (/dev/mapper/cryptroot) as the root mount source. - The kernel post-install hook bundles the FDE initramfs into the UKI, so the unlock prompt lives inside the same signed envelope as the kernel (see Composition with Secure Boot).
The passphrase you type is held only in memory while the install runs. It is piped to cryptsetup via stdin (never on the command line, never in argv), zeroized after use, and cleared on both the success and failure path. No copy is written to disk except in the LUKS header slot itself.
EXPERIMENTAL — TPM2-sealed unlock
If you tick Unlock with TPM2 (EXPERIMENTAL), Forge seals a fresh 32-byte random key against the current measured-boot state, adds that key as an additional LUKS slot, and writes the sealed-blob triplet (primary.ctx, secret.pub, secret.priv) to the ESP under /intergen/tpm2/. The seal is bound to a PCR0 + PCR7 policy: PCR0 tracks the firmware (BIOS/UEFI code), and PCR7 tracks Secure Boot policy state (the db/dbx/KEK/MOK enrollment status). On normal boots the system unlocks automatically without prompting.
The TPM2 sub-checkbox is greyed out with a tooltip if your hardware does not expose a TPM (/dev/tpmrm0 absent) or if the live ISO is missing the static TPM2 tools.
This is flagged EXPERIMENTAL because the failure modes are subtle. A firmware update changes PCR0; a kernel update that touches your shim/MOK state can change PCR7; a Secure Boot reconfiguration changes PCR7. Any of these invalidates the seal, and the boot falls through to the next configured method and ultimately to the passphrase prompt. The sealed blob on the ESP is not a secret — without the specific TPM that performed the seal, and the same PCR state, it is useless and cannot be unsealed on any other machine. The passphrase slot remains untouched.
EXPERIMENTAL — FIDO2-token unlock
If you tick Unlock with FIDO2 token (EXPERIMENTAL), Forge enrolls a credential on a FIDO2 security token (YubiKey, Solo, Nitrokey, etc.) plugged in during the install. Enrollment runs in two interactive steps:
- Generate credential:
fido2-cred -Mcreates a new credential on the token. You will be prompted to touch the token when it blinks. - Derive unlock key: a fresh 32-byte random nonce is generated and
fido2-assert -G --hmac-secretis invoked with that nonce as salt. The token returns an HMAC output bound to the credential and the nonce, which is added as an additional LUKS slot. You will be prompted to touch the token a second time.
Forge writes the cred_id and stored_nonce to the ESP under /intergen/fido2/. Neither file is a secret: without the physical token, the credential ID and salt are useless. The relying-party ID is intergenos. At boot, the same fido2-assert call against the same nonce yields the same HMAC bytes, which unlock the slot.
This is flagged EXPERIMENTAL for the same family of reasons as the TPM2 path: a lost token, a token-firmware update that rotates credential storage, or a token swap all invalidate the slot. The passphrase slot stays in the LUKS header for fallback.
The boot-time unlock chain
When an encrypted InterGenOS system boots, the firmware verifies the UKI signature, the kernel hands off to the FDE init, and the unlock chain runs in order:
- TPM2 unlock (if enrolled and
/dev/tpmrm0is present):tpm2_load+tpm2_unsealagainst the PCR0+PCR7 policy, piped tocryptsetup. On any failure, fall through. - FIDO2 unlock (if enrolled and the tools are available): wait up to 30 seconds for the token to enumerate, run
fido2-assert -G --hmac-secretagainst the stored nonce, pipe the HMAC tocryptsetup. On any failure, fall through. - Passphrase prompt — always the final fallback. Three attempts, then a recovery shell.
If neither TPM2 nor FIDO2 was enrolled, the chain skips straight to the passphrase prompt and the path is identical to a passphrase-only install. The prompt is plain text:
InterGenOS — encrypted root unlock
Enter passphrase for /dev/disk/by-uuid/<uuid>:
Three wrong attempts drops you into a recovery shell with cryptsetup available, where you can retry the unlock manually, inspect /etc/crypttab, or reboot.
The FDE initramfs is tiny: a static cryptsetup, a static busybox, the dm_crypt and ext4 kernel modules, and the storage drivers needed to see your disk. When TPM2 or FIDO2 unlock is enrolled it also carries the relevant static tools and kernel modules. It does no logging to disk, no telemetry, and no network — its only job is to attempt the unlock chain, mount the root filesystem, and hand off to systemd.
Debugging the unlock chain
The init script emits journal-grep-friendly prefixes when running EXPERIMENTAL methods. After boot, correlate each attempt by searching the journal:
| Prefix | What it means |
|---|---|
[fde-init][EXPERIMENTAL TPM2] | TPM2 unlock attempt — skipping (no /dev/tpmrm0, no tools, or no sealed blob), attempting unlock via sealed key (PCR0+PCR7), tpm2_load failed, a tpm2_unseal/cryptsetup PCR-drift failure, or unlock succeeded. |
[fde-init][EXPERIMENTAL FIDO2] | FIDO2 unlock attempt — skipping, attempting unlock — plug your security token + touch when it blinks, no FIDO2 token detected within 30s, a specific pipeline diagnostic, or unlock succeeded. |
[fde-init] (no suffix) | Passphrase prompt path, the recovery-shell drop, and root-mount errors. |
These messages go to the console during early boot and are captured by systemd-journald afterward, available via journalctl -b | grep fde-init.
Secure Boot
The boot path is the most privileged code on the machine: if an attacker can substitute a kernel before the OS finishes starting, every other defense is moot. InterGenOS signs the entire boot chain to close that class of attack; enabling Secure Boot (optional, and off by default on the current fleet) makes the firmware enforce those signatures.
The boot chain is:
Firmware (UEFI)
| trusts Microsoft 3rd-party CA
v
Microsoft-signed shim
| trusts the InterGenOS vendor cert (loaded as MOK)
v
InterGenOS GRUB
| enforces signature verification on UKIs
v
InterGenOS UKI (vmlinuz + initramfs + cmdline, one Authenticode binary)
|
v
InterGenOS userspace
A Unified Kernel Image (UKI) is a single signed file that bundles the kernel, the initramfs, and the kernel command-line. Signing the UKI envelope signs all three at once; nothing inside can be swapped without breaking the signature.
The live ISO and install media use UKIs signed by the release key on an offline signing workstation. That release key never leaves our hardware and physically does not exist on your machine. Once you install to disk, every kernel you install or upgrade is rebuilt into a UKI on your machine and signed with your machine’s MOK.
InterGenOS treats unsigned modules the same way it treats unsigned kernels: a signed kernel that loads unsigned out-of-tree modules at runtime is no better than an unsigned kernel. The trade-off for this strictness is a one-time MOK enrollment step for out-of-tree modules; the benefit, once Secure Boot is enabled, is that nothing unsigned runs during boot.
The Machine Owner Key (MOK)
A Machine Owner Key is a per-machine signing key, generated on your own machine, that the firmware trusts because you enrolled it via MokManager at first boot. It exists for two reasons:
- Your machine signs the kernels you install. When you install a new kernel with
pkm install linux-kernel-X.Y.Z, InterGenOS rebuilds the UKI and signs it with your MOK. The release key never sees the kernels you install. - You can trust your own third-party drivers. Out-of-tree modules (for example, proprietary GPU drivers via DKMS) can be signed by your MOK and load on a Secure Boot system without disabling enforcement.
The MOK is yours. It lives at /var/lib/intergen/mok/ on the installed system. If you reinstall, Forge generates a fresh MOK; if you migrate to a new machine, you generate a new MOK there.
What Forge does at install
The bootloader stage runs without asking further questions:
- Generates a per-machine MOK keypair (RSA-2048) as
mok.key(private key),mok.crt(PEM X.509 cert, used bysbsign), andmok.der(DER X.509 cert, the binary form MokManager wants for enrollment). - Generates a random 12-character enrollment password and stores it for the first-boot step.
- Stages the MOK for enrollment so MokManager picks it up on next reboot.
- Installs
ukifyandsbsigntoolso the kernel post-install hook can build and sign UKIs. - Installs an initial UKI built from the installed kernel and signed with the fresh MOK.
- Configures a recovery boot entry that loads the bare vmlinuz as a fallback if a UKI ever fails to sign or boot.
Forge shows the enrollment password on the install-complete screen and writes it to /var/log/intergen-install.log. Write it down before you reboot. You need it once, during MokManager enrollment.
First-boot MOK enrollment
On the first boot after install, the firmware notices a pending enrollment request and runs MokManager — a small blue-text-on-black utility — before continuing the boot. It walks you through three screens:
- “Perform MOK management” — press any key to start.
- “Enroll MOK” — review the certificate (subject
CN=InterGenOS Machine Owner Key) and confirm. - “Enter password” — type the enrollment password Forge gave you. It is single-use.
After enrollment, MokManager exits and the system boots normally. From that point, the firmware trusts your MOK and UKIs signed with it load without prompts.
If you skip enrollment, the system still boots using the release-signed UKI that shipped with the installer image — but the next kernel install or upgrade produces a MOK-signed UKI the firmware will not trust, and you will fall through to the recovery boot entry until you enroll.
Kernel install and upgrade
When you install or upgrade a kernel via pkm, the linux-kernel package’s post_install hook runs on your machine with no key material from the release infrastructure:
- Reads the kernel, the standard initramfs (and the FDE initramfs if your system is LUKS-encrypted), and the canonical command-line.
- Runs
ukify buildto bundle them into a single UKI. - Runs
sbsign --key /var/lib/intergen/mok/mok.key --cert /var/lib/intergen/mok/mok.crtto sign it. (sbsignreads PEM certs; the.derform is for MokManager enrollment only.) - Writes the signed UKI to the ESP under
/boot/efi/EFI/Linux/, namedintergenos-<kernel-version>.efi. - Updates the GRUB menu so the new kernel is the default boot entry.
If the UKI build or signing step fails (corrupt key file, full ESP, missing tooling), the hook falls back to the GRUB-loads-vmlinuz path: the kernel and initramfs are written out separately and GRUB loads them directly with the same signature-verification semantics, since GRUB is itself signed and enforces check_signatures=enforce. The kernel install is never rolled back on UKI failure, so you never end up with a half-installed kernel.
ESP sizing
Every kernel you install becomes a UKI in /boot/efi, so the ESP needs headroom for several generations. A typical UKI is 80-150 MB depending on the initramfs payload. Forge creates a fixed 1 GiB ESP during partitioning, leaving room for several kernel generations. If the ESP fills up, kernel install fails with a clear message; clean up with pkm remove linux-kernel-<old-version>.
Composition with Secure Boot
The encrypted-root and signed-boot stories are designed to compose. They do not interact at runtime except through the FDE initramfs being part of the signed UKI.
On a non-encrypted install, the UKI’s bundled initramfs is minimal — typically only CPU microcode — because storage and filesystem drivers are built into the kernel. On an encrypted install, the UKI’s bundled initramfs is the FDE initramfs: the same init that prompts you for the passphrase is part of the same signed envelope as the kernel.
The practical consequences:
- An attacker cannot substitute a fake unlock prompt that captures your passphrase, because the prompt code is inside the signed UKI. Tamper with it and Secure Boot refuses to load it.
- A kernel upgrade rebuilds the UKI with the new kernel and the same FDE initramfs, signed with your MOK. The unlock experience is identical across kernel upgrades.
- If TPM2-sealed unlock is enabled, the same UKI envelope holds the bits that talk to your TPM. The unlock path stays inside the signed envelope; the TPM is not a way to skip Secure Boot verification.
What is and is not protected
Encrypted at rest: the entire root filesystem, including /home, /var, /etc, /root, swap if placed on the encrypted volume, and anything written to disk once the system is running and unlocked.
Not encrypted:
- The ESP (the small
/boot/efipartition). The firmware reads it before any OS runs, so it cannot be encrypted. Its integrity is protected by Secure Boot signature verification on the UKI, not by encryption. - The LUKS header, which is on disk and visible. It reveals that the partition is LUKS-encrypted and which cipher is in use, but nothing about the payload.
- A running system. Once unlocked, the master key lives in kernel memory and the filesystem is readable to any process with the right permissions. Encryption-at-rest does not replace process isolation, user permissions, or AppArmor confinement.
If your threat model includes someone with physical access while the machine is running, full-disk encryption is not the control you want — use screen lock or a powered-off machine.
Recovery
“I forgot my passphrase”
Your data is gone. There is no master key, no recovery-key escrow, and no back door — a recovery channel we could use is a channel an attacker could use. Boot a live ISO and reinstall. Back up early and often.
Add or remove a passphrase
LUKS2 supports up to eight key slots. From a running system, as root:
cryptsetup luksAddKey /dev/disk/by-uuid/<uuid>
cryptsetup luksRemoveKey /dev/disk/by-uuid/<uuid>
luksAddKey prompts for an existing passphrase (to unwrap the master key) and then the new one. luksRemoveKey prompts for the passphrase belonging to the slot you want to remove; the other slots are untouched.
Back up the LUKS header
If the header is corrupted, the payload becomes unrecoverable even with the correct passphrase, because the encryption metadata lives in the header. Back it up to a separate medium:
cryptsetup luksHeaderBackup /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
Store it offline. Anyone with the backup file and your passphrase can decrypt your disk; treat it accordingly. Restore with cryptsetup luksHeaderRestore and the same --header-backup-file argument.
“I need to regenerate the MOK”
The MOK material lives under /var/lib/intergen/mok/. On a default install Secure Boot is off and there is no enrollment password to lose. If you run with Secure Boot enabled and need a fresh MOK, reinstalling with Forge regenerates one; the next kernel install or upgrade rebuilds the UKIs with it, and the bare-vmlinuz fallback in GRUB keeps the system bootable in the meantime. (There is no separate recovery wrapper command — UKI signing is handled entirely by the kernel package’s post-install hook.)
“Secure Boot is refusing my new kernel”
This usually means the MOK was not enrolled (or was un-enrolled) but the post-install hook signed a UKI with it. Boot the recovery entry, then either re-enroll the MOK or regenerate it via the password-reset path above.
“I want to run an unsigned kernel”
Don’t. Every kernel that boots is signed — this is non-negotiable. Build your kernel, sign it with your MOK using sbsign, and install it through the same pkm flow. To test bare unsigned kernels, use a VM with Secure Boot off, not a production install.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Passphrase prompt rejects every attempt | Wrong passphrase, or keyboard layout differs at boot | The FDE initramfs uses US-QWERTY by default; type the QWERTY equivalents of layout-sensitive characters. |
| Boot drops to the FDE recovery shell with “no LUKS volume specified” | /etc/crypttab was not written, or the encryption stage did not complete | Inspect /etc/crypttab from the recovery shell; if empty, boot a live ISO and reinstall. |
| Boot drops to the recovery shell with “LUKS volume not found after 30s” | Disk did not enumerate in time (failing drive, USB storage, slow RAID init) | Run ls /dev/disk/by-uuid/; if the volume appears, retry cryptsetup open manually. |
| TPM2-sealed unlock falls through to passphrase | PCR0 or PCR7 changed (firmware update, Secure Boot reconfiguration, shim/MOK update) | Enter the passphrase to boot. Re-enrolling TPM2 against the new PCR state restores automatic unlock. Check the [EXPERIMENTAL TPM2] journal lines for the specific outcome. |
| FIDO2 unlock does not detect the token | Token plugged in too late, or dead battery | Plug the token in before boot; the initramfs waits up to 30 seconds. Check the [EXPERIMENTAL FIDO2] journal lines. |
| Boot stops at MokManager every time | MOK enrollment never completed | Complete enrollment per First-boot MOK enrollment above. |
| New kernel installs but won’t boot, falls through to recovery | UKI signed with a MOK the firmware doesn’t trust | Re-enroll the MOK, or re-run the kernel post-install hook after enrollment. |
| GRUB shows only the recovery entry | UKI signing has been failing silently | Inspect /var/log/intergen-kernel-postinstall.log; ESP-full and a missing MOK key file are the common causes. |
ukify is missing on the installed system | Forge skipped the UKI tooling install | pkm install ukify sbsigntool and re-run the kernel post-install hook. |
| Secure Boot toggle is greyed out in firmware | Some OEM firmware makes Secure Boot read-only outside Setup Mode | See your vendor docs for entering Setup Mode. The standard MOK enrollment path is sufficient for normal operation. |
Further reading
- Forge installer guide — the install walkthrough that references the encryption opt-in and MOK enrollment in context.
- FAQ — common security questions.
Network Security & Firewalling
InterGenOS treats the network as the most exposed surface a machine has. The posture is default-deny: nothing listens on a public interface, nothing reaches out on its own, and no data leaves the machine unless you make it leave.
This page describes how that posture is enforced today and what it means for you as an operator of a machine you understand, can modify, and can trust.
The Default Posture: Deny
Two principles govern every networked component InterGenOS ships:
- Nothing listens publicly. Any server package shipped by InterGenOS binds exclusively to localhost (
127.0.0.1) by default. A database, a web server, or any other daemon you install is reachable only from the machine itself. It will not listen on a routable interface unless you deliberately edit its configuration to allow it. - Nothing phones home. InterGenOS collects zero analytics, crash reports, or usage statistics. There is no auto-update that contacts a server behind your back, and there is no opt-out toggle to hunt for in a settings menu. No usage or analytics data is produced, so none leaves to begin with.
A freshly installed system has no attack surface facing the network that you did not explicitly create. Opening a port is a decision you make, not a default you have to discover and undo.
Inbound: Why Nothing Is Reachable
The localhost-bind default is the primary control for inbound traffic. Because services do not listen on public interfaces, an unconfigured InterGenOS machine presents nothing for a remote scanner to connect to. This is enforced at the package level rather than left to a separately configured packet filter, so the protection holds even before any host firewall rules are evaluated.
When you choose to expose a service, the act of changing its bind address is the explicit step that takes you off the default-deny path. At that point the service’s own configuration, and the host firewall, govern who can reach it.
InterGenOS uses nftables (nft) as its host firewall, enabled by default with a default-deny posture. There is no firewalld or ufw; nftables is the single packet-filtering layer, and it mirrors the system’s overall stance of refusing inbound traffic you have not explicitly allowed.
Outbound: No Silent Egress
InterGenOS does not generate background network traffic on your behalf:
- No telemetry or analytics. Nothing in the base system reports usage, crashes, or metrics to any server.
- No auto-updates. Your system will not fetch or install software in the background. Updates happen only when you explicitly run them.
- No opt-out privacy. You do not flip toggles to stop the OS from sending usage data to the cloud, because it collects and sends none. (Network use that you initiate — package syncs, the one-time model download, services you start — is covered just below.)
When you observe outbound connections from an InterGenOS machine, they correspond to actions you took: syncing packages, running a browser, or starting a service yourself.
The local AI assistant follows the same rule. InterGen runs offline-first and local by default with zero telemetry; it does not transmit your prompts or data off the machine. The optional security scanner, InterGen Sentinel, defaults to local rules and a local model. Its cloud providers and the Phone-A-Friend (Frontier/Cloud Escalation) path are strictly opt-in, so no off-machine call to a frontier provider happens unless you turn it on.
Service Confinement Limits the Blast Radius
Even a service that does talk to the network runs inside tight confinement, so a compromise of one daemon does not become a compromise of the system:
- AppArmor in enforce mode. System daemons ship with AppArmor profiles in enforce mode by default, not complain mode and not disabled.
- Systemd sandboxing. System services are sandboxed with extensive isolation directives. Among the network-relevant ones,
RestrictAddressFamilieslimits services toAF_UNIX,AF_INET, andAF_INET6, denying access to lower-level or exotic socket families a service has no reason to use. These run alongside broader hardening such asNoNewPrivileges,ProtectSystem=strict,PrivateTmp,RestrictNamespaces, and a@system-servicesystem-call filter.
A network-facing service is confined to the narrow set of capabilities it actually needs. If it is breached, the sandbox limits where the attacker can go next.
The Package Mirror Is Signed End-to-End
The one network operation every InterGenOS machine performs routinely is talking to the package mirror, so that channel is verified cryptographically rather than trusted by transport alone.
Every time you sync with pkm, your machine verifies the package index signature against a release-signing subkey held on a hardware token and certified by the offline InterGenOS master key. When a package is downloaded, its SHA-256 hash is validated locally before installation. InterGenOS uses an index-only signature trust model for the 1.0 release, giving you a centralized, verifiable source of truth instead of relying on the network path being honest.
Credentials Are Never Default
No service shipped by InterGenOS comes with a blank or default admin password. Initial credentials are randomly generated or require manual setup during installation. A service that does become reachable on your network cannot be entered with a guessed factory password.
What This Means For You
- A new install exposes nothing to the network you did not ask it to expose.
- Making a service reachable is an explicit, auditable change to that service’s configuration.
- Even reachable services run confined, so a single breach stays contained.
- Local assistance stays local; any cloud escalation is opt-in.
- The package mirror, the one routine outbound dependency, is cryptographically verified rather than implicitly trusted.
Further Reading
- Hardening Baseline — the full set of out-of-the-box protections.
- Frequently Asked Questions — general questions about running InterGenOS.
Auditing & Logging
InterGenOS keeps a clear record of what happens on your machine, and keeps that record on your machine. Logs exist so you can understand and trust your system, not so a vendor can study you.
This page covers where logs live, what is recorded by default, and the privacy boundary that governs all of it.
The Privacy Boundary First
Auditing and logging on InterGenOS operate under one absolute rule: log data never leaves your machine on its own.
- No telemetry. InterGenOS collects zero analytics, crash reports, or usage statistics.
- No opt-out required. You do not flip toggles to stop your OS from sending data to the cloud. The data never leaves to begin with.
- No silent uploads. Logs are written locally and stay there until you choose to read, export, or delete them.
Everything below describes records held for you, on the system you control. See the Security Handbook overview for the full posture this rests on.
System Logs (journald)
InterGenOS ships GNOME 49 on Wayland over a systemd userland, so the system log is the systemd journal. The journal captures kernel messages, service output, boot records, and authentication events in a single queryable store.
Common queries:
# Everything since the last boot
journalctl -b
# Logs for a single service
journalctl -u <service-name>
# Follow new entries live
journalctl -f
# Only errors and above
journalctl -p err
# Scope an investigation by time
journalctl --since "2026-06-15 09:00" --until "2026-06-15 10:00"
What Is Audited By Default
Several InterGenOS security controls produce their own records, independent of any audit subsystem you might add later.
Mandatory Access Control (AppArmor)
InterGenOS ships AppArmor profiles for system daemons in enforce mode by default. When a confined daemon attempts an action its profile forbids, the denial is logged. These denial records are the primary signal that a service is behaving outside its expected envelope. See Sandboxing & Mandatory Access Control for how the profiles are structured.
Service Sandboxing (systemd)
System services run under extensive systemd isolation directives (NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, syscall filtering, and more). When a sandboxed service is blocked from a restricted operation, the failure appears in that service’s journal entries, giving you a direct view of the confinement working as intended. The full directive baseline is listed on the Hardening Baseline page.
Boot and Integrity Verification
The signed Secure Boot chain and dm-verity integrity protection both record their verification results during boot. A failed signature check or an integrity mismatch is a boot-time event, not a silent fallback. See Encryption, Keys & TPM2 for how the boot chain validates each stage and signs Unified Kernel Images.
Authentication Events
Login attempts, privilege escalation, and session lifecycle events are recorded through the journal in the usual way for a systemd system, so you can review who accessed the machine and when.
Package and Supply-Chain Records
Auditing on InterGenOS extends to the software you install, not just the running system.
- Signed-index verification. Every
pkm synccryptographically verifies the repository index signature against a release-signing subkey held on a hardware token and certified by the offline master key, and each package’s SHA-256 hash is validated locally before installation. A verification failure is surfaced, not skipped. - Software Bill of Materials. InterGenOS publishes a deterministic SPDX 2.3 JSON SBOM for the Secure Boot shim — the trust anchor the rest of the boot chain is verified through — describing its exact build inputs and source hashes, giving you a machine-readable provenance record for the boot chain’s root of trust.
See the Registry-Trust Boundary page for the full trust model behind these checks.
Reading and Managing Your Logs
Because the journal is local and queryable, routine auditing is a matter of asking the right questions of journalctl. To review security-relevant activity, combine the priority and unit filters shown above; to investigate a specific incident, scope by time with --since and --until.
When you export logs to share with someone, you are making a deliberate choice. Nothing on the system does that for you.
Further Reading
- Security Handbook overview — the full default-on protection posture.
- Sandboxing & Mandatory Access Control — AppArmor enforce-mode profiles and systemd confinement.
- Encryption, Keys & TPM2 — boot-chain verification and signing.
- Registry-Trust Boundary — package index and hash verification.
- FAQ — general questions about the system.
InterGenOS exists to give you a machine you understand, can modify, and can trust. Local, honest logging is part of that promise.
Registry-Trust Boundary
InterGenOS draws a single, auditable line between what it will do on its own and what requires your explicit authorization. That line is the trust boundary, and it governs two things that are often confused: the packages that make up the system, and the local AI assistant that can act on the system on your behalf.
This page explains where the boundary sits, how it is enforced, and why it is shaped the way it is. The goal is a machine you understand, can modify, and can trust.
Two boundaries, one principle
There are two distinct trust surfaces in InterGenOS:
- The package boundary — how software gets onto the machine, and how its integrity is proven before and after it lands.
- The AI action boundary — what the local assistant is permitted to do without asking, what it must ask to do, and what it will never do at all.
Both follow the same principle: do not invent a new gate, inherit the one the
operating system already has. A person at a terminal can freely touch their
own files and needs sudo or PolicyKit for system-level changes. Mirroring that
model keeps the machine understandable, because you already know how it works.
The package boundary
InterGenOS is built from source. The build pipeline runs in 20 phases (from
validate through iso, with an optional publish step), producing the tiered
package set that makes up the system. The package set spans six tiers —
toolchain, core, base, desktop, ai, and extra — for a total in the neighborhood
of 850 packages. These counts drift as the system evolves; derive the live
figures from the repository rather than treating any number as fixed.
The package manager, pkm, is the consumer side of that pipeline. It installs,
removes, queries, and verifies pre-compiled binary archives (.igos.tar.gz) on
the live filesystem. Its trust model rests on three layers.
Provenance: the archive trust check
Before installation, pkm can verify an incoming archive against a trusted
index synced from the central repository. The pkm install command exposes an
--archive-trust flag that accepts three values: strict (the default when the
flag is omitted), loose, and repo-only. In its strict and repo-only
modes the archive’s SHA-256 hash is computed and checked against the trusted
available index (synced via pkm sync) before the package is allowed to
install. This is the inbound side of the boundary: an archive that does not match
the repository’s recorded hash does not cross it.
Auditability: the hybrid data model
pkm keeps two parallel records of system state so that nothing about what is
installed is hidden:
- A SQLite database at
/var/lib/igos/pkm.dbis the fast source of truth for queries and transactions. It records installed packages, every deployed file with its SHA-256 checksum, dependencies, an append-onlyhistorylog of every install, removal, and supersede, and specialized tracking for/etcconfiguration files. - Human-readable text manifests at
/var/lib/igos/packages/are generated alongside the database records so you can inspect what a package owns without any special tooling.
This duality gives you performance without giving up the ability to read the ledger yourself. Reads of this state are free; you never need to authorize asking the system what it has installed.
Integrity: content-hash verification after install
The boundary does not stop at install time. pkm verify recalculates the
SHA-256 hash of every installed file on disk and compares it against the hash
recorded in the database. This detects both accidental corruption and
unauthorized modification of installed binaries after the fact. The archive
check proves what came in; pkm verify proves it has not changed since.
Hardened deployment
Installation extracts to a staging directory using hardened tar flags
(--no-same-owner, --no-same-permissions), checks invariants such as
directory collisions and SUPERSEDES ordering, then deploys to the root
filesystem. Setuid and setgid bits are dropped during extraction and only
explicitly restored from the package’s own manifest metadata, so an archive
cannot smuggle in unexpected privileged binaries. The database record is then
written in a single atomic transaction.
The boot and integrity chain
The package boundary sits inside a broader signed chain. InterGenOS ships a
signed Secure Boot chain, UKI (Unified Kernel Image) signing, and dm-verity
integrity for the live system image. Together these establish that what boots is what
was built and signed, before pkm ever runs on the live system.
The AI action boundary
InterGenOS ships InterGen, a tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry. Because the assistant can act on the machine, it sits behind the strictest version of the trust boundary.
InterGen evaluates every action on two orthogonal axes that are never conflated:
| Axis | Question | Mechanism |
|---|---|---|
| Privilege | Would a human need sudo for this, and what does it touch? | the gating model below |
| Content trust | Does data crossing the boundary carry injection inbound, or leak a secret outbound? | a separate scanner and provenance layer (ingress/egress scanning, InterGen Sentinel) |
Keeping these separate matters. The privilege axis decides whether an action is allowed; the content axis independently watches what a read returns or what an outbound message contains. A read of your own files is free on the privilege axis even while the content axis still inspects what that read returned.
Zones: where the action lands
The privilege axis classifies every target into one of three zones, mirroring
what a human would need sudo to write:
| Zone | What it is | Sudo to write? |
|---|---|---|
| Z1 — User space | Owned by you: ~/ and below, systemctl --user units, your own processes and files | No |
| Z2 — System config/state | Root-owned, ordinary administration: most of /etc, /usr, /opt, /var, system units, installed packages | Yes |
| Z3 — System-critical / trust anchor | Root-owned and part of the security and boot trust chain: /boot, EFI/UKIs, Secure Boot keys (MOK/db/KEK/PK), kernel and initramfs, dm-verity hashes, LUKS headers, the partition table, /etc/shadow, /etc/sudoers, /etc/pam.d, /etc/polkit-1 — plus InterGen’s own substrate | Yes, and these underpin the trust chain |
Operations and outcomes
Actions are classified as R (read/inspect), W (write/modify), or X (execute/state-change). Each combination of zone and operation resolves to one of three outcomes:
| Z1 User space | Z2 System config/state | Z3 System-critical / InterGen-self | |
|---|---|---|---|
| R | FREE | FREE | listing → FREE; secrets → AUTH-PROMPT |
| W | FREE | AUTH-PROMPT | FORBIDDEN |
| X | FREE | AUTH-PROMPT | FORBIDDEN |
- FREE — InterGen acts immediately, no prompt. All reads of non-secret data, and everything in your own space.
- AUTH-PROMPT — InterGen triggers the operating system’s real authorization (pkexec/PolicyKit), phrased plainly, for example: “InterGen wants to restart Bluetooth. That needs admin rights. Authorize?” Your password is the gate and the OS enforces it. There is no opaque internal “governance card.”
- FORBIDDEN — InterGen will not do it, and says so transparently (see below).
Reads are free even of system state: asking “what’s my system status?” or
running pkm list never requires authorization. A parallel “autonomy tier” that
blocks benign reads is exactly the anti-pattern this model exists to replace.
Reading a secret such as /etc/shadow is AUTH-PROMPT, not forbidden, because a
human can sudo cat their own shadow file. InterGen does not pretend to be
stricter than the operating system. Whether that content may then leave the
machine is the separate content-trust axis.
The self-protection keystone
InterGen’s own files are classified Z3, which means InterGen may never modify its own substrate. This closes one of the most dangerous attack surfaces: a capable adversary’s whole goal is to talk the assistant into rewriting its own gate, model, manifest, or guardrails. If InterGen’s substrate is write-forbidden to InterGen, then even a flawless prompt injection cannot make InterGen weaken InterGen. Only you, acting manually and outside the assistant, can change those files.
The forbidden-to-self substrate includes InterGen’s code, its GNOME Shell panel
extension, its signed model pins (models-manifest.json), the verified
root-owned model store, its daemon units and PolicyKit policy, and its
privileged runner. Reading this code is fine; changing it is not.
Transparent refusal
When InterGen refuses a Z3 action, it is open about it and hands control back to
you. It states plainly what it will not do and why — it protects the boot and
security trust chain, including its own integrity — and confirms that you can do
it yourself. There is never a silent failure, a hidden refusal, or internal
jargon. The intent is captured by its own wording: “I won’t modify the system’s
boot and security files. That’s the trust chain that keeps this machine yours.
It’s your machine, so you can do it yourself with sudo if you intend to; I
just won’t be the one to touch it.”
InterGen Sentinel and the content axis
The content-trust axis is handled by a separate mechanism, InterGen Sentinel, a pluggable security scanner. By default it runs on Local-Rules and a Local-Qwen model, keeping scanning offline. It can additionally use six opt-in cloud providers — Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek — none of which are engaged unless you choose to enable them.
This opt-in escalation path is Phone-A-Friend (Frontier/Cloud Escalation): when local scanning wants a stronger second opinion, and only with your consent, it can consult a frontier model. The default posture is fully local with zero telemetry; the boundary to any cloud provider is one you cross deliberately, not one InterGenOS crosses for you.
Where the code and the model disagree
The gating model is the authoritative specification, and the code is held to it: where the implementation and the model diverge, the model is the reference and the implementation is corrected to match it. A single zone classifier and operation classifier feed one outcome resolver, giving one place to audit every decision, and FORBIDDEN is always checked before any authorization prompt is ever raised.
See also
Self-Hosting Securely
InterGenOS is built from source and ships with a package manager (pkm) that
trusts a signed index, not a transport layer. That design is what makes
self-hosting your own binary mirror practical: you can stand up a repository
your machines pull from, sign it with keys you control, and let every client
verify it the same way the official mirror is verified.
A self-hosted mirror should leave you with a machine you understand, can modify, and can trust, which means the trust boundary has to be something you can inspect by hand, not a black box.
The trust model
The integrity boundary is the GPG signature on the package index
(InterGenOS.db), not TLS. TLS protects the transport; it does not prove
who built the index. A self-hosted mirror inherits this model:
pkm syncfetchesInterGenOS.dband its detached signature (InterGenOS.db.sig), verifies the signature against the public key in the client’s trust store, and only then trusts the per-package SHA-256 hashes inside the index.pkm installdownloads an archive and verifies its SHA-256 against that trusted index before deploying anything.
Because the signature is the boundary, a mirror can sit behind any web server or CDN. A compromised transport can withhold or stale an index, but it cannot forge one without the signing key.
Key handling
Keep the signing material off the mirror host. The recommended posture, and the one the official mirror uses, is:
- An offline master key that certifies signing subkeys and never touches a networked machine.
- One or more signing subkeys held on hardware tokens. Signing requires the token to be physically present and unlocked (PIN plus touch), so a remote compromise of either your workstation or the mirror host cannot produce a signature on its own.
- A backup signer on a second token, so loss of the primary does not lock you out of publishing.
Publishing writes the signed tree to the mirror over SSH using a key authorized only for that account, with no root step. The signing step happens on your workstation, where the token lives; the mirror host only ever receives already-signed files.
Building the index
pkm reads a gzipped-JSON index that lists each package and its SHA-256.
Generating it is a single operation against your directory of built
.igos.tar.gz archives, producing InterGenOS.db. The signature is then a
detached, armored GPG signature over that file
(gpg --detach-sign --armor), written as InterGenOS.db.sig.
Index generation is not byte-stable: regenerating the index produces a new
file, which voids any prior signature. Sign the exact InterGenOS.db you
intend to publish, and never regenerate after signing. If you need to re-sign
without rebuilding, sign the existing file directly with the subkey
fingerprint and skip the regenerate step.
Publishing without a downtime window
The official publish flow is worth copying because it never exposes a half-written repository:
- Stage. Rsync the signed tree into a fresh, per-publish staging directory (timestamped) under the architecture path, alongside the source archives.
- Promote atomically. Repoint the
currentsymlink with a single atomic rename (ln -sfnto a.newname, thenmv -T). On a journaling filesystem this is one syscall, so there is no 404 window: in-flight clients finish against the old target or restart against the new one. No web-server restart is needed; the server serves the swapped symlink on the next request. - Keep the previous set. Archive the prior target rather than deleting it, so a bad publish can be rolled back by flipping the symlink back.
Always dry-run first. A dry run validates that the signing key is available, generates the index in place, and prints the rsync and promote it would perform, without writing to the mirror. Confirm the archive count and staging path look right before the real run.
Pointing clients at your mirror
Clients read repository settings from /etc/pkm/repos.conf. Two settings
govern the security posture:
gpg_verifycontrols whetherpkm syncrequires a valid signature on the index. A fresh install ships with verification off so a first sync against an empty, not-yet-signed mirror does not fail closed. Once your mirror serves a signed index, setgpg_verify = trueso clients fail-closed on any unsigned or tampered index.- The client’s trust store holds the public key your index is verified against
(
/etc/pkm/trusted.gpg). Distribute only the public key; the private signing material stays on your token.
For installs, pkm also exposes archive-trust modes (strict / repo-only)
that check each downloaded archive’s SHA-256 against the synced index before
installation. Self-hosters should run a strict mode so a mirror that serves a
mismatched archive is rejected at the client.
Verifying your own mirror
A self-hosted mirror is only as trustworthy as your ability to audit it. Two layers:
Automated, ongoing. Run a periodic verification pass on the mirror host
that checks the index signature, walks every file’s SHA-256 against the index,
and scans for stray files not listed in the index, alerting on any drift. Run
it manually right after your first publish to confirm the live set verifies;
it stays red until a current/ target exists.
Manual, by anyone. Every step is reproducible by hand against your published public key, with no opaque steps:
curl -O https://<your-mirror>/x86_64/current/InterGenOS.db
curl -O https://<your-mirror>/x86_64/current/InterGenOS.db.sig
gpg --verify InterGenOS.db.sig InterGenOS.db # signed by your subkey, certified by your master
# then sha256sum any archive against its entry in the index
If those two commands succeed, the index is authentic and any archive you pull can be checked against it. That is the whole trust chain, and it is the same chain whether you pull from the official mirror or your own.
Append-only audit log
A publish can append the signed index to an append-only transparency log, so the history of what you published, and when, is auditable after the fact, independent of the live mirror state. Self-hosters operating a mirror for more than one machine should keep such a log; it turns “what did I serve last Tuesday” from a guess into a record.
Where this fits
- For how
pkminstalls, verifies, and supersedes packages on a client, see the package manager component documentation. - For installing InterGenOS itself with Forge, see ../install/forge-guide.md.
- For common questions, see ../start-here/faq.md.
Verify It Yourself
The InterGenOS promise is not “trust us.” It is “check us.” Security you cannot verify is a marketing claim; security you can verify is a property of your machine. Every guarantee this wiki makes is meant to be checkable — by you, on your own hardware, with a command whose output you can read.
This section gathers those checks in one place. Each page pairs a claim with the exact command that proves it and the output a healthy system shows, so you never have to take our word for anything.
In this section
- First Checks After Install — the five-minute, run-it-in-order ritual for a fresh install: ten checks, each with the exact command, the output a healthy system shows, and what it means if yours differs. Start here.
- Security Verification — the per-claim reference: Secure Boot, the signed boot chain, dm-verity root integrity, per-file package verification, signed-mirror trust, and kernel lockdown — each with the command that proves it.
These checks lean on two reference pages that are evidence in their own right:
- Reproducibility & Verification — rebuild from source and confirm the result matches the published artifact, byte for byte. The strongest possible answer to “is the binary really built from this source?”
- Package & Config Reference — the complete, generated inventory of what the system is made of: every package, tier, and the configuration behind it.
If a check on your machine does not show what these pages describe, that is a real signal — see Troubleshooting, and tell us.
First Checks After Install
You just installed InterGenOS. Before you trust it with anything, make it prove itself — in about five minutes, with commands you can read.
This page is a ritual, not a reference. Run the checks in order, top to bottom, on your own machine, right after your first boot. Each one shows the exact command, what a healthy system prints, and what it means if you see something else. None of them change anything — they read state and report it. (A few need sudo to read privileged state.)
The companion page, Security Verification, is the per-claim reference — it explains the mechanism behind each guarantee. This page is the fast pass you run first. When a check here makes you want the “why,” that page has it.
A healthy fresh install passes every check below. If one does not match, that is a real signal worth chasing — see the “If you don’t see this” note on each, and Troubleshooting.
1. You are actually running InterGenOS
Start at the bottom: confirm the system identifies as what you installed.
$ cat /etc/os-release
You should see NAME="InterGenOS", ID=intergenos, and a VERSION_ID:
NAME="InterGenOS"
PRETTY_NAME="InterGenOS 1.0-dev (Revival)"
ID=intergenos
VERSION_ID=1.0
If you don’t see this: you are not booted into InterGenOS — you may have booted the installer ISO or another OS. Check your firmware boot order.
2. Every installed file matches the signed release
This is the headline check — the one that proves the files on your disk are exactly the files in the signed release, with nothing swapped, corrupted, or silently altered since install.
$ sudo pkm verify --all
Verified (strict): 831 ok, 0 with issues; 11 expected-absent (removed by post_install)
You should see every package ok with 0 issues. pkm recorded a SHA-256 for every file it installed and re-checks them here. The expected-absent entries are files a package’s own post-install step intentionally removed — pkm tracks them so they are never mistaken for tampering. The exact totals track your installed set (yours will differ from the numbers above; what matters is 0 with issues).
If you don’t see this: a non-zero “with issues” count means a tracked file changed. That can be a legitimate local edit to a config file — pkm verify will name the file, so you can tell. An unexplained binary mismatch is a real signal; do not ignore it.
3. Your software comes from a signed source
Updates should only ever come from a package index signed by the InterGenOS release key — a swapped or tampered mirror is rejected, not silently trusted.
$ sudo pkm sync
Hit: intergenos-current https://repo.intergenos.org/x86_64/current
Index: InterGenOS.db
Signature: Good — InterGenOS release subkey ✓
You should see Signature: Good. When pkm fetches the index it verifies the signature against a release-key fingerprint pinned into pkm itself — so even a mirror that presents a different, valid-looking key is refused. On your machine the Signature line names the specific signing subkey by its short key id (shown generically above); you can confirm that key matches the published release key.
If you don’t see this: a signature failure means the index could not be trusted — pkm refuses it rather than installing from it. A persistent failure on the official mirror is worth reporting.
4. The kernel is locked down and enforcing
The running kernel should be in integrity lockdown, refuse unsigned modules, and carry the full security-module stack.
$ cat /sys/kernel/security/lockdown
none [integrity] confidentiality
$ cat /sys/module/module/parameters/sig_enforce
Y
$ cat /sys/kernel/security/lsm
lockdown,capability,yama,bpf,landlock,apparmor,ima,evm
You should see lockdown engaged at [integrity] (the brackets mark the active mode), sig_enforce = Y (unsigned kernel modules are rejected), and the LSM line listing lockdown, landlock, apparmor, ima, evm among others. Integrity lockdown is forced on by the InterGenOS kernel configuration regardless of Secure Boot state, so you see [integrity] here even on a fresh install with Secure Boot off (check 7).
If you don’t see this: [none] selected for lockdown, or sig_enforce = N, means the kernel is not enforcing its integrity guarantees — a significant deviation from a stock install.
5. Nothing failed to start
A clean boot leaves no failed services behind.
$ systemctl --failed
0 loaded units listed.
You should see an empty list — zero failed units.
If you don’t see this: each failed unit is named; systemctl status <unit> and journalctl -u <unit> tell you why. A failed security unit (firewall, auditing) matters more than a failed cosmetic one.
6. The firewall is closed by default
InterGenOS ships a default-deny firewall: inbound connections are dropped unless you open them. Nothing listens to the network on your behalf without you choosing it.
$ sudo nft list ruleset | grep 'hook input'
type filter hook input priority filter; policy drop;
You should see the input chain with policy drop — the default is to reject inbound traffic. The shipped ruleset (/etc/nftables.conf, loaded by nftables.service at boot) permits only loopback, established/related replies, and the ICMP needed for the network to function; SSH and every other inbound port are closed until you open them yourself.
If you don’t see this: an empty result, or an input chain without policy drop, means the default-deny policy is not loaded — check systemctl status nftables. (The shipped ruleset also carries policy drop on the forward chain and policy accept on the output chain — outbound is allowed by design; the input line above is the one that matters here. If you changed the firewall, this reflects your change.)
7. Secure Boot — your state, and how to turn it on
This is the check most likely to surprise you, so read the result carefully.
$ mokutil --sb-state
SecureBoot disabled
You should see SecureBoot disabled on a fresh install — and that is expected, not a failure. InterGenOS provisions a fully signed boot chain (shim → GRUB → Unified Kernel Image) on every install, but ships Secure Boot enforcement off by default. Turning it on is a deliberate, one-time Machine Owner Key (MOK) enrollment you perform — so the key trusting your boot chain is yours, not a vendor’s. The full walkthrough is in Verified Boot & Secure Boot.
You can confirm the firmware’s own view, including TPM and measured-boot support:
$ bootctl status | head -8
systemd-boot not installed in ESP.
System:
Firmware: UEFI ...
Secure Boot: disabled
TPM2 Support: yes
Measured UKI: yes
bootctlreportssystemd-boot not installed— that is correct. InterGenOS boots via shim → GRUB, not systemd-boot; the useful part here is the firmware System block (Secure Boot state, TPM2, Measured UKI).
After you enroll your MOK, mokutil --sb-state reports SecureBoot enabled and the chain is enforced. Re-run check 10 then.
8. Disk encryption — if you chose it at install
If you selected full-disk encryption in FORGE, your root filesystem sits on a LUKS2 volume that unlocks at boot.
$ sudo cryptsetup status root
/dev/mapper/root is active and is in use.
type: LUKS2
cipher: aes-xts-plain64
You should see LUKS2 and active (the mapper name may differ from root depending on your install).
If you don’t see this: is inactive (or no crypt device in lsblk) means this install is not encrypted — expected if you did not choose FDE. Encryption is an install-time choice; see Disk Encryption & LUKS to understand the trade-off.
9. Know your assistant’s state — and how to turn it off
The InterGen assistant is a per-user service. You should always be able to see whether it is running, and you are always in control of whether it runs at all.
$ systemctl --user is-active intergen.service
$ systemctl --user is-enabled intergen.service
You should see the state you chose at install: active / enabled if you opted the assistant in, or inactive / disabled if you did not. The assistant is local-only — it does not phone home — and it is yours to disable.
To turn it off (or constrain it): see Disabling & Constraining the Assistant, the authoritative procedure. You can stop it for this session, disable it from starting, or remove the package entirely.
10. Confirm the boot chain verified this boot (after enrollment)
This last check is for after you have enrolled your MOK and enabled Secure Boot (check 7). It is the difference between “Secure Boot is enabled” and “Secure Boot verified this exact boot and nothing failed.”
$ sudo journalctl -b | grep -iE 'secure boot|sb_verify|mok'
You should see the signature-verification events for the current boot with zero failures. With Secure Boot off (the default), this shows only Secure boot disabled and the firmware’s own certificate load — which is why this check belongs after enrollment.
If you don’t see this: verification failures in the log after you have enabled Secure Boot mean the enforced chain rejected something — stop and investigate before trusting the boot.
You’re done — and you didn’t take our word for any of it
If all the checks that apply to your install passed, you have personally confirmed: the files match the signed release, software comes from a signed source, the kernel is enforcing, the firewall is closed, your boot and encryption posture are what you intend, and your assistant is under your control. That is the whole point — a guarantee you can check is a property of your machine, not a promise from us.
Where to go next
- Security Verification — the per-claim reference behind each check above, in depth.
- Reproducibility & Verification — go further: rebuild a package from source and confirm it matches the published artifact.
- Verified Boot & Secure Boot — enroll your MOK and turn on enforcement.
- Security Handbook — the design behind every guarantee you just verified.
Security Verification
InterGenOS asks you to verify, not trust. Every security claim on this site is something you can check yourself, on your own machine, with a command whose output you can read. This page lists the core claims, the command that proves each one, and what a healthy system shows.
Security is not first. It is only — and a security claim you cannot check is just marketing. So check.
Run these as yourself; a few need
sudo. None of them change anything — they read state and report it.
The boot chain is signed — and Secure Boot enforces it once you enable it
Claim: the machine boots a signed chain (shim → GRUB → Unified Kernel Image), anchored to your Machine Owner Key. Secure Boot enforcement is validated end to end and one enrollment away: the signed chain is provisioned on every install, but enforcement ships off by default, and turning it on is a one-time MOK enrollment you perform yourself.
$ mokutil --sb-state
$ bootctl status
mokutil --sb-state reports whether Secure Boot is enabled; bootctl status shows the active boot loader, the signed entries, and the firmware’s Secure Boot state. On a default install mokutil --sb-state reports Secure Boot disabled — that is expected: the signed chain is in place, but enforcement ships off. After the one-time enrollment at first boot it reports enabled, with your own Machine Owner Key trusting the chain. The full walkthrough is in Verified Boot & Secure Boot.

The whole claim in one frame: InterGenOS booted under enforced Secure Boot — validated end to end in a UEFI VM that enforces it — the chain anchored to your own enrolled Machine Owner Key (CN=InterGenOS Machine Owner Key), the kernel in integrity lockdown and refusing unsigned modules. Enforcement ships off by default; this is the state after you enroll. Every line is something you run and read yourself.
The same matrix has been confirmed with full-disk encryption active — Secure Boot enforcing the chain while a LUKS2-encrypted root unlocks behind it, GRUB carrying its own SBAT record so the chain Secure-Boots with no hand-patching. That combined proof, and the boot itself, are shown on the Verified Boot & Secure Boot page. Secure Boot is off by default; turning it on is the one-time MOK enrollment described there.
The boot chain verified end to end
Claim: verification actually happened at boot — it is not just configured, it ran, and nothing failed.
$ journalctl -b | grep -iE 'sb_verify|mok|verification'
A healthy boot shows the signature-verification events with zero failures. This is the difference between “Secure Boot is enabled” and “Secure Boot verified this exact boot.”
The root image is integrity-sealed (dm-verity)
Claim: the live system image cannot be tampered with — its integrity is sealed by a cryptographic root hash baked into the signed boot image, and checked before it is used.
$ sudo veritysetup status <verity-device>
The sealed igos.verity.roothash lives on the kernel command line inside the signed UKI, so the hash that gates the image is itself covered by the boot signature. At boot, the init path verifies the squashfs against that hash before mounting it — a mismatch stops the boot rather than running a modified image. dm-verity seals the read-only image that the live ISO and the installer boot; once InterGenOS is installed to a writable root, per-file integrity is enforced instead by the signed UKI plus pkm verify (next section) — so on an installed system, integrity is proven by signature and content hash rather than by a dm-verity device.
Every installed file matches what was published
Claim: the files on disk are exactly the files in the signed release — nothing was swapped, corrupted, or silently altered.
$ pkm verify --all
Verified (strict): 831 ok, 0 with issues; 11 expected-absent
pkm records a SHA-256 for every file it installs and re-checks them on demand. A clean system reports every package ok with 0 issues. (The expected-absent entries are files a package’s own post-install step intentionally removes — pkm tracks them so they are never mistaken for tampering or loss; the exact totals track your installed set.) This is the installed-system analogue of the install-time integrity gate: the gate proves what was written, pkm verify proves it stayed that way.
That install-time gate is the very first thing Forge does — before it writes a single file, it verifies the archive set against the release-signed manifest:

The package index is signed by the release key
Claim: updates come only from a package index signed by the InterGenOS release key — a swapped or tampered mirror is rejected, not silently trusted.
$ pkm sync
When pkm syncs the index it verifies the index signature with gpgv against a release-key fingerprint pinned into pkm itself — so even a mirror that presents a different valid-looking key is refused. A good sync shows a VALIDSIG against the pinned fingerprint; you can confirm that fingerprint matches the published release key.
The kernel is locked down and enforcing
Claim: the running kernel is in integrity lockdown, refuses unsigned modules, has the full security-module stack active, and ships a default-deny firewall.
$ cat /sys/kernel/security/lockdown # [none] [integrity] confidentiality — integrity active
$ cat /sys/module/module/parameters/sig_enforce # Y — unsigned modules rejected
$ sudo nft list ruleset | head # input policy drop (default-deny)
$ systemctl --failed # 0 loaded units failed
A healthy InterGenOS system shows lockdown engaged at integrity, sig_enforce=Y, the LSM stack (lockdown / IMA / landlock / AppArmor) active, an nftables ruleset whose input policy is drop, and no failed units. These are the steady-state guarantees the Security Handbook describes — here you confirm them yourself.
Where to go next
- Reproducibility & Verification — rebuild a package from source and confirm it matches the published artifact, byte for byte.
- Package & Config Reference — the full package set, tiers, and configuration the system is built from.
- Security Handbook — the design behind each guarantee you just verified.
- Verified Boot & Secure Boot — the MOK, signed GRUB, dm-verity, and UKI-signing model in depth.
Desktop & Daily Use
InterGenOS ships GNOME 49 on Wayland as its desktop. It is modern, fast, and built for a machine you understand, can modify, and can trust. There is no telemetry, no app-store analytics, and nothing that installs updates on its own.
This section covers what you see and use every day: the desktop environment, the applications that come installed, how you add more, the local AI assistant, and the deliberate omissions that define the system’s posture.
The desktop environment
The default desktop is GNOME 49 running on the Wayland display protocol. X11 applications run through Xwayland automatically when needed.
The visual experience is tuned for the InterGenOS look: the Papirus-Dark icon theme by default, the Bibata-Modern-Classic cursor, a system-wide prefer-dark color scheme, and Inter for UI and document typography paired with JetBrains Mono for terminal and code surfaces. A Cybernetic Blue icon theme ships as a featured alternate, selectable from Settings → Appearance.
Wayland gives each application per-window isolation: one application cannot key-log another or scrape another window’s pixels. It also handles HiDPI, variable refresh rate, mixed-DPI multi-monitor, and touch and gesture input correctly, because the protocol was designed for them.
See Graphical Session (Wayland/X11) for the full breakdown of the session, the Wayland posture, and X11 compatibility.
KDE Plasma, Xfce, and Sway as switchable desktop environments are planned and not yet shipped. The current release ships GNOME only.
What’s installed
The desktop tier provides a fully functional workstation out of the box: Firefox ESR, Files (Nautilus), GNOME Text Editor, GNOME Console, Image Viewer (Loupe), Settings, Calendar, Contacts, the Evince document viewer, and the Totem video player, alongside system utilities such as a disk usage analyzer, system monitor, and screenshot tool.
The total install spans roughly 850 packages across six build tiers (toolchain, core, base, desktop, ai, and extra). These counts drift as the system is built and rebuilt, so derive the live figures from the package set rather than relying on a fixed number.
There is no GUI app store. The software slot is served by pkm, the InterGenOS package manager, from the command line. See The Transparent Package Manager for the full command reference.
Adding more software
The binary repository carries a curated selection of optional, user-facing applications you install on demand. A developer toolchain (Git, Node.js, Go, Rust, Vim) ships by default in the core tier, and a set of modern command-line utilities (htop, rsync, bat, ripgrep, fd) ships in the base tier.
Some proprietary or distribution-restricted applications are available through download-helper packages. These do not bundle the vendor binary; they fetch it from the vendor on first install after you accept the license. The NVIDIA proprietary driver follows the same opt-in pattern under the package name nvidia, offered only on hardware where an NVIDIA GPU is present.
Multimedia and audio are covered in Multimedia & Audio; gaming and Steam in Gaming & Steam; and fonts, input, Bluetooth, and printing in Fonts, Input, Bluetooth & Printing.
Hardware acceleration
The Mesa graphics stack ships and is enabled by default for AMD (Radeon) and Intel (Arc, Iris, UHD) GPUs, covering OpenGL, Vulkan, VA-API hardware video decoding, and OpenCL compute. NVIDIA’s proprietary driver is an explicit opt-in via the nvidia package; the base distribution does not ship proprietary firmware by default. For GPU compute and AI workloads, see the GPU Compute & AI Workloads section.
The local AI assistant
InterGen is a tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry. It runs on your machine, sized to your hardware.
InterGen Sentinel is a pluggable security scanner. By default it uses Local-Rules and a Local-Qwen model, entirely on-device. Six cloud providers — Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek — are available strictly opt-in.
When a task exceeds local capability, Phone-A-Friend (Frontier/Cloud Escalation) lets you route a single request to one of those cloud providers, on your explicit action. Nothing leaves your machine unless you send it. See The AI Assistant for the full picture.
What we don’t ship
InterGenOS makes deliberate omissions:
- No Snap. The
snapddaemon is not installed and not in the repository. - No Flatpak by default. It is available as an optional install if you want sandboxed third-party applications.
- No telemetry. No component of the desktop phones home — not GNOME, not Firefox (telemetry is locked off via Mozilla policy and cannot be re-enabled by users), not the shell, not the package manager.
- No auto-update. No background service applies updates without your explicit action.
- No boot splash. InterGenOS shows your boot. You see the kernel hand off to systemd and every service start with its [OK] or [FAILED] marker. Spotting odd output during boot is a real practice for catching compromise or hardware change; we would rather give you that surface than hide it behind a logo.
Trust foundations
The desktop sits on a signed Secure Boot chain, dm-verity integrity over the read-only system image, and UKI signing. Updates and new software arrive through pkm and a signed package index, never through an opaque auto-updater. The system installer is Forge. For the full security story, see the Security Handbook.
In this section
- Graphical Session (Wayland/X11) — the session, the Wayland posture, and X11 compatibility
- Multimedia & Audio — players, codecs, and the audio stack
- Gaming & Steam — running games on InterGenOS
- Fonts, Input, Bluetooth & Printing — peripherals and daily-driver details
- FAQ — common questions
- Install with FORGE — installing InterGenOS to disk
Graphical Session (Wayland/X11)
InterGenOS 1.0-dev (build id v1.0-dev1) ships GNOME 49 on Wayland as its graphical session. This is the desktop you get today on every install. It is fast, modern, and built to respect your control of the machine: no telemetry, no app-store analytics, and no software that updates itself without you.
The desktop is part of that posture, not separate from it: every system service is confined by AppArmor and systemd isolation from first boot, and Wayland’s per-window isolation means one application cannot key-log another or scrape another window’s pixels.
The display protocol
Wayland is the default and only graphical protocol used for the GNOME session. Every GNOME application ships with native Wayland support.
X11 applications are not left out. Compatibility is provided through Xwayland, a translation layer that runs automatically when an X11 application needs it. You do not configure it or start it by hand: when a legacy application launches, Xwayland is there.
Why Wayland is the default:
- Per-window isolation. Each application sees only its own input and pixel buffer.
- Modern input handling. HiDPI, variable refresh rate, mixed-DPI multi-monitor, and touch/gesture input work because the protocol was designed for them.
- No screen tearing. Every frame is composited through the display server.
- Future-proof. GNOME, Firefox, and the broader Linux desktop are standardizing on Wayland.
Logging in
The graphical session begins at the GDM greeter, where you select your user and authenticate. After login, GDM hands off to the GNOME 49 Wayland session.
The default layout
The default GNOME 49 desktop with the InterGenOS visual language and a bottom application dash.
The desktop is tuned with the InterGenOS visual language: a system-wide prefer-dark color scheme, the Papirus-Dark icon theme (chosen for broad application coverage), and the Bibata-Modern-Classic cursor. A Cybernetic Blue icon theme ships as a featured alternate, selectable from Settings -> Appearance. System typography is Inter for UI and documents, paired with JetBrains Mono for the terminal and code surfaces.
The Adwaita widget theme is the GTK4 baseline, customized through a GSettings override applied at session start, so the look is consistent across core GNOME apps and third-party GTK4 applications installed through pkm.
The Activities overview and application grid
The Activities overview with the application grid, search field, and workspace thumbnails.
Press the Super key (the Windows key on most keyboards) to open the Activities overview. Open windows, workspace thumbnails, the application dash, and a search field are all visible at once. Start typing to search applications, settings, and files; click an icon in the grid to launch.
Alternate panel layout
InterGenOS also ships a panel-style layout for users who prefer a classic, taskbar-driven desktop with a traditional application menu.
A panel-style layout with a bottom taskbar showing pinned and running applications, the system tray, and the clock.
The categorized application menu with places shortcuts, Settings, and session controls.
This menu organizes applications by category (Accessories, Education, Graphics, Internet, Office, Programming, Sound & Video, System Tools, and more), surfaces your home folders and Settings on the right, and provides session controls. It is a familiar metaphor for users coming from a Windows-style or traditional Linux desktop.
Keyboard shortcuts
| Shortcut | Action |
|---|---|
Super | Open Activities overview |
Super + Tab | Switch between open applications |
Super + ` | Switch between windows of the same application |
Ctrl + Alt + T | Open the terminal |
Super + L | Lock screen |
Super + Left/Right | Tile window to the left or right half of the screen |
Super + Up/Down | Maximize or restore the window |
Super + Shift + Arrow | Move window to adjacent monitor |
Ctrl + Alt + Del | Power off / restart dialog |
Alt + F2, then r, then Enter | Restart GNOME Shell (without logging out) |
Multi-monitor, gestures, and accessibility
- Multi-monitor. GNOME 49 handles mixed-DPI and mixed-refresh-rate setups without configuration. Hot-plug a monitor and it works immediately.
- Gestures. Three-finger swipe to switch workspaces, pinch-to-zoom in compatible applications, and touch scrolling on touchscreen hardware.
- Accessibility. Orca screen reader, on-screen keyboard, high-contrast theme, and large-text mode are built in and enabled from the Accessibility panel in Settings.
Hardware acceleration
The graphical session is accelerated through the Mesa graphics stack for AMD (Radeon) and Intel (Arc, Iris, UHD) GPUs:
- OpenGL and OpenGL ES through
radeonsi(AMD) andiris/crocus(Intel) - Vulkan through
radv(AMD) andanv(Intel) - VA-API hardware video decoding through
radeonsiandintel-media-driver - Compute (OpenCL) through
rusticl
All Mesa drivers are installed and enabled by default. GNOME Shell selects OpenGL or Vulkan automatically.
NVIDIA’s proprietary driver is not shipped by default. It is available as an explicit opt-in through pkm install nvidia, offered only on hardware with an NVIDIA GPU present, and presents the NVIDIA license for acceptance before installing.
No boot splash, by design
InterGenOS does not paint a logo over boot. There is no Plymouth splash between the bootloader and the greeter. You see the kernel hand off to systemd, each service report [OK] or [FAILED], your network come up, and AppArmor load. If something fails — a broken mount, an odd module load, a hardware quirk — you see it immediately. This is a security signal, not a polish gap.
On the roadmap (not in this build)
These are roadmap items. They are not part of 1.0-dev today, and you should not expect them in the current image:
- KDE Plasma (Qt6) and other switchable desktop environments. The planned design lets you install an additional desktop through pkm and select it at the greeter, with no reinstall.
The desktop you run today is GNOME 49 on Wayland.
Where this fits
InterGenOS is a built-from-source distribution: a machine you understand, can modify, and can trust. The desktop tier is one of six build tiers (toolchain, core, base, desktop, ai, extra) assembled across the 20-phase build. Package counts drift as the system grows; to see what is installed on your own machine, query pkm rather than relying on a fixed figure.
Cross-references
Multimedia & Audio
InterGenOS ships a working multimedia stack out of the box: a video player with hardware-accelerated decoding, a Wayland-native image viewer, and a document viewer, all running on GNOME 49 over Wayland. Audio editing and music-player applications are available on demand through the package manager. This page covers what plays today, how hardware acceleration is wired up, and which applications you add yourself.
The multimedia stack carries no telemetry, no usage analytics, and no background service. What it does, it does on your machine and nowhere else.
What Ships by Default
The desktop tier installs a functional media set for everyday use. Package counts drift between builds; the desktop tier carried 420 packages as of 2026-06-11, and that figure is not permanent.
| Application | Purpose |
|---|---|
| Totem (Videos) | Video player with hardware decoding through VA-API |
| Image Viewer (Loupe) | Wayland-native image viewer with touch and gesture support |
| Evince (Document Viewer) | PDF, PostScript, DjVu, and comic-book viewer |
For the full default application set, see The Graphical Session.
Hardware-Accelerated Playback
Video playback is hardware-accelerated through the Mesa graphics stack, which ships and is enabled by default for AMD (Radeon) and Intel (Arc, Iris, UHD) GPUs.
- VA-API hardware video decoding runs through
radeonsi(AMD) andintel-media-driver(Intel). - Totem uses VA-API for hardware-accelerated video playback.
- Firefox uses VA-API for hardware-accelerated video on the web.
Common video formats decode on the GPU rather than the CPU, which keeps playback smooth and power draw low on supported hardware.
NVIDIA Hardware
The NVIDIA proprietary driver is not installed by default. It is available as an explicit, user-initiated opt-in through the package manager:
pkm install nvidia
Installing it presents the NVIDIA license for acceptance before the driver is fetched. After install, follow the post-install steps to enroll the NVIDIA kernel module with your Machine Owner Key. Hardware-accelerated rendering and CUDA on NVIDIA hardware depend on this opt-in. See CUDA on NVIDIA for the full NVIDIA path.
Audio and Video Applications
The following media applications are optional. They are not pre-installed; you add them when you need them, through the package manager:
- Audacity — Multi-track audio editor
- Rhythmbox — Music player with podcast support
- Celluloid — GTK4 frontend for mpv
- Transmission — BitTorrent client
Install any of these on demand, for example:
sudo pkm install audacity
Wayland and Media
Every default media application runs on the Wayland display protocol. Wayland’s per-window isolation means each application sees only its own input and pixel buffer: one application cannot scrape another window’s pixels or capture its input. Applications not yet ported to Wayland run through Xwayland, a translation layer that starts automatically when needed. Compositing every frame through the display server also eliminates the screen-tearing artifacts common in legacy X11 video playback.
For the broader display posture, see The Graphical Session.
No Telemetry, No Analytics
No part of the multimedia stack phones home. There is no usage tracking and no app-store analytics. The package manager (pkm) records the packages you have installed for dependency resolution, and that data never leaves your machine. This is a machine you understand, can modify, and can trust.
Planned, Not Shipped
Larger creative and production applications are planned for future releases and are not part of the current build. Do not assume they are present today. When they arrive, you will add them through the package manager like any other optional package.
Cross-References
- The Graphical Session — Default applications, GNOME, and Wayland
- Peripherals — Audio devices and other hardware
- Package Manager — Installing optional applications with pkm
- CUDA on NVIDIA — Opt-in NVIDIA driver and acceleration
- FAQ
Gaming & Steam
This page is explicit about what InterGenOS provides for gaming today, what you install yourself, and what is not bundled. Where a detail is gaming-specific and not yet confirmed against the shipping system, it is flagged rather than invented.
InterGenOS is a built-from-source Linux distribution with a security-only posture: security is not first, it is only. The goal is a machine you understand, can modify, and can trust. Gaming on InterGenOS works the same way it works on any modern Wayland desktop: the graphics and input foundations are already in place, and the game platforms themselves are installed at your discretion.
The Graphics Foundation
Gaming starts with the GPU stack, and that stack ships and is enabled by default.
InterGenOS runs GNOME 49 on Wayland, with the Mesa graphics stack for AMD (Radeon) and Intel (Arc, Iris, UHD) GPUs. This covers the APIs games rely on:
- Vulkan through
radv(AMD) andanv(Intel) - OpenGL / OpenGL ES through
radeonsi(AMD) andiris/crocus(Intel) - VA-API hardware video decode through
radeonsiandintel-media-driver - OpenCL compute through
rusticl
All Mesa drivers are installed and enabled out of the box. GNOME Shell uses OpenGL or Vulkan automatically. X11-only games run through Xwayland, the automatic translation layer for applications not yet ported to native Wayland.
NVIDIA GPUs
NVIDIA’s proprietary driver is not shipped by default. It is available as an explicit, user-initiated opt-in through pkm, and is offered only on hardware with an NVIDIA GPU present:
pkm install nvidia
You accept the NVIDIA license when prompted, then follow the post-install instructions for enrolling the NVIDIA kernel module with your Machine Owner Key. This matters for gaming because the module must be signed and enrolled to load under the signed Secure Boot chain that InterGenOS ships. See CUDA & NVIDIA for the driver path and Encryption & Keys for the Secure Boot and Machine Owner Key details.
Installing Steam
Steam is not part of the default desktop install. The desktop tier (derive the live count from the manifest; it is in the low hundreds of packages as of this writing) is a general workstation set, not a gaming bundle.
InterGenOS provides proprietary and license-restricted applications through download-helper packages. These do not bundle the vendor binary; they fetch it from the vendor on first install after you accept the license. Brave, Google Chrome, the Claude Code CLI, and Microsoft VS Code already ship under this pattern. If you intend to install Steam, check the repository for a helper package first:
pkm search steam
If a helper package is present, install it with pkm install <name> and accept the vendor license when prompted. If no native or helper package is available, Steam can also be run as a sandboxed Flatpak (see below). Confirm what your installed system actually offers with pkm search rather than assuming a package name.
Flatpak for Game Platforms
Flatpak is not pre-installed, but it is available as an optional install when you want sandboxed third-party applications:
sudo pkm install flatpak
Flatpak is a common delivery path for game platforms and launchers; several publish Flatpak builds upstream. It is not pre-installed because the binary mirror’s signed-index trust chain already provides equivalent integrity guarantees for packages built and signed in-tree. For third-party game platforms that InterGenOS does not build itself, the Flatpak sandbox is a reasonable trade.
What Is Not Bundled
InterGenOS makes deliberate omissions, and several of them touch gaming:
- No Snap. The Snap daemon is not installed and not in the repository. Some games and launchers are distributed as Snaps upstream; that is not an installation path here.
- No Flatpak by default. It is one command away, but it is opt-in, not pre-staged.
- No auto-update. No background service downloads or applies updates without your explicit action. Game platforms with their own self-updaters operate within their own sandbox or install scope; the system itself updates only when you run
sudo pkm sync && sudo pkm upgrade. - No telemetry from the OS. No component of the desktop phones home. Game platforms you install have their own privacy behavior, governed by the vendor and, where applicable, the Flatpak sandbox, not by InterGenOS.
Performance Notes
A few system characteristics are relevant to gaming and are confirmed by the shipping design:
- Wayland compositing eliminates screen tearing. Every frame is composited through the display server. Variable refresh rate and mixed-DPI multi-monitor setups are handled by GNOME 49 without manual configuration.
- Per-window isolation. Each application sees only its own input and pixel buffer, so one application cannot key-log another or scrape another window’s pixels. This is a security property that also applies while a game has focus.
- VA-API hardware decode is available for video playback (for example, streaming or recorded gameplay in a player) through
radeonsiandintel-media-driver.
Anti-Cheat and Online Play
Online and competitive games that rely on kernel-level anti-cheat have varying Linux support that depends on the title and the anti-cheat vendor. Because InterGenOS ships a signed Secure Boot chain, dm-verity integrity, and UKI signing, any component that needs to load a kernel module (including some anti-cheat solutions, and the NVIDIA driver above) must be signed and enrolled to load. Check the specific game’s Linux support before relying on it for competitive play.
AI Assistance for Setup
If you get stuck configuring a game platform or a GPU driver, InterGen, the offline-first local assistant (Qwen models, hardware-detected, zero telemetry), can help walk through pkm commands and driver setup without leaving your machine. For questions beyond the local model’s reach, Phone-A-Friend (Frontier/Cloud Escalation) can route to a frontier provider, but only when you choose to invoke it. Nothing leaves the machine by default.
Cross-References
- Desktop & Graphical Session — GNOME 49 on Wayland and the default desktop
- CUDA & NVIDIA — NVIDIA driver opt-in and module enrollment
- Vulkan — Vulkan support across the Mesa stack
- Package Manager — pkm command reference and the signed-index trust chain
- Sandboxing & MAC — AppArmor and systemd isolation
- Encryption & Keys — Secure Boot, dm-verity, and Machine Owner Key enrollment
- FAQ — Common questions about installation and the desktop
Fonts, Input, Bluetooth & Printing
This page covers the everyday peripheral and presentation surfaces of the InterGenOS desktop: system typography, keyboard and input handling, Bluetooth pairing, and printing. The desktop ships GNOME 49 on Wayland, so most of these surfaces are managed through GNOME Settings and the Wayland input stack.
Fonts
InterGenOS ships a deliberate, consistent typographic baseline:
- Inter — a clean geometric sans-serif used across the UI, documents, and titlebars.
- JetBrains Mono — a programming-ligature monospace used for the terminal, the text editor, and other code surfaces.
These pairings define the InterGenOS visual language rather than relying on whatever a toolkit happens to default to. The Adwaita widget theme is the GTK4 baseline and is customized through a GSettings override applied at user-session start, so typography stays consistent whether you are in a core GNOME app or a third-party GTK4 application installed through pkm.
A GNOME Font Viewer utility ships by default for inspecting font files.
Fonts are managed as ordinary pkm packages and install system-wide under /usr/share/fonts/, one directory per family (inter/, jetbrains-mono/, noto/, dejavu/, and the base X11 bitmap sets). The default install ships Inter for UI and document text, JetBrains Mono for the terminal and code, and the Noto families for broad Unicode and CJK coverage. To add more, install a font package with pkm, or drop personal font files into ~/.local/share/fonts/ for a single user and run fc-cache -f to refresh the cache.
Input
InterGenOS uses Wayland for input, with Xwayland providing a seamless translation layer for X11 applications that have not yet been ported.
Why Wayland matters for input
- Per-window isolation: each application sees only its own input and pixel buffer. One application cannot key-log another or scrape another window’s pixels.
- Modern input handling: HiDPI, variable refresh rate, mixed-DPI multi-monitor, and touch and gesture input work correctly because the protocol was designed for them.
Keyboard and pointer
GNOME 49 handles keyboard layouts, repeat rate, and pointer behavior through GNOME Settings. Touchpad and touchscreen gestures work out of the box:
- Three-finger swipe to switch workspaces.
- Pinch-to-zoom in compatible applications.
- Touch scrolling on touchscreen hardware.
Common keyboard shortcuts include Super for the Activities overview, Super + Left/Super + Right to tile a window to the left or right half of the screen, Super + Up/Super + Down to maximize or restore it, and Ctrl + Alt + T for the terminal. The full shortcut reference lives on the Desktop Experience page.
Accessibility input
The Accessibility panel in GNOME Settings provides an on-screen keyboard, the Orca screen reader, a high-contrast theme, and large-text mode for users who need alternative input and output. These are enabled from the Accessibility panel.
Complex-script and CJK input
InterGenOS uses IBus as its input-method framework for CJK and other complex-script input. Fcitx is not shipped.
Bluetooth
Bluetooth is managed through the Bluetooth panel in GNOME Settings, which is part of the default desktop install. From there you can power the adapter on or off, make the machine discoverable, and pair devices such as headsets, keyboards, mice, and controllers.
Under the hood, Bluetooth is provided by the BlueZ stack, with bluetooth.service enabled by default. The bluetoothctl command-line tool is available for users who prefer to manage adapters and pairings from a terminal.
Pairing is an explicit, user-initiated action. No background pairing service or telemetry runs outside this surface, consistent with the InterGenOS goal of a machine you understand, can modify, and can trust.
Printing
Printing on InterGenOS is provided by CUPS. The service is socket-activated: cups.socket is enabled by default and cups.service starts on demand the first time a print queue is contacted, so the print daemon does not run continuously when it is not needed.
Printer configuration on GNOME is normally reached through the Printers panel in Settings. From the command line, CUPS is administered with the standard tools — lpadmin to add and configure printers and lpstat to inspect queues and status.
If a particular printer driver or additional printing component is not present out of the box, search the available packages with pkm. See The Transparent Package Manager for how to search for and install software.
Related pages
- Desktop Experience — the full GNOME 49 on Wayland walkthrough
- Multimedia & Audio — playback, codecs, and the audio stack
- Hardening Baseline — AppArmor, systemd isolation, and the desktop security posture
- The Transparent Package Manager — installing optional software with pkm
System Administration
This section covers the day-to-day operation of an InterGenOS machine: managing users and services, configuring the network, working with filesystems and the boot chain, running virtual machines and containers, and keeping the system maintained over time.
InterGenOS is a built-from-source Linux distribution with a single, consistent design goal: a machine you understand, can modify, and can trust. The administration model reflects that. The system is hardened from the moment it boots rather than after a post-install script, services bind to localhost unless you deliberately open them, and nothing updates or reports home behind your back. Administering the system means making explicit, visible decisions, not discovering hidden ones.
What ships today
The current release is InterGenOS 1.0-dev (build id v1.0-dev1). The desktop is GNOME 49 on Wayland.
Core administration components you will use across the tasks in this section:
- pkm — the package manager. Software is pulled from a signed binary mirror, the index signature is verified on every sync, and each package’s SHA-256 hash is validated locally before install. There are no auto-updates; software changes only when you run pkm yourself.
- Forge — the InterGenOS installer. Forge handles disk layout, initial credentials, and Machine Owner Key (MOK) enrollment for systems that need out-of-tree kernel modules. See the Forge installer guide.
- A signed Secure Boot chain — a Microsoft-signed shim validates the GRUB bootloader, which verifies the kernel and Unified Kernel Images. Installed systems regenerate and sign each kernel’s UKI with your machine’s local MOK on every kernel install or upgrade.
- Image integrity — the read-only live ISO image is sealed with dm-verity (its root hash carried inside the signed UKI); on the installed system, per-file integrity is checked on demand with
pkm verify.
The package set is built across six tiers (toolchain, core, base, desktop, ai, and extra) and totals roughly 850 packages as of June 2026. These counts drift between builds; derive the live figures from the system rather than treating any number as fixed.
On-device assistance
Two local, offline-first tools are available to help administer the system:
- InterGen — a tiered, hardware-detected local assistant built on Qwen models. It runs on-device with zero telemetry.
- InterGen Sentinel — a pluggable security scanner. The defaults are Local-Rules and Local-Qwen, both on-device. Six cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek) are available strictly opt-in. Escalating a scan to one of these external models is called Phone-A-Friend (Frontier/Cloud Escalation); it never happens unless you choose it.
See the assistant documentation for configuration details.
Pages in this section
- Users, Groups & Services — account management and controlling the systemd services that run on your machine.
- Networking — interface configuration and the default localhost-only bind policy for server software.
- Filesystems, Kernel & Boot — storage layout, kernel management, and the signed boot chain including MOK and UKI signing.
- Virtualization & Containers — running virtual machines and containers on InterGenOS.
- Power Management & Maintenance — keeping the system updated, healthy, and efficient over its lifetime.
Security defaults
Much of administering an InterGenOS system is understanding what it already does on your behalf. By default, AppArmor profiles for system daemons run in enforce mode, systemd services are sandboxed with extensive isolation directives, server packages bind only to 127.0.0.1, and no service ships with a blank or default password. There is no telemetry and no analytics. Nothing upgrades itself: the only background package task is a daily update check that notifies you of available upgrades without installing them, and it can be switched off (systemctl disable --now pkm-check-updates.timer).
For the full enforced baseline, read the security section.
Users, Groups & Services
This page covers day-to-day administration of user accounts, groups, and system services on InterGenOS. The defaults described here reflect the design philosophy of the system: a machine you understand, can modify, and can trust.
InterGenOS 1.0-dev (build id v1.0-dev1) ships GNOME 49 on Wayland as its desktop, with systemd as the init system and service manager.
Users and Groups
InterGenOS uses the standard Linux user and group model. Accounts live in /etc/passwd, groups in /etc/group, and shadowed password hashes in /etc/shadow. The usual coreutils and shadow-suite tools apply.
Creating and managing accounts
# Add a new user with a home directory and login shell
useradd -m -s /bin/bash alice
# Set or change a password
passwd alice
# Add a user to a supplementary group
usermod -aG <group> alice
# Lock or unlock an account
usermod -L alice
usermod -U alice
# Remove a user (and optionally their home directory with -r)
userdel -r alice
Group management follows the same conventions:
groupadd developers # create a group
gpasswd -a alice developers # add a member
groupdel developers # remove an empty group
Account policy
InterGenOS does not ship services or databases with blank or default admin passwords. Initial credentials are randomly generated or set up manually during installation, so there is no well-known account to compromise on a fresh system. When you create accounts afterward, you choose the credentials and the policy.
On a default install, password quality is enforced by pam_pwquality: a password must be at least 12 characters and include at least one uppercase letter, one lowercase letter, one digit, and one other character, with no more than three identical characters in a row — and the rule applies to root as well. Repeated failed logins are rate-limited by pam_faillock. Passwords do not expire on a timer by default, because forced rotation tends to push people toward weaker, more predictable choices; you are free to set an expiry policy if your environment requires one. The first account Forge creates is added to the administrative wheel group (which grants sudo) along with the audio, video, input, cdrom, and lpadmin groups for desktop hardware and printing.
The first user account is created during installation by Forge, the InterGenOS installer. See the Forge installer guide for how the initial account and its administrative access are set up.
Privilege escalation
Administrative actions are performed with sudo rather than by logging in as root directly. InterGenOS does not ship doas. Administrative users are granted their elevated access by membership in the wheel group.
Services and the Init System
InterGenOS uses systemd to manage services, sockets, timers, and the boot sequence. Administration uses the standard systemctl and journalctl tooling.
Managing services
systemctl status <unit> # inspect a service
systemctl start <unit> # start now
systemctl stop <unit> # stop now
systemctl restart <unit> # restart
systemctl enable <unit> # start at boot
systemctl disable <unit> # do not start at boot
systemctl enable --now <unit> # enable and start in one step
Reading logs
journalctl -u <unit> # logs for one unit
journalctl -b # logs since the current boot
journalctl -f # follow new log entries live
Service Hardening Defaults
InterGenOS does not rely on post-installation hardening scripts. System services are sandboxed from the moment the system boots, to minimize the blast radius of a potential compromise. Every system daemon runs under extensive systemd isolation directives, and InterGenOS additionally ships AppArmor profiles for selected daemons. Profiles are loaded with apparmor_parser (/usr/sbin/apparmor_parser). The default AppArmor mode is enforce, with a few shipped profiles intentionally written in complain (learning) mode — currently intergen-mcp and pkm — which graduate to enforce per-profile as confidence builds.
The baseline systemd directives applied across system daemons include:
| Directive | Effect |
|---|---|
NoNewPrivileges=true | A service and its children cannot gain new privileges |
ProtectSystem=strict | The entire filesystem hierarchy is read-only to the service |
ProtectHome=true | User home directories are inaccessible |
PrivateTmp=true | The service gets a private, isolated /tmp |
PrivateDevices=true | Only a minimal, virtual /dev is exposed |
ProtectKernelTunables=true | /proc and /sys kernel tunables are read-only |
ProtectKernelModules=true | Module load/unload is denied |
ProtectKernelLogs=true | The kernel ring buffer is inaccessible |
ProtectControlGroups=true | The cgroup hierarchy is read-only |
ProtectHostname=true | The hostname cannot be changed |
ProtectClock=true | The system clock cannot be changed |
ProtectProc=invisible | Other processes are hidden in /proc |
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 | Only these socket families are permitted |
RestrictNamespaces=true | Creating new namespaces is denied |
RestrictRealtime=true | Realtime scheduling is denied |
RestrictSUIDSGID=true | Creating SUID/SGID files is denied |
LockPersonality=true | The execution-domain personality is locked |
MemoryDenyWriteExecute=true | Writable-and-executable memory is denied (a package whose runtime needs a JIT can set this to false in its own unit, as PostgreSQL does for its LLVM JIT) |
RemoveIPC=true | IPC objects are cleaned up when the service stops |
SystemCallArchitectures=native | Only native-architecture syscalls are allowed |
SystemCallFilter=@system-service | A baseline syscall allowlist is enforced |
SystemCallFilter=~@privileged @resources @mount @swap @reboot | Privileged and dangerous syscall groups are denied |
You can inspect the effective sandbox of any running service with:
systemd-analyze security <unit>
Safe network binds
Any server package shipped by InterGenOS binds exclusively to localhost (127.0.0.1) by default. Services never listen on public interfaces unless you deliberately edit their configuration to allow it. If you intend to expose a service, that is a conscious change you make, not a default you have to discover and undo. See Network security for the broader posture.
Overriding the defaults
These directives are defaults, not a cage. Because you control your own machine, you can relax a directive for a specific service with a drop-in override:
systemctl edit <unit>
This creates a drop-in under /etc/systemd/system/<unit>.d/ that layers on top of the shipped unit without modifying it. Reload and restart to apply:
systemctl daemon-reload
systemctl restart <unit>
For the rationale behind these controls and how they fit the wider security model, see Sandboxing and mandatory access control and the Hardening baseline.
What Runs By Default
InterGenOS keeps the running surface small. It collects zero telemetry, no analytics, and no crash or usage reports, so there are no background phone-home services to disable. The system will not update software behind your back; updates happen only when you explicitly run the package manager. There are no opt-out privacy toggles to hunt for, because the data never leaves to begin with.
Two InterGenOS services are worth knowing about because they are part of what makes the system distinctive:
- InterGen is a tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry. It runs locally and selects a model tier appropriate to your hardware. When a query exceeds local capability, the optional “Phone-A-Friend” (Frontier/Cloud Escalation) path can hand off to a remote model, but only when you invoke it.
- InterGen Sentinel is a pluggable security scanner. Its default backends are Local-Rules and Local-Qwen, both running on your machine. Cloud providers are available strictly opt-in — currently Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek.
Neither sends anything off the machine unless you explicitly opt into a cloud backend.
See Also
- Forge installer guide — how the first account is created
- Maintenance — updates and ongoing administration
- Networking — interfaces and connectivity
- Sandboxing and mandatory access control
- Hardening baseline
- Frequently asked questions
Filesystems, Kernel & Boot
This page explains how an installed InterGenOS system boots: the signed boot chain, the per-machine signing key, optional full-disk encryption, and how the kernel is rebuilt and signed on every install or upgrade. It is written for users and contributors who want to understand the model well enough to operate and recover it.
The boot path is the most privileged code on the machine, so InterGenOS verifies every executable that runs before userspace and gives you a machine you understand, can modify, and can trust.
For the installer that sets all of this up, see Forge, the installer. Related deep dives ship as Verified boot and Disk encryption.
The boot chain at a glance
InterGenOS builds a fully signed boot chain, though it does not require UEFI Secure Boot — the default fleet install runs with it off, so the signatures are present and verifiable but not firmware-enforced unless you enable Secure Boot. The chain of trust runs:
Firmware (UEFI)
│ trusts the Microsoft 3rd-party CA
▼
Microsoft-signed shim (v1.0 piggybacks Fedora's pre-signed shim)
│ trusts your machine's MOK
▼
InterGenOS GRUB (release-signed on the ISO/install media;
│ enforces signature MOK-signed for the GRUB written to disk)
│ verification on UKIs
▼
InterGenOS UKI (kernel + initramfs + cmdline, bundled and
│ kernel handoff signed as one Authenticode binary)
▼
InterGenOS userspace
A Unified Kernel Image (UKI) is a single signed file that bundles the kernel, the initramfs, and the kernel command-line. One signature covers all three; nothing inside can be swapped without breaking it.
The live ISO and install media ship UKIs signed by the InterGenOS release key, which lives only on an offline signing workstation and never touches your machine. Once you install to disk, every kernel you install or upgrade is rebuilt into a UKI on your machine and signed with your own key.
The Machine Owner Key (MOK)
A Machine Owner Key is a per-machine signing key generated on your own machine during install. The firmware trusts it because you enroll it once, via MokManager, at first boot. It exists so that:
- Your machine signs the kernels you install. When you install a kernel, InterGenOS rebuilds the UKI and signs it with your MOK. The release key never sees a kernel you build or install locally.
- You can trust your own out-of-tree drivers. Modules you build (for example, proprietary GPU drivers via DKMS) can be signed by your MOK and load on a Secure Boot system without disabling enforcement.
The MOK is yours and lives only on the installed system, under /var/lib/intergen/mok/. Reinstalling generates a fresh MOK; migrating to a new machine means generating a new one there.
During the bootloader stage, the Forge installer generates an RSA-2048 MOK keypair as mok.key (private), mok.crt (PEM X.509, used by sbsign for UKI signing), and mok.der (DER X.509, the form MokManager wants for enrollment). It also generates a random 12-character enrollment password, stages the MOK for enrollment, installs ukify and sbsigntool so the kernel package can build and sign UKIs later, installs an initial MOK-signed UKI, and configures a recovery boot entry that loads the bare vmlinuz.
Forge shows the enrollment password on the install-complete screen and writes it to /var/log/intergen-install.log. Write it down before you reboot. You need it once.
First-boot MOK enrollment
On the first boot, the firmware sees the pending enrollment request and runs MokManager (blue text on black) through three screens:
- Perform MOK management — press any key to start.
- Enroll MOK — review the certificate. Its subject reads
CN=InterGenOS Machine Owner Key. Confirm. - Enter password — type the enrollment password. It is single-use.
After enrollment, the system boots normally and the firmware trusts your MOK from then on. If you skip enrollment, the system still boots the release-signed UKI that shipped on the installer image, but the next kernel upgrade (which produces a MOK-signed UKI) will not be trusted, and you fall through to the recovery entry until you enroll.
Kernel install and upgrade
When you install or upgrade a kernel with pkm install linux-kernel-X.Y.Z, the kernel package’s post_install hook runs entirely on your machine, with no release-infrastructure key material:
- Reads the kernel, the standard initramfs (plus the FDE initramfs if the system is LUKS-encrypted), and the canonical command-line.
- Runs
ukify buildto bundle them into a single UKI. - Runs
sbsign --key /var/lib/intergen/mok/mok.key --cert /var/lib/intergen/mok/mok.crtto sign the UKI. (sbsignreads the PEM cert; the.derform is for MokManager enrollment only.) - Writes the signed UKI to
/boot/efi/EFI/Linux/intergenos-<kernel-version>.efi. - Updates the GRUB menu so the new kernel is the default entry.
- Retains a configurable number of old kernels and their UKIs as fallback entries (default: 2).
If signing fails (corrupt key file, full ESP), the hook falls back to writing the kernel and initramfs separately and having GRUB load them directly. GRUB is itself signed and enforces check_signatures=enforce, so the same verification semantics apply. You never end up with a half-installed kernel.
ESP sizing
Because every installed kernel becomes a UKI in /boot/efi, the ESP needs headroom for several kernel generations. A typical UKI is 80–150 MB depending on the initramfs payload. Forge creates a fixed 1 GiB ESP, leaving room for several kernel generations. If the ESP fills up, kernel install fails with a clear message; free space with pkm remove linux-kernel-<old-version>.
Full-disk encryption (LUKS2)
Full-disk encryption is opt-in, not default. Forge asks; you choose. We recommend it for any portable device.
- The format is LUKS2 with a passphrase, via
cryptsetup: AES-256 in XTS mode, withargon2id(memory-hard) key derivation. Forge forces argon2id parameters (1 GB memory cost, 4 iterations, 4 threads) calibrated to defeat GPU-accelerated brute force without risking out-of-memory on 4 GB systems. - The encrypted volume holds the entire root filesystem —
/home,/var,/etc,/root, and swap if placed inside the container. - Your passphrase is never written to disk outside the LUKS header slot, never logged, and never sent anywhere. There is no recovery key escrow and no master key. If you forget your passphrase, the data is gone by design.
- The ESP is not encrypted — the firmware must read it before any OS runs. Its integrity is protected by Secure Boot verification on the UKI, not by encryption.
A LUKS2 volume has a header (cipher metadata plus up to eight key slots), independent key slots (each wrapping the master key with one unlock method), and the encrypted payload. The master key never leaves the header; your passphrase unwraps a slot to yield it, and the passphrase lives only in volatile memory during unlock.
What Forge does for an encrypted install
When you tick Encrypt the root filesystem with LUKS2, Forge prompts for a passphrase with a confirmation field. Both frontends enforce a non-empty, matching value and surface a soft strength warning (8 characters is the floor; 12 with at least two character classes is the recommended baseline). The warning does not block — you confirm and continue. Forge then formats the partition with cryptsetup luksFormat, writes /etc/crypttab (mapper name cryptroot, referenced by UUID=), writes /etc/fstab with /dev/mapper/cryptroot as the root source, and the kernel hook bundles the FDE initramfs into the signed UKI. The passphrase is piped to cryptsetup via stdin (never on the command line), zeroized after use, and never written to disk outside the LUKS header.
Experimental unlock methods
Two unlock methods are wired as EXPERIMENTAL v1.0 sub-options. Both compose with the passphrase by adding an extra LUKS key slot; the passphrase slot is always retained as the unconditional fallback.
- TPM2-sealed unlock seals a fresh 32-byte key against the current measured-boot state, bound to a PCR0 + PCR7 policy (PCR0 tracks firmware code; PCR7 tracks Secure Boot policy/MOK state). The sealed blob triplet is written to the ESP under
/intergen/tpm2/. Normal boots then unlock automatically. It is EXPERIMENTAL because a firmware update (PCR0) or a Secure Boot/shim/MOK change (PCR7) invalidates the seal and falls through to the passphrase. The sub-checkbox is greyed out if no TPM is exposed (/dev/tpmrm0absent) or the TPM2 tools are missing from the ISO. - FIDO2-token unlock enrolls a credential on a FIDO2 token (YubiKey, Solo, Nitrokey, and similar). Enrollment runs
fido2-cred -Mthen afido2-assert -G --hmac-secretagainst a random nonce; the HMAC output becomes a LUKS slot. The relying-party ID isintergenos. Forge writes{cred_id, stored_nonce}to the ESP under/intergen/fido2/. A lost or swapped token invalidates the slot, so the passphrase stays in the header for fallback.
Neither the TPM2 sealed blob nor the FIDO2 metadata is secret on its own: without the specific TPM (and matching PCR state) or the physical token, those files are useless.
The boot-time unlock flow
After Secure Boot verifies the UKI and the kernel hands off to the FDE init, the unlock chain runs in order:
- TPM2 (if enrolled and
/dev/tpmrm0present):tpm2_load+tpm2_unsealagainst the PCR0+PCR7 policy, piped tocryptsetup. On any failure, fall through. - FIDO2 (if enrolled and tools available): wait up to 30 s for the token, run
fido2-assertagainst the stored nonce, pipe the HMAC tocryptsetup. On any failure, fall through. - Passphrase prompt (always the final fallback): an InterGenOS-branded prompt with three attempts, then a recovery shell.
If neither experimental method is enrolled, the chain skips straight to the passphrase prompt and the path is identical to a passphrase-only install. The FDE initramfs is tiny — a static cryptsetup, a static busybox, the dm_crypt/ext4 modules, and the storage drivers needed to see the disk (plus the static TPM2/FIDO2 tools and their modules when those methods are enrolled). It does no logging, no telemetry, and no network.
The FDE init emits journal-friendly prefixes you can correlate after boot:
| Prefix | Meaning |
|---|---|
[fde-init][EXPERIMENTAL TPM2] | TPM2 unlock attempt and outcome (skipping, attempting via sealed key, tpm2_load failed, unseal/cryptsetup failed, or success). |
[fde-init][EXPERIMENTAL FIDO2] | FIDO2 unlock attempt and outcome (skipping, attempting, no token within 30s, a pipeline diagnostic, or success). |
[fde-init] (no suffix) | Passphrase prompt path, recovery-shell drop, and root-mount errors. |
Search them with journalctl -b | grep fde-init.
How encryption and signed boot compose
The encrypted-root and signed-boot models are designed to compose. On a non-encrypted install the UKI’s bundled initramfs is minimal (typically only CPU microcode), because storage and filesystem drivers are built into the kernel. On an encrypted install, the UKI’s bundled initramfs is the FDE initramfs: the same code that prompts for your passphrase is inside the same signed envelope as the kernel.
The practical consequences:
- An attacker cannot substitute a fake unlock prompt to capture your passphrase, because the prompt code is inside the signed UKI. Tamper with it and Secure Boot refuses to load it.
- A kernel upgrade rebuilds the UKI with the new kernel and the same FDE initramfs, signed with your MOK. The unlock experience is identical across upgrades.
- A TPM2-sealed unlock does not skip Secure Boot verification; the TPM bits live inside the signed envelope too.
What encryption does and does not protect
Protected at rest: the entire root filesystem and anything written to disk while the system is running and unlocked.
Not protected: the ESP (read by firmware before any OS; integrity comes from Secure Boot, not encryption); the LUKS header itself (visible on disk — it reveals that the partition is LUKS and which cipher is used, but nothing about the payload); and a running, unlocked system (the master key is in kernel memory and the filesystem is readable to permitted processes). Encryption-at-rest does not replace process isolation, user permissions, or AppArmor confinement. If your threat model includes someone with physical access while the machine is running and unlocked, you want a screen lock or a powered-off machine, not just FDE.
Recovery
Most of the time none of this needs attention. When something goes wrong:
Add or remove a LUKS passphrase
LUKS2 supports up to eight key slots. From a running system, as root:
cryptsetup luksAddKey /dev/disk/by-uuid/<uuid>
cryptsetup luksRemoveKey /dev/disk/by-uuid/<uuid>
luksAddKey prompts for an existing passphrase, then the new one. luksRemoveKey prompts for the passphrase of the slot to remove; other slots are untouched.
Back up the LUKS header
If the header is corrupted (disk damage at the wrong offset, or an accidental dd), the payload is unrecoverable even with the correct passphrase. Back it up to offline media:
cryptsetup luksHeaderBackup /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
cryptsetup luksHeaderRestore /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
Anyone with the backup and your passphrase can decrypt the disk; store it accordingly.
I forgot my LUKS passphrase
The data is gone. There is no master key, no escrow, and no back door, because a recovery channel we could use is a channel an attacker could use. Boot a live ISO and reinstall. Back up early and often.
I need to regenerate the MOK
The MOK lives under /var/lib/intergen/mok/. On a default install Secure Boot is off and there is no enrollment password to lose. If you run with Secure Boot enabled and need a fresh MOK, reinstalling with Forge regenerates one; the next kernel install or upgrade rebuilds the UKIs with it, and the bare-vmlinuz fallback in GRUB keeps the system booting in the meantime. (There is no separate recovery wrapper command — UKI signing is handled by the kernel package’s post-install hook.)
Boot dropped me to the FDE recovery shell
Three failed passphrase attempts (or a missing /etc/crypttab or LUKS volume) drop you to a minimal busybox shell with cryptsetup. From there:
cryptsetup open /dev/disk/by-uuid/<uuid> cryptroot
mount /dev/mapper/cryptroot /newroot
exec switch_root /newroot /sbin/init
Use ls /dev/disk/by-uuid/ to inspect what enumerated, and reboot -f to reboot (the standard reboot is not available pre-systemd). The recovery shell has no network and no logs by design.
Secure Boot is refusing my new kernel
Usually the MOK was not enrolled (or was un-enrolled) but the post-install hook signed a UKI with it. Boot the recovery entry (bare vmlinuz via GRUB), then re-enroll or regenerate the MOK.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Boot prompt asks for the passphrase but every attempt fails | Wrong passphrase, or boot keyboard layout differs from inside the OS | The FDE initramfs uses US-QWERTY by default; type the QWERTY equivalents for layout-sensitive characters. |
| Boot drops to the FDE recovery shell: “no LUKS volume specified” | /etc/crypttab was not written, or encryption did not complete | cat /etc/crypttab; if empty, reinstall from a live ISO with encryption enabled. |
| Boot drops to the FDE recovery shell: “LUKS volume not found after 30s wait” | Disk did not enumerate in time (failing/USB/RAID-slow) | ls /dev/disk/by-uuid/; if the volume appears, retry cryptsetup open manually. |
| TPM2-sealed unlock falls through to passphrase | PCR0 or PCR7 changed (firmware update, Secure Boot reconfig, shim/MOK update) | Enter the passphrase; re-enroll TPM2 against the new PCR state. Check `journalctl -b |
| FIDO2 unlock does not detect the token | Token plugged in too late, or dead battery | Plug in before boot (30 s window); fall back to passphrase. Check `journalctl -b |
| New kernel installs but won’t boot, falls through to recovery | UKI signed with a MOK the firmware doesn’t trust | Re-enroll the MOK, then re-run the kernel post-install hook. |
| GRUB menu shows only the recovery entry | UKI signing has been failing silently | Inspect /var/log/intergen-kernel-postinstall.log; ESP-full and a missing MOK key file are the common causes. |
| The ESP filled on a kernel upgrade and the new UKI was skipped | UKI generation logged ESP-full and kept the previous default | pkm remove linux-kernel-<old-version> to free space, then re-run the post-install hook. |
ukify is missing on the installed system | Forge skipped the UKI tooling on an older or different-boot-path install | pkm install ukify sbsigntool and re-run the post-install hook for the current kernel. |
Running unsigned kernels
Don’t, on a real install. Every kernel that boots is signed. Build your kernel, sign it with your MOK using sbsign, and install it through the same pkm flow as everything else. To test bare unsigned kernels, use a VM with Secure Boot off.
Further reading
- Forge, the installer — the install flow that sets up the MOK, the boot chain, and optional encryption.
- Verified boot and Disk encryption — the install-side companions to this page.
- FAQ — quick answers to common boot and encryption questions.
Networking
This page covers day-to-day network administration on InterGenOS: bringing interfaces up with DHCP or static addressing, joining a VPN, and reasoning about the firewall posture. InterGenOS ships GNOME 49 on Wayland, so most desktop users will manage connections through the graphical network panel, while administrators and contributors can drop to the command line for the same operations.
Networking on InterGenOS inherits the system’s overall stance: security is not first. It is only. Defaults are conservative, nothing listens on a public interface unless you ask it to, and the network never carries telemetry off your machine. The goal is a machine you understand, can modify, and can trust.
Default Network Posture
Two defaults shape everything else on this page:
- Services bind to localhost. Any server package shipped by InterGenOS binds exclusively to
127.0.0.1by default. Services do not listen on public interfaces unless you deliberately edit their configuration to allow it. This means a freshly installed system exposes effectively no network attack surface on its own. - No traffic leaves on its own. InterGenOS collects zero analytics, crash reports, or usage statistics, and it does not auto-update. The only outbound connections your system makes are the ones you initiate, plus package operations you explicitly run (such as
pkm syncagainst the signed mirror).
Because of the localhost-bind default, opening a service to the network is a deliberate, auditable act rather than something you have to discover and switch off after the fact.
Managing Connections
From the desktop
On the GNOME 49 Wayland session, use the Settings -> Network (wired) and Settings -> Wi-Fi panels, or the system status menu in the top bar, to connect to wired and wireless networks. This is the recommended path for laptops and workstations: DHCP works out of the box, and the panel handles Wi-Fi credentials, per-connection settings, and VPN profiles.
Static vs. DHCP
DHCP is the default for new connections. To assign a static address from the desktop, open the connection’s settings in the Network or Wi-Fi panel, switch the IPv4 (or IPv6) method from Automatic (DHCP) to Manual, and enter the address, prefix/netmask, gateway, and DNS servers for your network. Apply the change and reconnect the interface for it to take effect.
NetworkManager is the default network management daemon and is enabled at boot. Administrators can manage connections from the command line with nmcli or the text-based nmtui, which drive the same connections as the desktop panels. (systemd-networkd ships as well but is disabled by default; it is available for hosts that prefer a networkd-based configuration.)
For headless or server-style hosts, configure the same wired/static/DHCP choices with nmcli, which creates and edits NetworkManager connection profiles directly. Use nmcli connection to add, modify, and bring profiles up or down without the desktop panel.
VPN
InterGenOS supports standard Linux VPN clients. The desktop network panel can import and manage VPN connections, and command-line clients can be installed and configured directly.
A VPN changes which interface and DNS your traffic uses, so keep the localhost-bind default in mind: a VPN tunnel does not, by itself, expose any local service to the remote network. If you want a service reachable over a VPN, you still have to bind it beyond 127.0.0.1 and open the firewall for it deliberately.
No VPN client ships by default — there is no preinstalled WireGuard, OpenVPN, or Tailscale on a fresh install. Install the client you need with pkm (for example WireGuard or OpenVPN), then configure it through the desktop network panel or its own command-line tooling.
Firewalling
Because shipped services bind to localhost by default, the network attack surface of a default install is minimal before you add a firewall on top. For systems that expose services intentionally, or that sit on untrusted networks, configure a host firewall to make the allowed-traffic policy explicit and auditable.
InterGenOS layers several controls beneath the firewall that are relevant to network exposure:
- AppArmor in enforce mode confines system daemons, limiting what a compromised network-facing service can reach.
- Aggressive systemd sandboxing restricts each service’s address families. The baseline
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6directive, applied across system daemons, denies access to other socket families entirely. - No default passwords. InterGenOS does not ship services with blank or default credentials, so an exposed service is not also a free login.
The host firewall is nftables (the nft command), enabled by default with a default-deny posture: inbound traffic is denied unless a rule allows it. InterGenOS does not ship firewalld or ufw, so rules are expressed and audited directly in nftables.
For the firewall configuration itself, and for the reasoning behind the network-exposure defaults, see the security handbook page on Network Security & Firewalling.
Verifying Network State
Treat what the system reports as the source of truth rather than assuming. To confirm what is actually listening and where, inspect the live socket and routing state on your machine (for example with the standard ss and ip tooling), and compare it against your intended policy. If a service is listening on anything other than 127.0.0.1, that exposure was configured deliberately and should match a firewall rule you can point to.
Further Reading
- Network Security & Firewalling — the security-handbook treatment of firewall policy and network exposure.
- Attack-Surface Minimization — why InterGenOS ships almost nothing listening by default.
- Users, Groups & Services — managing the services that may bind to the network.
- Self-Hosting Securely — exposing your own services on purpose, safely.
- FAQ — common questions about defaults and behavior.
Virtualization & Containers
This page covers running containerized workloads on InterGenOS. The container stack ships as installable packages in the extra tier; nothing container-related runs until you install it and opt in. That posture is deliberate: security is not first. It is only. The goal is a machine you understand, can modify, and can trust, so a root-privileged daemon never starts on your behalf.
InterGenOS is built from source. The container engines and their runtimes are compiled and signed alongside the rest of the system, verified by pkm before installation against the live package index. See Repository Trust and the Package Manager for how that verification works.
Containers
InterGenOS provides two OCI container engines today: Podman and Docker. Both are open-source (Apache-2.0), and both manage standard OCI images and containers.
Podman
Podman is the daemonless OCI engine. It runs containers without a long-lived background service and supports rootless operation, which fits the system’s least-privilege posture. The Podman package pulls in the supporting runtime stack automatically as dependencies:
- crun — low-level OCI runtime
- conmon — container monitor for
conmon-managed processes - netavark and aardvark-dns — container networking and name resolution
- fuse-overlayfs — userspace overlay storage driver for rootless containers
- catatonit — minimal init for container PID 1
- containers-common — shared configuration for container tools
- passt — userspace networking
Install it with pkm:
sudo pkm install podman
Once installed, Podman is invoked directly. Because it is daemonless, there is no service to enable before you can run a container.
Docker
Docker ships as a separate, opt-in package. It bundles the Docker engine (dockerd and docker-proxy), the docker CLI, and an init for container PID 1. Docker depends on containerd (its runtime peer) and runc (the low-level OCI runtime), both built and pinned alongside it.
Docker is mirror-only: it is not part of the default desktop image, so it never lands on a system without explicit operator action. Install it with pkm:
sudo pkm install docker
Unlike Podman, Docker uses a root-privileged daemon. To honor the secure-default posture, docker.service and docker.socket ship disabled. The daemon does not start until you opt in:
sudo systemctl enable --now docker.socket
Until you run that, the Docker daemon is not listening and not running. This is a belt-and-suspenders default on top of the mirror-only inclusion: even after install, you make a deliberate choice to start a privileged daemon.
Choosing between Podman and Docker
If you want a daemonless, rootless-capable engine that keeps privilege low by default, use Podman. If your existing tooling or CI expects the Docker daemon and socket, install Docker and enable it explicitly. Both consume and produce standard OCI images, so workflows are portable between them.
Virtual machines
No VM or hypervisor packages ship by default — there is no QEMU, libvirt, or GNOME Boxes on the desktop image. The current release focuses on the OCI container stack described above. If you need full virtual machines, install the tooling you want with pkm.
Defaults and posture
- Nothing pre-installed. No container engine is present in the desktop image. You install exactly what your workload needs.
- No privileged daemon by default. Podman is daemonless; Docker’s daemon and socket ship disabled and require an explicit
systemctl enable --now. - Verified before install.
pkmchecks signatures against the trusted package index before any container package is placed on disk. - No telemetry. The container stack carries no usage reporting off your machine.
Further reading
- Package Manager — installing and managing packages with
pkm - Repositories — where packages come from and how they are trusted
- Sandboxing & Mandatory Access Control — the broader confinement model
- Package & Config Reference — the generated catalog of what InterGenOS ships
- FAQ
Power Management & Maintenance
This page covers keeping an InterGenOS machine healthy over its lifetime: applying updates, managing power and battery, watching disk and journal usage, and verifying that the signed boot chain and system image are still intact. The defaults described here follow the same principle as the rest of the system. Nothing happens behind your back; maintenance is a set of explicit, visible actions you take.
InterGenOS 1.0-dev (build id v1.0-dev1) ships GNOME 49 on Wayland, with systemd as the init system and service manager. The tooling below is standard systemd and InterGenOS pkm.
Updating the System
There are no automatic upgrades. Software changes only when you run the package manager yourself. This is deliberate: updates are a decision you make, not one made for you.
Updates flow through pkm, the InterGenOS package manager. Software is pulled from a signed binary mirror. Every sync verifies the index signature against a release-signing subkey (held on a hardware token and certified by the offline InterGenOS master key), and each package’s SHA-256 hash is validated locally before it is installed.
sudo pkm sync # refresh and cryptographically verify the package index
sudo pkm upgrade --all # apply available upgrades for everything installed
pkm sync (also spelled pkm update) only refreshes the local copy of the signed index and verifies its signature; it changes nothing on disk. pkm upgrade is the command that actually installs newer versions — --all upgrades everything, or name specific packages. Your system stays exactly as you left it until you run pkm upgrade.
InterGenOS does ship one background package task: a daily timer that checks for available upgrades and shows a count (a GNOME tray indicator and a login message) but never installs anything. It is opt-out — sudo systemctl disable --now pkm-check-updates.timer. For the full pkm command surface and the notification details, see The Transparent Package Manager.
For the repository verification model behind these commands, see the security section.
Kernel updates and the boot chain
When you install or upgrade a kernel, the installed system regenerates and signs that kernel’s Unified Kernel Image (UKI) with your machine’s local Machine Owner Key (MOK). The same boot-time signature verification that protects the original ISO image therefore continues to apply to every kernel you install afterward. You do not need to re-run any signing step by hand; it happens as part of the kernel install or upgrade.
If your hardware needs out-of-tree modules (for example proprietary drivers), Forge walks you through MOK enrollment on first boot. See Filesystems, Kernel & Boot for the storage and boot-chain detail, and the Forge installer guide for enrollment.
Power Management
InterGenOS uses systemd for power state transitions. The standard commands apply:
systemctl poweroff # shut down
systemctl reboot # restart
systemctl suspend # suspend to RAM
systemctl hibernate # suspend to disk
systemctl hybrid-sleep # suspend to both RAM and disk
On the GNOME 49 desktop, power settings (screen blanking, automatic suspend, what the power button does, and battery behavior on laptops) are exposed through GNOME’s Settings under the Power section. These are user-facing preferences and do not change the system’s security posture.
Logind governs lid-switch, idle, and power-key behavior at the system level through /etc/systemd/logind.conf (and drop-ins under /etc/systemd/logind.conf.d/). After editing, apply with:
systemctl restart systemd-logind
Power profiles are managed by power-profiles-daemon, which is integrated with the GNOME power settings. You can switch and query profiles from the command line with powerprofilesctl. InterGenOS does not ship tlp or thermald; profile management goes through this single daemon.
Battery and thermal status
The kernel exposes battery and thermal information through sysfs, which you can read without additional tooling:
cat /sys/class/power_supply/BAT0/capacity # battery charge percentage
cat /sys/class/power_supply/BAT0/status # charging / discharging / full
The device name (BAT0, BAT1, and so on) depends on your hardware. List /sys/class/power_supply/ to see what your machine exposes.
Disk and Storage Maintenance
Keeping an eye on disk usage is the most common maintenance task. The standard tools apply:
df -h # filesystem usage by mount point
du -sh <dir> # size of a directory tree
Journal management
systemd retains logs in the journal. Over time this can grow. Inspect and bound it with journalctl:
journalctl --disk-usage # how much space the journal occupies
journalctl --vacuum-size=500M # trim the journal down to 500 MB
journalctl --vacuum-time=2weeks # drop entries older than two weeks
For reading logs day to day, see Users, Groups & Services.
Package cache
pkm keeps downloaded packages and verified hashes locally so installs are reproducible and verifiable. The cache lives under /var/cache/pkm, with subdirectories for the index database (db/), downloaded packages (packages/), in-progress downloads (partial/), and rollback data (rollback/).
Verifying System Integrity
InterGenOS boots through a signed chain: a Microsoft-signed shim validates the GRUB bootloader, which verifies the kernel’s Unified Kernel Image (UKI). On an installed system the UKI — kernel, command line, and initramfs — is MOK-signed and regenerated on every kernel install, so a tampered kernel cannot boot under your enrolled key; this runs automatically, you do not start it. (dm-verity additionally seals the read-only live ISO image, its root hash carried inside the signed UKI.) To check the installed files themselves, pkm verify --all re-validates every package’s SHA-256 on demand.
You can review what is enforced and how it is verified in the security section. To inspect the effective sandbox of any running service, use:
systemd-analyze security <unit>
The system collects zero telemetry, no analytics, and no crash or usage reports, so there are no background reporting services to find and stop as part of maintenance. The maintenance surface is intentionally small: update when you choose, watch disk and journal usage, and trust that the boot chain verifies itself.
On-Device Assistance
Two local, offline-first tools can help you administer and maintain the system:
- InterGen is a tiered, hardware-detected local assistant built on Qwen models. It runs on-device with zero telemetry and selects a model tier appropriate to your hardware. When a query exceeds local capability, the optional Phone-A-Friend (Frontier/Cloud Escalation) path can hand off to a remote model, but only when you invoke it.
- InterGen Sentinel is a pluggable security scanner. Its default backends are Local-Rules and Local-Qwen, both running on your machine. Six cloud providers are available strictly opt-in: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek. Nothing leaves the machine unless you choose a cloud backend.
See the assistant documentation for configuration.
See Also
- System Administration overview
- Users, Groups & Services — service management and reading logs
- Filesystems, Kernel & Boot — storage layout and the signed boot chain
- Networking — interfaces and the localhost-only bind policy
- Forge installer guide — first boot and MOK enrollment
- Security section — the full enforced baseline
- Frequently asked questions
Troubleshooting
This section is for when something does not behave as expected, whether you are running InterGenOS on hardware or building it from source. InterGenOS is a built-from-source, security-only-aligned distribution: the goal is a machine you understand, can modify, and can trust, so the troubleshooting guidance here favors understanding the root cause over applying an opaque workaround.
InterGenOS is currently at version 1.0-dev (build id v1.0-dev1). Pages in this section will continue to grow as the system stabilizes and more commands and flows are documented.
How to use this section
Start with the methodology page if you are not sure where a problem belongs. It covers the general approach: read the actual error, identify which layer it comes from (boot, desktop, a service, a package build), and gather the facts before changing anything. From there, jump to the page that matches your symptom.
- Troubleshooting methodology — a general approach to diagnosis: read the error, locate the layer, gather facts, change one thing at a time.
- Boot and graphical issues — the system does not boot, drops to a console, or the graphical session fails to start. The shipping desktop today is GNOME 49 on Wayland.
- Service and hardware issues — a system service will not start, or a hardware device is not detected or behaves incorrectly.
- Package and build failures — problems installing or building software, including the from-source build pipeline.
Build-pipeline gates (for builders)
If you build InterGenOS from source, the build runs through 20 phases, beginning with a fast validate phase that checks reproducibility and correctness before any compilation starts. A failure here is cheap to fix: it halts before the build chroot is created, so you can correct the finding and relaunch without reverting any state.
The detailed walkthrough of those gates — audit coverage, tier validation, build-order and dependency scans, and how to resolve each correctly rather than silence it — belongs with the build-side material. The package and build failures page is the entry point for build problems in this wiki.
Before you ask for help
Two habits make a problem far easier to diagnose, for you and for anyone helping:
- Quote the exact error. Copy the real message, not a paraphrase. The precise text, including any package names, paths, or exit codes, is usually the fastest route to the cause.
- Change one thing at a time. When you apply a fix, change a single variable and re-test, so you know what actually resolved the issue.
If your question is more “how does this work” than “this is broken,” the FAQ is the better starting point. For security configuration and verified-boot questions, see the security section and the install section. Security here is not first. It is only — so when a fix would weaken the system’s integrity, treat that as a reason to find a different fix, not to accept the weaker one.
Related sections
- Start here — orientation and the FAQ.
- Installation — Forge, the installer, and recovery.
- Security — the verified-boot chain, hardening, and trust boundaries.
Troubleshooting Methodology
This page is the spine of the troubleshooting section. It gives you an ordered way to work a problem on InterGenOS, from the cheapest checks to a full recovery, and tells you when to escalate and how to ask for help so that someone can actually act on it.
The approach mirrors how InterGenOS itself is built: surface every error, never mask one, and turn an unverified assumption into a checked fact before you act on it. Security is not first. It is only. The goal of every step below is the same goal as the system: a machine you understand, can modify, and can trust.
InterGenOS is version 1.0-dev (build id v1.0-dev1). The shipped desktop is GNOME 49 on Wayland.
Where a command, package name, or flag is specific to a subsystem, this page points you to the
focused page for that subsystem rather than guessing.
The escalation ladder
Work a problem in order. Most issues resolve at the first or second rung; the later rungs exist so that a hard problem still has a defined path and you never have to improvise under pressure.
- Basic — observe, reproduce, and read the obvious signals.
- Advanced — read logs, isolate the failing component, change one variable at a time.
- Recovery — restore a known-good state when the running system can no longer be trusted.
- Support — gather evidence and escalate so someone can act on facts, not guesses.
Do not skip rungs. A “fix” applied before you have reproduced the problem is a guess, and a guess that appears to work hides the real cause until it resurfaces later.
Rung 1 — Basic
Start here for every problem. The aim is to state the problem precisely and gather the cheapest signals before touching anything.
- State the symptom exactly. What did you do, what did you expect, what happened instead? “It is broken” is not a symptom; “the login screen appears, I enter my password, and it returns to the login screen” is.
- Reproduce it. A problem you cannot reproduce is a problem you cannot confirm you have fixed. Note the exact steps. If it only happens sometimes, note how often and under what conditions (cold boot vs. warm reboot, on battery vs. plugged in, after a specific action).
- Read the obvious signals first. On-screen error text, a failed action, a missing icon. Read the message literally before interpreting it.
- Confirm scope. Does it affect one application, one user account, or the whole system? One app misbehaving and the whole desktop failing are different problems with different first steps.
- Note what changed. Did the problem start after an update, a new package, a settings change, or a hardware change? The most recent change is the first suspect.
If the problem is specific to one area, jump to the focused page once you have the symptom in hand:
The FAQ covers common first-time questions and may resolve the issue before you go further.
Rung 2 — Advanced
If the basic signals do not resolve it, move to evidence. The principle here is the same one the build process uses: read the logs end to end, do not spot-check, and change one variable at a time. An “it works now” after changing three things at once tells you nothing about which change mattered.
- Read the system and session logs. The journal carries the real story — failed units, service
errors, and the boot sequence. A success banner on screen is not a passing grade; the failures
that matter hide in the logs. Review the current boot with
journalctl -b. - Check for failed units. A service that failed to start, or one locked down so tightly it
cannot write its own state, is a common and silent cause. List failed units with
systemctl --failed, then read the status and recent log lines for each. - Isolate the failing component. Narrow from “the system” to a single service, package, device, or configuration file. Reproduce against that component alone where you can.
- Change one variable, then re-test. Revert it if it does not help. Keep a written list of what you changed so you can undo cleanly and so a fix is attributable to a single change.
- Distinguish a by-design failure from a real one. Some subprocesses are expected to fail and are handled; do not chase those. Confirm whether a failing line is genuinely the cause before acting on it.
- Verify, do not assume. Trace the behavior to its source. If you cannot support a conclusion with a log line or a reproduced result, it is a hypothesis, not a finding.
For the kinds of failures tied to building or installing packages, and for the host-side validation gates that catch most misconfigurations early, see Package & Build Failures.
InterGenOS ships local assistance that can help you read and interpret this evidence offline. InterGen is a tiered, hardware-detected, offline-first local assistant (built on Qwen models) with zero telemetry; it can help explain a log line or a failed unit without anything leaving the machine. InterGen Sentinel is a pluggable security scanner whose default backends are Local-Rules and a Local-Qwen model. See the Assistant section for how to use them.
Rung 3 — Recovery
Move to recovery when the running system can no longer be trusted to give honest answers, or cannot boot far enough to investigate: a broken boot chain, a graphical session that will not start, a configuration change that locked you out, or a corrupted component.
InterGenOS is built to make recovery a defined operation rather than an improvisation, because the system carries the trust machinery that recovery depends on:
- A signed Secure Boot chain. A Microsoft-signed shim validates GRUB, which verifies the kernel’s signed UKI; on an installed system the UKI is MOK-signed and regenerated on every kernel install, so a tampered kernel cannot boot under your enrolled key.
- Image integrity. The read-only live ISO image is sealed with dm-verity — its root hash
carried inside the signed UKI — so the installer/live environment is verified before it runs. On
the installed system,
pkm verifyconfirms every installed file against its signed SHA-256, so “are my files intact?” is a question with a checkable answer, not a guess.
Practical recovery paths:
- Boot a known-good target. If a recent change broke boot, recovering to a previously working boot entry or the installation media is the fastest way back to a usable system to investigate from.
- Reinstall cleanly when in doubt. Because the system is built from source and reproducible, and the installer (Forge) writes a verifiable system, a clean reinstall is a legitimate and honest recovery step, not a defeat. See the Forge install guide and the Recovery & Reinstall page for the supported flow, including the encrypted-disk and broken-boot-chain paths.
- Use the package manager (
pkm) to restore packages from the signed mirror. The mirror’s index is signed as a whole and verified against one signature, so a restore comes from a source whose integrity you can check yourself.
Do not “fix” a recovery by hand-editing the running system and declaring it done. A change that only holds because of a manual edit on a running box is a note about a fix, not a fix; it must be re-applied through a supported path and survive a clean boot to be trusted. If the change belongs in the system itself, see Service & Hardware Issues for where service and hardware configuration lives.
Rung 4 — Support (Phone-A-Friend)
If the problem outlasts the first three rungs, escalate. The goal of this rung is to make your problem actionable for someone else: a clear symptom, a reproduction, and the evidence you gathered.
Bring with you:
- The exact symptom and the steps to reproduce it.
- What changed most recently (update, package, setting, hardware).
- The relevant log excerpts and failed-unit output from Rung 2 — the actual lines, not a paraphrase.
- The InterGenOS version and build id (
v1.0-dev1), and whether the issue is on the live ISO, after install, or after an update. - What you have already tried, and the result of each attempt.
A vague report (“it does not work”) cannot be acted on; an evidence-backed report often resolves on the first reply.
Phone-A-Friend (Frontier/Cloud Escalation)
For problems where local analysis is not enough, InterGen Sentinel supports Phone-A-Friend (Frontier/Cloud Escalation): a set of opt-in cloud providers you can choose to route a question to. This is off by default and never sends anything until you opt in for a specific check. The supported providers are Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek. The local backends (Local-Rules and Local-Qwen) remain the default; cloud escalation is a deliberate, per-use choice that you control.
This keeps the same posture as the rest of the system: nothing leaves the machine unless you decide it should, and you can see and check what is being sent.
See also
- Boot & Graphical Issues
- Package & Build Failures
- Service & Hardware Issues
- Frequently Asked Questions
- Forge install guide
- Recovery & Reinstall
- Verified Boot & Secure Boot
Boot & Graphical Issues
This page covers the problems most users hit between pressing the power button and reaching a working desktop: Secure Boot and MOK enrollment, kernels that refuse to load, and graphics or session issues under GNOME on Wayland.
InterGenOS builds a fully signed boot chain and signs every kernel it boots, but Secure Boot enforcement is optional and off by default on the current fleet. Boot problems still often trace back to the signing chain rather than a missing driver, so this page leans heavily on the boot chain. For the full design — including what is signed versus enforced — see Verified Boot & Secure Boot.
Boot does not look like other distributions
InterGenOS ships no boot splash. There is no logo painted over the seconds between GRUB and the login screen. You see the kernel hand off to systemd, every service start with [OK] or [FAILED] markers, the network come up, and AppArmor load.
This is intended. A visible boot is a security signal: a broken mount, an odd module load, or a hardware change shows up immediately instead of hiding behind a logo. If you are used to a silent splash, the scrolling text is normal, not a fault.
MokManager appears at first boot
On the first boot after installing with Forge, the firmware notices a pending Machine Owner Key (MOK) enrollment request and runs MokManager before continuing. It is a small blue-text-on-black utility with three screens:
- “Perform MOK management” — press any key to start.
- “Enroll MOK” — review the certificate. The subject reads
CN=InterGenOS Machine Owner Key. Confirm. - “Enter password” — type the enrollment password Forge gave you on the install-complete screen (also written to the install log at
/var/log/intergen-install.log). The password is single-use.
After enrollment, the system boots into InterGenOS normally and the firmware trusts your MOK from then on.
Write the enrollment password down before you reboot. You need it once, during this step.
MokManager appears on every boot
If boot stops at MokManager each time, enrollment never completed. Walk through the three screens above to completion. The firmware re-prompts until the key is actually enrolled.
MokManager rejected the password
MokManager allows three attempts, then reboots. A transposed digit is the usual cause; try again. If the password is lost, regenerate the MOK from a live ISO (see Regenerating the MOK).
A new kernel installs but will not boot
When you install or upgrade a kernel, InterGenOS rebuilds it into a Unified Kernel Image (UKI) and signs it on your machine with your MOK. If the firmware does not trust that MOK, Secure Boot refuses the UKI and you fall through to the recovery boot entry.
The common cause is that the MOK was never enrolled (or was un-enrolled) while the kernel post-install hook went ahead and signed a UKI with it. The fix:
- Boot the recovery entry, which loads the bare
vmlinuzdirectly through signed GRUB. - Re-enroll the MOK (see MokManager appears at first boot), or regenerate it (see Regenerating the MOK).
- Re-run the kernel post-install hook for the current kernel after enrollment so a trusted UKI is produced.
You never end up with a half-installed kernel. If UKI signing fails outright, the post-install hook falls back to writing the kernel and initramfs separately, and signed GRUB loads them directly under the same enforced signature verification.
The GRUB menu shows only the recovery entry
No UKI entries means UKI signing has been failing. Inspect /var/log/intergen-kernel-postinstall.log. The two common causes are a full ESP and a missing or unreadable MOK key file.
The ESP is full
Every installed kernel becomes a signed UKI in /boot/efi. A UKI is typically 80–150 MB depending on the initramfs payload, and Forge sizes the ESP for at least three kernels. If the partition fills, kernel install fails with a clear message. Free space by removing an old kernel:
pkm remove linux-kernel-<old-version>
UKI tooling is missing
If the installed system lacks the UKI builder (an older install, or one with a different boot path), reinstall it and re-run the post-install hook for the current kernel:
pkm install ukify sbsigntool
Regenerating the MOK
The MOK lives under /var/lib/intergen/mok/. On a default install Secure Boot is off, so there is no enrollment password to lose. If you run with Secure Boot enabled and need a fresh MOK, reinstalling with Forge regenerates one; the next kernel install or upgrade rebuilds the UKIs with it, and the GRUB-loads-vmlinuz recovery entry keeps the system bootable in the meantime. (There is no separate recovery wrapper command — UKI signing is handled by the kernel package’s post-install hook.)
The release signing key never touches your machine and is never asked to sign anything you produce locally. Your MOK lives only on your machine, at /var/lib/intergen/mok/.
Firmware will not let me change Secure Boot
Some firmware, especially on OEM laptops, makes the Secure Boot toggle read-only outside Setup Mode. InterGenOS does not require Setup Mode for normal operation; the standard MOK enrollment path is sufficient. If you do need to change firmware settings, consult your hardware vendor’s documentation for entering Setup Mode.
Graphical and session issues
InterGenOS ships GNOME 49 on Wayland. Hardware acceleration runs through the Mesa stack for AMD (Radeon) and Intel (Arc, Iris, UHD) GPUs, all installed and enabled by default. Wayland is the default display protocol; X11-only applications run through Xwayland automatically.
The shell becomes unresponsive
You can restart GNOME Shell without logging out: press Alt + F2, type r, and press Enter. Open applications keep running across the restart.
A monitor or external display misbehaves
GNOME 49 handles mixed-DPI and mixed-refresh-rate setups without configuration, and a hot-plugged monitor should work immediately. If a display is not detected as expected, check it in Settings → Displays, then move a window to it with Super + Shift + Arrow.
NVIDIA graphics
The base distribution does not ship proprietary firmware, and the NVIDIA driver is offered only when an NVIDIA GPU is present. It is an explicit opt-in:
pkm install nvidia
Accept the NVIDIA license when prompted, then follow the post-install instructions for enrolling the NVIDIA kernel module with your MOK. On a Secure Boot system, an out-of-tree module that is not signed and enrolled will not load, so this enrollment step is required for the driver to work.
An application cannot capture another window’s pixels or input
This is Wayland’s per-window isolation working as designed: each application sees only its own input and pixel buffer. Tools that expect the old X11 global-capture behavior may need a Wayland-native portal-based path instead.
Related pages
- Verified Boot & Secure Boot — the full boot-chain security model: what is verified, who signs what, and every recovery path.
- Graphical session — GNOME 49 on Wayland, keyboard shortcuts, hardware acceleration, and what ships by default.
- FAQ — quick answers to common questions.
Service & Hardware Issues
This page covers problems that surface at the boundary between InterGenOS and your hardware: Secure Boot and kernel module signing, device drivers and firmware, and system services that fail to start or refuse to listen on the network. Many of the symptoms below are the system enforcing a control you can verify and, where appropriate, adjust. InterGenOS is built on a single doctrine: security is not first. It is only. When a security control conflicts with convenience, security wins.
For software-install and package problems, see Frequently Asked Questions. For a complete picture of what is enforced out of the box, read the Hardening Baseline overview.
Secure Boot and Kernel Modules
InterGenOS builds a signed boot chain: a Microsoft-signed shim validates the InterGenOS GRUB bootloader, which in turn verifies the Linux kernel and Unified Kernel Images (UKIs). Secure Boot enforcement is optional and off by default on the current fleet, so these signatures are present and verifiable but not firmware-enforced unless you enable it; with it enabled, unsigned kernel modules are not trusted.
A driver or out-of-tree kernel module will not load
Out-of-tree modules, including proprietary drivers, must be signed by a key the firmware trusts. InterGenOS uses a Machine Owner Key (MOK) for this. The Forge installer walks you through enrolling a MOK on your first boot. If you skipped MOK enrollment, an out-of-tree module is refused even though it is present on disk.
What to check:
- Confirm Secure Boot is active and that your MOK was enrolled during first boot. If it was not, re-run the enrollment step described in Verified Boot & Secure Boot.
- After a kernel install or upgrade, installed systems regenerate and sign each kernel’s UKI with your machine’s local MOK. The same boot-time signature verification applies to kernels you install after the original ISO image, so a freshly installed kernel that will not boot points to a MOK signing or enrollment problem rather than a corrupt kernel.
The InterGenOS release-signing key never leaves a hardware token under InterGenOS control. Only the MOK that Forge generates on your own machine signs the kernels you install. This is intentional: the keys that authorize your machine to boot belong to your machine.
The system will not boot after a kernel or bootloader change
Because the boot chain verifies each stage, a tampered or unsigned component halts the boot rather than running it. If a kernel installed or upgraded outside the normal package flow fails to boot, the most common cause is a missing or mismatched UKI signature. Re-installing the kernel through the package manager (pkm), so the UKI is regenerated and signed with your MOK, restores a valid signature.
Drivers and Firmware
The core operating system relies exclusively on open-source drivers and firmware. Proprietary blobs are available if your hardware strictly requires them, but they are never forced on you.
A device needs proprietary firmware
If a network card, GPU, or other device does not work with the open drivers that ship by default, your hardware may strictly require a proprietary firmware blob. These are available but are not installed automatically. Install the firmware your device needs, and if it ships as an out-of-tree kernel module, ensure your MOK is enrolled so the signed module can load (see the Secure Boot section above).
System Services
InterGenOS hardens system services aggressively to minimize the blast radius of a compromise. The same isolation that protects you can make a service look broken when it is in fact being confined exactly as configured.
A service starts but cannot reach a file, device, or directory
System daemons run under extensive systemd sandboxing. Baseline directives applied across system services include ProtectSystem=strict, ProtectHome=true, PrivateTmp=true, PrivateDevices=true, ProtectKernelTunables=true, ProtectKernelModules=true, NoNewPrivileges=true, and a restrictive SystemCallFilter. AppArmor profiles for system daemons ship in enforce mode by default, with a few profiles (currently intergen-mcp and pkm) intentionally shipped in complain mode and graduating to enforce as they mature.
If a service cannot read or write a path, open a device, or perform a syscall, the cause is usually one of these controls working as intended:
ProtectHome=truehides/home, so a daemon configured to read a file under a user’s home directory will not see it.ProtectSystem=strictmakes most of the filesystem read-only to the service.PrivateDevices=trueremoves most device nodes from the service’s view.- AppArmor in enforce mode denies access outside the profile’s allowed paths.
What to check:
- Inspect the service’s journal for the specific denial. AppArmor denials and systemd sandbox refusals are logged with the path or capability that was blocked.
- Confirm whether the resource the service wants is one the security baseline deliberately withholds. If so, the correct fix is to adjust the service’s configuration or its profile, not to disable the protection wholesale.
This is a trade InterGenOS makes deliberately. When a security control conflicts with convenience, security wins.
A server is running but I cannot connect to it from another machine
Any server package shipped by InterGenOS binds exclusively to localhost (127.0.0.1) by default. Services never listen on a public interface unless you deliberately edit their configuration to allow it. A service that responds on the same machine but refuses connections from the network is behaving correctly.
To expose a service on the network, edit its configuration to bind to the appropriate interface, and understand that you are widening its exposure on purpose. Pair any such change with firewall rules you control.
A database or service reports no usable credentials
InterGenOS does not ship databases or services with blank or default admin passwords. Initial credentials are randomly generated or require manual setup during installation. If a service rejects a login you never explicitly set, you have likely hit this default. Set or retrieve the credential through the service’s documented setup path rather than assuming a well-known default exists.
A JIT workload fails with a memory-protection error
MemoryDenyWriteExecute=true is applied across system daemons. Workloads that require writable-then-executable memory, such as just-in-time compilation, are the exception. PostgreSQL is one such case: its LLVM JIT compiler emits machine code into writable-then-executable pages, so its shipped unit sets MemoryDenyWriteExecute=false to keep the JIT working. If a service that legitimately needs JIT fails with a memory-protection error, this directive is the cause, and the fix is a targeted exception for that service rather than removing the protection from every daemon.
Telemetry and Updates Are Not the Cause
When tracing unexpected behavior, two things you can rule out by design:
- InterGenOS collects zero analytics, crash reports, or usage statistics. No background process is phoning home.
- Software does not update behind your back. Updates happen only when you explicitly run
pkm sync. A service whose behavior changed did not change on its own.
When the Control Is the Problem
Every default described here is verifiable and adjustable. The intent is a machine you understand, can modify, and can trust. If a hardened default genuinely blocks a workflow you need:
- Confirm the control is the cause by reading the journal and AppArmor denials.
- Make the narrowest possible change to the affected service or profile.
- Avoid disabling a protection system-wide to fix one service.
Further Reading
- Hardening Baseline — the full list of what is enforced by default.
- Verified Boot & Secure Boot — MOK enrollment and the boot chain.
- Frequently Asked Questions — software-install and general questions.
Package & Build Failures
This page covers two distinct failure surfaces in InterGenOS:
- Package-manager failures — problems while installing, removing, upgrading, or verifying packages on a live system with
pkm. - From-source build failures — problems while constructing packages and the ISO with the build orchestrator, most commonly the
validate-phase gates that run before any compilation.
Read the symptom carefully to decide which surface you are on. A pkm failure touches the live root filesystem and its package database; a build failure happens in an isolated build environment and never modifies your installed system.
InterGenOS is built from source and ships a machine you understand, can modify, and can trust. The package and build tooling are designed so that every state change is auditable. When something fails, the goal is to find the root cause, not to paper over it.
Part 1 — Package-manager (pkm) failures
pkm manages the installed operating system: installation, removal, querying, and integrity verification of pre-compiled binary archives (.igos.tar.gz). It operates on the live filesystem and keeps two coordinated records of state:
- A SQLite database at
/var/lib/igos/pkm.db— the primary source of truth for fast queries and transactions. - Text manifests under
/var/lib/igos/packages/— human-readable files generated alongside the database records for inspection.
This duality gives you performance without sacrificing auditability. If the two ever appear to disagree, treat the database as authoritative and report the divergence.
Integrity verification fails (pkm verify)
pkm verify recalculates the SHA-256 hash of every installed file on disk and compares it against the expected hash stored in the database’s files table. A mismatch means the file on disk differs from what was deployed — either accidental corruption or unauthorized modification.
What to do when verify reports a mismatch:
- Identify the file and its owning package. The database indexes files by
path, so a single mismatched file points you directly at the package that owns it. - Decide whether the change was intentional. Files under
/etc/are tracked as configuration and are expected to drift as you edit them. A mismatch on a binary or library is more serious. - Do not dismiss a mismatch. A changed binary on a security-only-aligned system is a finding to investigate, not to acknowledge and move on.
Archive trust / verification rejected at install time
Before installation, the CLI supports an --archive-trust flag, which accepts three values: strict (the default), loose, and repo-only. In strict or repo-only modes, the incoming .igos.tar.gz archive’s SHA-256 hash is computed and checked against the trusted available index that was synced from the repository with pkm sync.
If installation is rejected on trust grounds:
- The archive hash does not match the index entry. Re-run
pkm syncto refresh theavailablecache, then retry — your index may be stale relative to the published archive. - If the hash still does not match after a fresh
sync, stop. A persistent mismatch between a downloaded archive and a freshly-synced trusted index is exactly what archive verification exists to catch.
A directory-collision or invariant check aborts installation
Before deploying files, pkm runs invariant checks. The two it is documented to enforce:
- Directory collisions — it refuses to let a package replace a critical path (for example, turning the
/libsymlink into a directory). - Supersede ordering — if a package declares
SUPERSEDES, the predecessor it supersedes must exist and be correctly ordered in the install queue.
If install aborts here, the package’s manifest is asking for a filesystem change that would damage the system layout, or an upgrade ordering that cannot be satisfied with the packages on hand. Install the predecessor first, or fix the queue order, rather than forcing past the check.
The filesystem deploy step is the point of no return: once files are written to the root filesystem, the package is committed to disk before the database transaction that records it. The invariant checks run before that write precisely so a bad manifest never reaches it.
Understanding upgrades: the “supersede” model
pkm does not do in-place version replacement; it uses a supersede model. When package B supersedes package A:
- Files present in both
AandBare overwritten on disk byB, and their database ownership transfers fromAtoBwith updated SHA-256 hashes. - Files that existed in
Abut are not inBare left in place, still owned byA’s historical record. A’s record is timestampedsuperseded_by, pointing atB.
This is how a package can split cleanly (for example, util-linux into util-linux-core and util-linux-extra) without orphaning files or breaking dependencies. If after an upgrade you find files you expected to be gone, this model — not a bug — is usually why: those files belonged only to the superseded record.
Removal leaves files behind, or warns about a modified file
Removal is deliberately cautious:
- Configuration files under
/etc/are skipped to preserve your data, unless you pass--force. - If a file’s on-disk hash differs from the database hash (it was modified after install),
pkmemits a warning but still removes it. - Directories are removed only when they become completely empty.
So “leftover” files after a removal are usually preserved configuration or a non-empty shared directory, both by design. The modified-file warning is informational; it is telling you the file you removed was not the one originally deployed.
Config files: .new after an upgrade
pkm tracks the original hash of each /etc/ file in a config_files table. When an upgrade ships a new version of a config file you have modified, pkm will attempt a safe merge or leave the new version as a .new file beside your edited one. Review and reconcile .new files; they are how upgrades avoid silently overwriting your changes.
Part 2 — From-source build failures
The build orchestrator constructs InterGenOS from source in an isolated environment, then assembles a signed, verity-protected ISO. As of this writing the build runs 20 phases:
validate → verify-sources → setup → toolchain → chroot-prep → chroot-tools → core → config → core-extra → base → kernel → desktop → ai → extra → bootloader → image → manifest → squashfs → ukis-verity → iso, with an optional publish step.
Packages are organized into six tiers — toolchain, core, base, desktop, ai, and extra — totalling roughly 850 packages across the tree as of 2026-06-15. These counts drift as the tree evolves; derive the live count from the package tree rather than trusting a fixed number.
The overwhelming majority of “my build failed before it really started” reports are validate-phase gate failures, covered next. A genuine compilation failure happens later, inside the build environment, and looks different: a compiler error, a failing test, or a missing build dependency surfaced during a tier build.
Telling a validate-phase gate from a real build bug
The validate phase is the first phase and runs in roughly one second. It runs entirely on the host side: it reads package.yml files, the audit database, and source tarballs. It does not create or touch the isolated build root, which is set up in a later phase.
This has a practical consequence that saves a lot of time:
- A validate failure halts the orchestrator with exit 1 before any toolchain work.
- The build root and build scratch space are left untouched (on a clean baseline they do not exist yet).
- You can fix the finding and relaunch without reverting your build environment — there is no contamination to undo.
A fail in roughly 0.1–1 second is almost always a validate-phase gate, not a build bug.
The validate-phase gates, in order
| # | Gate | What it enforces | Halts build? |
|---|---|---|---|
| 1 | Tier reachability | every tier can be reached and built | yes |
| 2 | Audit-coverage (reproducibility) | every in-scope package has a current audit record | yes |
| 3 | Tier validation | each package sits in its correct tier | yes |
| 4 | Scan A — build-order | dependencies build before their consumers | yes |
| 5 | Scan B — silent feature loss | no silent capability regressions (skipped on a first build — no prior reference to compare) | yes |
| 6 | Scan A.2 — undeclared build deps | no build dependency is used but undeclared | yes |
A separate aggregate reconciliation report is also produced. It is advisory rather than a build gate, but its mismatch rows are real signals that should be triaged, not ignored.
The two gates that fire most often when you add or change a package are audit-coverage (Gate 2) and tier validation (Gate 3).
Gate 2 — Audit-coverage: “N packages need audit work”
A typical failure:
[audit-preflight] missing audit: 3
[audit-preflight] stale (version): 1
[audit-preflight] FAIL: 4 packages need audit work.
Every in-scope package must carry a current audit record. The gate distinguishes three failure classes:
- missing — no audit record at all. Cause: a newly-added package.
- stale — the audit record’s version does not match the
package.ymlversion. Cause: a version bump. - drift — the audit’s recorded build dependencies do not match the
package.ymlbuild dependencies. Cause: dependencies edited without re-auditing.
Understand the data flow or you will re-aggregate to no effect. The per-package auditor reads the package.yml and the source tarball and writes a per-package audit record into the private audit store. An aggregation step then ingests all those records into the build database that the gate actually reads. The gate reads the database, so you must re-aggregate after auditing; auditing alone does not update what the gate sees.
To resolve, for each flagged package: refresh its audit record, re-aggregate into the database, then re-run the audit-coverage check until it reports PASS. Commit the refreshed audit records to the private audit store.
Gate 3 — Tier validation: “MOVE→<tier>” or “UNCLEAR”
This gate computes each package’s canonical “natural tier” and compares it to the tier the package declares. Verdicts:
- MOVE→X — the natural tier differs from the declared tier.
- UNCLEAR — no natural tier could be determined.
- CROSS-TIER-DEP — a build/host dependency resolves to a later tier. This is a genuine ordering violation; fix the dependency, never demote the consumer.
The natural tier is derived in layers: explicit curated category lists and naming patterns first, then consumer inference from the build/host reverse-dependency graph (a package takes the earliest tier that consumes it). A subtle trap: the inference graph is built from build and host dependencies only. A package consumed only as a runtime dependency has no graph consumer, so inference cannot place it and it comes back UNCLEAR.
Do not blindly obey the verdict. Evaluate it against the tier source-of-truth document first. There are two correct outcomes:
- The package really is in the wrong tier — move it: relocate its directory to the correct tier, update the
tier:field inpackage.yml, fix builder wiring as needed, then re-audit and re-aggregate (the audit record carries the tier). - The package is in the correct tier but the heuristic misfires — encode the source-of-truth: add an explicit entry for the package to the validator’s appropriate category list. This is legitimate only when the tier document already classifies the package that way; you are encoding the documented truth, not gaming the gate. If the document is genuinely ambiguous, that is an operator judgment call, not a self-serve edit.
Reconciliation mismatches (advisory): a required dependency not in our build deps
The reconciliation report can flag that an upstream-required dependency is missing from a package’s declared build dependencies. This is advisory, but every mismatch is a real signal to triage:
- Real gap — the dependency is genuinely needed and was forgotten. Add it, re-audit, re-aggregate.
- Intentional divergence — InterGenOS builds the package differently from upstream, so the upstream dependency does not apply. Record the divergence at the comparison site with an inline justification. A permanent deviation from upstream requires operator authorization: propose it with evidence rather than self-authorizing.
There is also a per-package override mechanism that can skip a package’s audit checks temporarily, carrying a reason, an approver, and an expiry date. Reserve it for a genuinely temporary, whole-package gap. For a permanent single-dependency divergence, prefer the precise, self-documenting divergence record over a broad whole-package override.
After a fix: relaunch without reverting
Because the validate phase exits before the build root is created, the recovery loop for a validate gate is cheap:
- Read the failing gate’s output and identify the packages and the failure class.
- Apply the correct fix (refresh audits, move a tier, encode the source-of-truth, or triage a mismatch).
- Re-run the checks locally until every gate is green.
- Commit the changes (public tree for tier/validator edits, private store for audit records), then relaunch the build.
No revert of the build environment is needed for a validate-phase fix.
A note on packages changed after a successful build
When a from-scratch build has already succeeded and been captured as a reference, any package added or changed after that point is where unrecorded-but-intentional decisions hide. Before resolving a gate on such a package, review its history since the last good build so you preserve, rather than silently undo, a deliberate choice. A correct-but-unrecorded divergence can sit un-triaged for days precisely because the build was passing.
Where state lives
| Concern | Location |
|---|---|
| Installed-package database | /var/lib/igos/pkm.db |
| Human-readable package manifests | /var/lib/igos/packages/ |
| Per-file ownership and hashes | the files table in pkm.db |
| Configuration-file tracking | the config_files table in pkm.db |
| Operation and transaction log | the append-only history table in pkm.db |
The history table is an append-only log of every install, removal, and supersede. When you need to reconstruct what changed and when, it is the audit trail.
Related pages
Release Notes
InterGenOS is built from source, on purpose, so that you run a machine you understand, can modify, and can trust. These release notes record what each version actually ships, so you can verify the system in front of you against a written record.
How release notes are structured
Each released version gets one section, organized the same way every time:
- Highlights — the headline changes that define the release.
- New components — packages, tools, and subsystems added since the previous version.
- Breaking changes — anything that changes existing behavior, on-disk layout, signing trust, or upgrade path. Read this section before you upgrade.
- Other — fixes, documentation, security hardening, and smaller changes that don’t fit the categories above.
InterGenOS follows Semantic Versioning once v1.0 ships.
Until then, development tracks as an unreleased line against the master
branch, and the items staged there ship together at the v1.0 tag.
Current version: 1.0-dev
The current development build identifies as v1.0-dev1. It is pre-release: the
structure below describes what the build produces today. Final per-tier package
counts, the canonical signing-key fingerprint, and the live mirror URL are
fixed at the v1.0 tag, not before.
What the build produces
InterGenOS is assembled by a 20-phase from-source pipeline. The phases run in order:
validate → verify-sources → setup → toolchain → chroot-prep →
chroot-tools → core → config → core-extra → base → kernel →
desktop → ai → extra → bootloader → image → manifest → squashfs →
ukis-verity → iso
A publish step to the binary mirror is optional and runs only on a complete,
signed build.
Packages
Packages are organized into six tiers: toolchain, core, base, desktop,
extra, and ai. As of June 2026 the development line carries roughly 857
packages across those tiers (toolchain ~28, core ~272, base ~23, desktop ~420,
extra ~112, ai ~2). These counts are derived live from the package set and
drift as the build evolves; treat them as a snapshot, not a fixed figure. The
final per-tier numbers are recorded here at the v1.0 release.
What ships today
- Desktop: GNOME 49 on Wayland.
- Package manager:
pkm, the InterGenOS package manager. - Installer: Forge, the native InterGenOS installer. See the Forge guide.
- Trusted boot: a signed Secure Boot chain, dm-verity integrity over the read-only system image, and Unified Kernel Image (UKI) signing.
- InterGen: a tiered, hardware-detected, offline-first local assistant built on Qwen models. It runs on the machine, with zero telemetry, and selects a model tier based on detected hardware.
- InterGen Sentinel: a pluggable security scanner. The default configuration uses Local-Rules and a Local-Qwen model, fully on-device. Six cloud providers are available strictly opt-in: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek. Routing a scan to a cloud provider is the “Phone-A-Friend” (Frontier/Cloud Escalation) path, and it never engages unless you choose it.
Planned, not yet shipped
The following are on the roadmap and are not part of the current build. They will appear in release notes only once they ship:
- A KDE/Plasma (Qt6) desktop option and switchable desktops.
- Curated application campaigns covering tools such as Kdenlive, OBS, Krita, Blender, FreeCAD, GnuCash, and Boxes.
Work remaining before the v1.0 tag
Tracked items still open ahead of the first tagged release:
- Forge Secure Boot validation on the first bare-metal hardware target.
- Microsoft
shim-reviewsubmission. pkmpackaged as a system tool installable on a fresh target.- Source mirror completion, including the tarball upload path and an upstream version poller.
- Live ISO infrastructure: custom initramfs, squashfs builder, and boot menu.
- The Forge GUI frontend (GTK4 + libadwaita).
- InterGen Tier 1 integration (
intergen-consoleandintergen-daemon). - InterGen Sentinel scanning with the Local-Rules and Local-Qwen defaults.
Security and supply chain
The development line removed PyPI from the build path for the maturin and
python-cryptography packages in response to a 2026 PyPI supply-chain attack
window. Both now build from upstream source tarballs through a reproducible
cargo-vendor pipeline. Vendored Rust crate archives were standardized on the
POSIX pax format to eliminate a class of path-length failures.
When v1.0 ships
The 1.0.0 entry is finalized when v1.0 ships. It will record the complete from-source build chain, the first signed publish to the binary mirror, the signed Secure Boot chain (shim, boot loader, UKI, dm-verity), the local AI assistant (InterGen and InterGen Sentinel), the GNOME 49 Wayland desktop, and the Forge installer flow that the image ships.
Earlier history
Pre-2026 builds from 2015–2016 are archived under the InterGenOS GitHub organization. They are not covered by these release notes. The 2026 work is a from-scratch rewrite and shares no code with the original builds.
See also
Security Advisories
Security advisories are a first-class deliverable in InterGenOS, not an afterthought. When a vulnerability affects the kernel or packages we ship, we document it in full: what it is, whether InterGenOS was exposed, exactly how it is mitigated, and how you can verify the mitigation on your own machine. This reflects the project’s posture directly.
This page summarizes the published advisories and the format they follow. The canonical advisory documents live in the source tree under docs/security/advisories/.
How to read an advisory
Advisories come in two shapes, and both share the same goal: give you enough detail to understand, audit, and if you choose, change the mitigation yourself. A machine you understand, can modify, and can trust is the whole point.
A typical advisory contains:
- Identification. A CVE number and/or an InterGenOS advisory ID (for example
IGOS-SA-2026-002), the disclosure date, and a CVSS score with its vector string where one is published. - Summary. A plain-language description of the vulnerability and its root cause.
- InterGenOS status. Whether builds were exposed, and the explicit verdict (for example
NOT AFFECTED, orfully vulnerablepre-fix). Advisories state honestly when a built kernel image was vulnerable as compiled, even if no public installation was ever affected. - Mitigation. The concrete fixes applied, named down to the patch file and the script that installs them. InterGenOS favors layered defense: an upstream or backported kernel patch as the primary fix, plus a defense-in-depth measure such as a module blacklist.
- User impact and opt-out. What changes for you, what does not, and how to reverse a default if your workflow needs it. Mitigations that change defaults are always plainly visible and user-editable.
- Verification. Copy-pasteable commands so you can confirm the mitigation is present on your own system rather than taking our word for it.
- Timeline, composition, and sources. Disclosure-to-fix dates, how the advisory relates to other security work, and links to upstream commits and third-party write-ups.
A core principle runs through every advisory: defaults that change behavior for security reasons remain transparent and reversible. If a mitigation blacklists a kernel module, the configuration file is visible on disk, documented, and removable by an administrator who genuinely needs the affected functionality.
Published advisories
CVE-2026-31431 — Copy Fail (algif_aead local privilege escalation)
A logic flaw in the Linux kernel algif_aead subsystem allowed an unprivileged local user to escalate to root. The flaw was introduced upstream in 2017 and affected mainstream Linux distributions shipped since then.
InterGenOS status: NOT AFFECTED. Mitigated on the day of public disclosure (2026-04-29) with two independent layers:
- Kernel patch. The upstream fix is applied as a patch in
packages/core/linux-kernel/patches/, reverting the vulnerable in-place optimization across theaf_algandalgif_*crypto sources. - Module blacklist (defense-in-depth). The
algif_aeadmodule is additionally blacklisted via/etc/modprobe.d/disable-algif.conf, guarding against an unpatched fallback boot, a future regression in the same subsystem, or unintended module loading.
User impact is zero. dm-crypt/LUKS, kTLS, IPsec, OpenSSL/GnuTLS/NSS, SSH, and kernel keyring crypto all use the in-kernel crypto API directly and do not route through AF_ALG. The only affected workloads are userspace applications explicitly configured to use AF_ALG AEAD sockets, which is rare outside embedded crypto-offload scenarios.
To verify the mitigation on your own install, the advisory provides commands to inspect the blacklist file, confirm the module is not loaded, and check the running kernel version. See the full advisory at docs/security/advisories/CVE-2026-31431-copy-fail.md.
IGOS-SA-2026-002 — Dirty Frag + Fragnesia (kernel socket-buffer cluster)
A cluster of three upstream Linux kernel CVEs disclosed in May 2026 (CVE-2026-43284, CVE-2026-43500, and CVE-2026-46300), all local privilege escalation to root. They share a root cause: socket-buffer code paths that fail to set or propagate the marker indicating that paged fragments are externally owned, which can lead to in-place decryption writing into page-cache pages an unprivileged process can observe.
InterGenOS status: the kernel shipped with this release line was vulnerable as built before the mitigation commit. Because no public ISO had been shipped during the exposure window, no public installations were affected. The advisory documents the cluster and the fix in full regardless.
Mitigation again uses two layers:
- In-tree kernel patches. Three patches in
packages/core/linux-kernel/patches/address the cluster. Two apply the upstream mainline commits cleanly; the third (CVE-2026-43500, rxrpc) is an InterGenOS-authored backport, because the upstream patch targets a refactored file layout that does not exist in this release’s pinned kernel. The structurally equivalent fix is applied at the corresponding site in the pinned source, and the patch file header documents the provenance and full reasoning. The release line keeps its pinned kernel version and backports fixes rather than bumping the kernel. - Defense-in-depth module blacklist. A configuration file under
/etc/modprobe.d/refuses to load theesp4,esp6, andrxrpcmodules. This is the explicit lesson of the cluster: a later CVE in the same fragile area proved that patches alone may not cover every related path, so the blacklist holds the line if a similar bug drops before a fresh kernel ships.
User impact is minimal for typical desktop use. Modern consumer VPNs such as WireGuard and OpenVPN do not use the esp4/esp6 modules, and rxrpc is OpenAFS-only. The blacklist file is plainly visible and editable: users who depend on traditional IPsec ESP or OpenAFS can remove the file (or unblock a single module) and reload the module dependency cache, as documented in the advisory’s opt-out section. The kernel patches remain in effect even with the blacklist removed; opting out loses only the defense-in-depth layer.
These mitigations take effect on a kernel rebuild, since the kernel image and the signed boot image both change. See the full advisory at docs/security/advisories/dirty-frag-fragnesia.md.
Where mitigations land in the build
Kernel-level fixes are delivered as patches under packages/core/linux-kernel/patches/ and applied automatically during the kernel build phase; the build applies every patch in the directory in alphabetical order at configure time. Defense-in-depth configuration files (such as module blacklists) are installed during the system’s chroot configuration step. Because a kernel-image change also changes the signed Unified Kernel Image, kernel-level advisories require a kernel rebuild and a new UKI to take full effect. For background on the signed boot chain and integrity model, see Verified Boot & Secure Boot and the Kernel Hardening page.
Reporting a vulnerability
Security reports for InterGenOS go to security@intergenstudios.com.
Related reading
Contributing to InterGenOS
InterGenOS is a Linux distribution built entirely from source, currently at version 1.0-dev (build id v1.0-dev1). It ships a custom package manager (pkm), the Forge installer, a signed boot chain with dm-verity sealing the live image and UKI signing (Secure Boot enforcement optional, off by default on the current fleet), and a tiered, offline-first local AI assistant (InterGen). Today the desktop is GNOME 49 on Wayland. Contributions of all kinds are welcome.
The guiding principle
Every contribution must serve the project’s core purpose:
InterGenOS exists to put the user in control of their own machine. Every design decision, every default, every included component must serve this purpose: giving people a system they understand, can modify, and can trust.
If a change adds complexity that does not serve the user, it is not welcome, regardless of how conventional it may be. The result we are after is a machine you understand, can modify, and can trust.
The three lenses
Before any development decision is made — a recipe edit, a fix, a build flag, a package choice, a process step — it is run through three lenses, in order. They are the working filter for every choice. An option that fails any one of them is wrong, no matter how convenient, conventional, fast, or precedented it is.
- Security is not first. It is only. We build assuming adversaries have superhuman vulnerability-discovery capability. The question is always whether a change eliminates silent failure and turns an unverified assumption into a checked gate. A masked error, a blanket “ignore failures,” an unverified “known-good” claim, or a degraded-but-shipped feature is exactly what such an adversary exploits. If an option masks rather than verifies, it is wrong.
- The user controls a machine they understand, can modify, and can trust. We reject bespoke complexity that hides how the system works, and prefer the standard, transparent, built-from-source path even when a shortcut would be more convenient. A machine the user cannot trust is a machine they do not control.
- Logic and project intent. Does the choice satisfy everything it is evaluated against — secure, from-source, reproducible — and the actual goal behind the work? A locally clever answer that defeats the project’s stated intent is wrong.
These lenses usually converge on a single answer. When they do, that is the answer.
How to contribute
Reporting issues
- Use GitHub Issues for bug reports and feature requests.
- For build failures, include the package name, version, and build log output.
- Check existing issues before opening a new one.
- For security vulnerabilities, follow the project’s
SECURITY.mdpolicy rather than filing a public issue.
Code contributions
InterGenOS is currently maintained by a single developer. To contribute code:
- Open an issue first to discuss the change.
- Fork the repository and create a branch.
- Follow the existing code style — no surprises.
- Test your changes; the build must remain reproducible.
- Submit a pull request with a clear description.
Package templates
The most impactful contributions are package templates. Each package lives under packages/<tier>/<name>/ and needs two files:
package.yml— metadata: source URL, SHA256, dependencies, and build style.build.sh— bash functionsconfigure(),build(),check(), anddo_install().
Follow the BLFS 13.0 book for build instructions, and use DESTDIR="" for all installs.
Packages are organized into six tiers — toolchain, core, base, desktop, ai, and extra. As of June 2026 the tree carries roughly 857 packages across those tiers (about 28 toolchain, 272 core, 23 base, 420 desktop, 2 ai, and 112 extra). These counts drift as the tree evolves, so derive the live numbers from the source tree rather than treating any figure as fixed.
What we value
- Research before implementing. Check the LFS/BLFS book and study how other distributions handle it. A short investigation beats hours of trial and error.
- Simplicity over cleverness. If there is a simpler way, use it.
- Transparency. No hidden behavior, no magic.
- Tested changes. If you cannot verify it works, do not submit it.
Security standards
InterGenOS is built for hostile-network resilience. The project assumes adversaries have superhuman vulnerability-discovery capability and treats every package, configuration, and code change as potentially within their reach. All contributions are reviewed against current best-practice vulnerability-discovery tooling before merging.
Contributions that introduce any of the following will not be accepted:
- Known vulnerabilities — code patterns flagged by static analysis, dependency chains with published CVEs, or configurations that weaken the system’s security posture.
- Supply chain risks — unverified source tarballs, missing or incorrect SHA256 checksums, dependencies fetched from untrusted origins.
- Privilege escalation vectors — improper setuid usage, world-writable files in privileged paths, or unsafe default permissions.
- Feature regressions disguised as fixes — disabling functionality or removing dependencies to work around build failures rather than resolving the root cause.
If review surfaces an issue in your contribution, the maintainer will work with you to resolve it before merging. Security is not negotiable.
Public content audit
All pull requests to master are scanned by an automated public-content audit (.github/workflows/public-content-audit.yml). This check ensures that internal development artifacts — host-specific paths, internal file references, and credential-like strings — do not enter the public repository. If the audit fails on your PR, amend the flagged files and push again. Legitimate public content that happens to match a flagged pattern can be added to scripts/check-public-content.allowlist.
The doctrine: only a clean build counts
A build whose packages all compiled is not a build that is known-good. The expensive failures of a from-source distribution are not compile errors. They are the class of defect that compiles fine, packages fine, and only manifests when the artifact is installed and booted on real hardware: a service unit locked down with no writable path, a directory omitted from a package’s file list, a hardware-detection heuristic wrong for an integrated GPU, a first-boot race. None of these is caught by “all packages built, 0 failures.” Every one is caught by installing the artifact and booting it on real hardware.
Two laws follow:
- Validate on a clean build and install, on hardware that reproduces the bug — never on a hand-patched development box. Nothing is done until the fix lives in the source tree and a clean build reproduces the corrected behavior with zero manual intervention (the signing step is the one sanctioned human action). A fix that only works because of a manual edit on the running target is a note about a fix, not a fix.
- Fixing now is the default for trust-bearing, build-orchestration, and small gaps. An unfixed gap compounds. When immediate repair is genuinely not the right call, that exception is recorded with an explicit expiry condition and a way to measure it, never as a bare line on a list.
Race-class fixes carry two extra requirements: validate on the hardware that actually reproduces the race (the slower, lower-end tier is the honest test), and require several consecutive clean cold boots. A single clean boot does not clear a race, and a warm reboot is not a substitute for a cold power-cycle.
The build lifecycle
InterGenOS is produced as an ordered, reproducible lifecycle. A full from-scratch build runs 20 phases in a fixed order inside an isolated, reproducible build environment:
validate → verify-sources → setup → toolchain → chroot-prep → chroot-tools → core → config → core-extra → base → kernel → desktop → ai → extra → bootloader → image → manifest → squashfs → ukis-verity → iso
An optional publish step pushes the result to the signed package mirror. The stages group into these decision gates:
- Build from source — the proving ground. Every source is pinned and checksum-verified before use; the build is deterministic by construction (full byte-identical reproducibility across independent builders is a 1.x goal). Minting a candidate is deliberately expensive so that what comes out of it has earned trust.
- Handle build issues without cheating. A failure is fixed in the source tree, never worked around. No moving a package to a different tier to dodge a wiring problem, no disabling a feature to bypass a missing dependency, no silently skipping a failed step, no stub functions (“a stub is a lie”). Disabling a package’s test suite is a last resort, not a first response. After a few failed tactical attempts on one problem, the process stops and switches to research-first investigation rather than thrashing.
- Sign the boot chain. The build halts for a hardware-token signing step. One signing covers the bootloader and all of the unified kernel images. Each kernel image’s command line carries the verified-integrity root hash of the read-only system image, so a tampered system image cannot boot under a validly signed kernel. Signing only appends a signature; it never alters the payload.
- Assemble the ISO. The read-only system image is compressed, a dm-verity hash tree is generated over it, and the bootable ISO stages the signed bootloader and kernel images alongside it. Integrity verification (root hash sealed in the signed kernel command line) is the primary path, with a whole-file checksum fallback; both are asserted non-empty at build time and verified again at boot.
- Pre-install evaluation. The ISO is booted on real hardware (or a Secure-Boot-capable test VM) and the live environment is examined before any install: the Secure-Boot and integrity chain, the system and user logs, failed units, and the shipped security posture (the system ships locked — no remote access enabled, default-deny firewall). A clean smoke pass does not by itself guarantee a clean install.
- Install and post-install evaluation. The installer writes the system to disk, then the result is examined exhaustively, not as a spot-check. The full installer trace is read end to end, the install-run journals are read, the system is rebooted into the installed target, and the installed logs are read for every boot — confirming zero failed units and a clean boot-chain trust record. Every operator observation and every log anomaly becomes a tracked issue.
- Track issues, then iterate. Findings are grouped into layers applied and validated together, so a regression localizes to its layer. For day-to-day iteration, a single rebuilt package can be slipstreamed into the install set without rebuilding the whole ISO. Every such surgical edit is saved to the source tree and must prove itself on the next from-scratch build; no edit rides un-reproduced.
- Publish to the signed mirror. The index is the signed manifest of the whole repository, so every publish regenerates and re-signs the complete index; clients verify the entire index against one signature. Data transfer is incremental, but the signed index is never partial, and the live repository is promoted by an atomic swap.
- Promote to a stable release. A candidate is promoted to a golden release only when a full from-scratch cycle runs end to end with zero triggers — nothing required a fix. All boot and install legs are validated on representative (lower-end) hardware, with race-class items cleared over several consecutive cold boots. Anything short of that bar is a trigger: fix it in the tree and keep iterating.
The non-negotiables
- Built from source. The standard, transparent, from-source path, not opaque shortcuts.
- No silent failures. Every error surfaces; an unverified assumption becomes a checked gate or it is not trusted.
- No stubs. Placeholder code that pretends to work does not ship.
- Reproducible. Pinned, checksum-verified sources; deterministic builds.
- Only a clean build counts. A fix is done when it lives in the tree and a clean build reproduces the corrected behavior with zero manual steps.
- Signed end to end. A signed Secure-Boot chain, an integrity-verified system image, and a signed package index — verification you can check yourself.
Development setup
The build requires:
- An Ubuntu 24.04 (or equivalent) build host.
- KVM/QEMU with libvirt for VM-based builds.
- Python 3.12+ with PyYAML for the build system.
- All LFS 13.0 host requirements (run
python3 scripts/host-check.pyto verify).
License and sign-off
InterGenOS is licensed under the GNU General Public License v3.0 or later, the project’s outbound license. Contributions are accepted under this same license (inbound = outbound; there is no separate Contributor License Agreement).
The contributor authorship and right-to-submit attestation is the Developer Certificate of Origin (DCO), revision 1.1. By appending a Signed-off-by: trailer to each commit, you certify the DCO statements; the verbatim text lives in the repository’s DCO.md.
git commit -s
The -s (or --signoff) flag adds the trailer automatically using your user.name and user.email git configuration. Every commit in a pull request must carry the trailer; pull requests whose commits are not all signed off will fail the public-content + DCO audit workflow and cannot merge until the trailer is added.
To add the trailer to existing commits retroactively:
git rebase --signoff master # all commits on this branch
git commit --amend --signoff # the latest commit only
Commits made before 2026-05-18 (when the DCO was adopted) are grandfathered under the prior model; the DCO applies from that date forward.
Where to go next
- New to the system? Read the FAQ.
- Installing InterGenOS? See the Forge installer guide.
Packaging & Package Manager Internals
InterGenOS builds every package from source and ships the results as signed binary archives. This page documents the two halves of that pipeline: igos-build, the factory that compiles source into archives, and pkm, the package manager that installs, removes, queries, and verifies those archives on a running system. It covers the recipe model, the on-disk database, signing and integrity, and the reproducible-builds direction.
This is a developer and contributor reference. For adding a single package end to end, the gates described below mirror the maintainer workflow.
Version: 1.0-dev (build id v1.0-dev1).
Two components, one pipeline
igos-build is the factory; pkm is the consumer.
igos-buildcompiles source code in an isolated chroot and produces a.igos.tar.gzarchive per package.- During the tracking phase,
igos-buildgenerates the initial file list and content hashes for each archive. - If a build uses
direct_install(deploying straight into the chroot rather than to aDESTDIRstaging tree),igos-buildcallspkminternally to register the resulting files into the package database. - For end users,
pkmis the CLI tool that downloads and installs those.igos.tar.gzarchives from the network repository.
igos-build constructs packages from source in an isolated environment; pkm operates on the live filesystem.
The package recipe model
A package is a directory at packages/<tier>/<name>/:
packages/<tier>/<name>/
├── package.yml ← required: metadata + verify_paths
├── build.sh ← required for build_style: custom; optional for autotools/meson
├── <name>.1 ← optional manpage (some packages ship a tracked manpage in-recipe)
└── patches/ ← optional, build.sh-consumed
Tiers
InterGenOS organizes packages into six tiers. Each tier is built by exactly one builder, and a package’s tier: field determines which one. As of 2026-06-15, the live tree carries roughly 857 packages: toolchain 28, core 272, base 23, desktop 420, extra 112, and ai 2. These counts drift as packages land; derive the current numbers from the tree rather than treating any number as fixed.
| Tier | Builder | Where wired |
|---|---|---|
toolchain | bootstrap toolchain phases | build orchestrator |
core | bash static list | scripts/chroot-build-*.sh (one per phase) |
base | bash static list | scripts/chroot-build-base.sh |
desktop | Python topological sort | igos-build.py --tier desktop |
extra | Python topological sort | igos-build.py --tier extra |
ai | Python topological sort | igos-build.py --tier ai |
Pick the tier that matches the package: foundational utilities go to core or base; GUI and desktop applications go to desktop; servers, dev tooling, browsers, and system utilities go to extra; the local AI runtime goes to ai.
The two builders are mutually exclusive. The bash static-list builder (tiers core and base) enumerates packages explicitly in run_package lists inside scripts/chroot-build-<phase>.sh. The Python tier-driver (igos-build.py, tiers desktop / extra / ai) walks packages/<tier>/ at build time, computes the topological-sort closure of declared dependencies:, and builds everything reachable. A package must be reachable by exactly one builder; a recipe reachable by neither is an orphan that will never build. The orphan detector at scripts/check-builder-coverage.py is the early-warning system for that class and should report OK: all packages reachable by exactly one builder.
package.yml
The recipe metadata file declares identity, source, dependencies, and the paths the package is expected to install:
name: <name>
version: "<semver>"
release: 1
description: <one-line description>
license: <SPDX-identifier>
homepage: https://<upstream-homepage>
tier: <core|base|desktop|extra|ai>
build_style: <custom|autotools|meson|cmake|cargo|python>
source:
- url: https://<mirror-or-upstream-url>/<name>-<version>.tar.<ext>
sha256: <expected-sha256-of-tarball>
dependencies:
build: [] # build-only deps (autoconf, pkgconf, etc.)
host: [] # host-only tooling (rare)
runtime: # runtime deps (libraries linked, interpreters required)
- <dep1>
verify_paths:
- /usr/bin/<name>
- /usr/lib/lib<name>.so
- /etc/<name>/<name>.conf
The source tarball’s sha256: is pinned in the recipe; a download whose hash does not match is rejected. The discipline is mirror-first: stage the tarball on the InterGenOS source mirror or a file:/// URL inside the chroot. Networked https:// URLs are accepted but are not the default posture.
verify_paths: the install contract
verify_paths: is the package’s declaration of which files prove it landed. Each entry must be an absolute path with at least three segments (for example /usr/bin/x), and a recipe should pick two or three paths that establish identity:
- The primary binary at
/usr/bin/<name>or/usr/sbin/<name>is the strongest identity signal. - The primary library at
/usr/lib/lib<name>.so*for library-only packages. - A canonical directory under
/usr/share/<name>/,/usr/lib/<name>/,/etc/<name>/, or a firmware path for data, firmware, or config packages. - The
site_perlorsite-packagespath for Perl/Python module packages. - For the kernel,
/boot/vmlinuz-<version>plus/usr/lib/modules/<version>.
verify_paths is enforced at two gates. The pre-push hook refuses a new package.yml that declares neither verify_paths: nor pending_acquisition:. At image-build time, the pre-squashfs audit (scripts/pre-squashfs-audit.py) verifies every declared path is actually present in the chroot and halts the build if one is missing. A helper at igos-build/verify_paths_derive.py can auto-derive a fallback when a recipe omits the field, but the human-curated declaration remains the source of truth.
A package that legitimately cannot be acquired yet (blocked on an external dependency such as upstream sponsorship) replaces the verify_paths: block with pending_acquisition: "<reason>". The pre-squashfs audit skips such packages. This is reserved for blocked-on-external cases, not as a workaround for skipping the install contract.
build.sh
For build_style: custom, build.sh defines configure, build, and do_install functions; the orchestrator sources the script in the chroot’s per-package work directory and calls each in sequence. An optional post_install runs after the package is registered, for cache-rebuild work such as ldconfig or systemd presets that depends on the files already being in place.
#!/bin/bash
configure() {
set -e
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
}
build() {
set -e
make -j"$(nproc)"
}
do_install() {
set -e
make DESTDIR="${DESTDIR}" install
}
Two recipe rules carry weight here. Stub functions are forbidden: a configure() that is only : and a do_install() that produces nothing is rejected. If the package has source, it must compile. A true metapackage with no source declares source: [] and uses do_install() only to write config files, with a header comment stating the package is intentionally meta. Patches to bundled source are applied by hand inside build.sh from the recipe’s own patches/ dir, not via a package.yml patches: key (that key is auto-applied from the source-staging directory and is for patches that ship alongside a fetched upstream tarball).
The package manager: pkm
pkm manages the state of the installed operating system: installation, removal, querying, and integrity verification of the pre-compiled .igos.tar.gz archives.
Hybrid data model
pkm uses two stores that mirror each other:
- A SQLite database at
/var/lib/igos/pkm.dbis the primary source of truth, used for fast queries and transaction management. - Text manifests at
/var/lib/igos/packages/are human-readable records generated alongside the database for inspection and transparency.
The duality keeps queries fast without giving up auditability: every database fact has a readable text counterpart you can inspect directly.
Database schema
The schema (pkm/database.py) consists of several interconnected tables:
installedtracks active and superseded package metadata:name(unique),version,tier,description,install_date,superseded_by,superseded_at.filesmaps every deployed file to its owning package:package_id(foreign key),path,is_dir,is_config,checksum(SHA-256). Indexed bypathfor fast owner lookups.dependstracks runtime package relationships.availablecaches remote repository metadata, synced viapkm sync.historyis an append-only transaction log of every operation (installs, removals, supersedes) for audit trails.config_filesspecially tracks files in/etc/to manage user modifications.
Installation pipeline
pkm/installer.py follows a strict sequence:
- Staging extraction. The archive is extracted to a temporary staging directory using hardened
tarflags (--no-same-owner,--no-same-permissions). - Manifest reading. The staged manifest is parsed for the file list,
SUPERSEDESdeclarations, and embedded file hashes. - Invariant checks.
pkmchecks for directory collisions (for example, preventing a package from replacing the/libsymlink with a directory) and verifies that any predecessors named inSUPERSEDESexist and are correctly ordered in the install queue. - Filesystem deploy. The archive is deployed to the root filesystem with
tar --no-overwrite-dir --keep-directory-symlink. The hardened flags drop setuid/setgid bits, which are then explicitly restored by parsing thetarfileheader metadata. This deploy is the point of no return: a successful write commits the package to disk before the database transaction that records it. - Atomic DB transaction. A single
BEGIN/COMMITblock creates theinstalledrecord, registersfileswith their content hashes, transfers overlapping file ownership for anySUPERSEDESpredecessor (marking itsuperseded_by), and appends ahistoryentry. - Text manifest generation. The text manifest at
/var/lib/igos/packages/{name}-{version}is written reflecting the final database state.
Removal
pkm/remover.py processes files cautiously. The file list is read from the database; configuration files under /etc/ are skipped to preserve user data unless --force is supplied. Regular files are unlinked. If a file’s on-disk hash differs from the database hash (it was modified post-install), pkm warns but proceeds. Directories are removed only when they become completely empty. The installed, files, and depends records are then deleted.
Upgrades: the supersede model
pkm handles upgrades through supersede semantics. When package B supersedes package A:
- Files present in both
AandBare overwritten on disk byB; in the database, ownership transfers fromAtoBwith updated SHA-256 hashes. - Files that existed in
Abut notBare left in place, still owned byA’s historical record. A’sinstalledrecord receives asuperseded_bytimestamp pointing toB.
This supports fine-grained package splits (for example util-linux splitting into util-linux-core and util-linux-extra) without orphaning files or breaking dependencies.
Integrity and security
InterGenOS treats verifiability as a core property, not an add-on. The package layer contributes three checks.
Content-hash verification
pkm verify recalculates the SHA-256 hash of every installed file on disk and compares it against the expected hash in the files table. This detects both accidental corruption and unauthorized modification of installed binaries.
Archive verification
Before installation, the cli.py layer exposes an --archive-trust flag. In strict or repo-only modes, the incoming archive’s SHA-256 is computed and checked against the trusted available index synced from the central repository. An archive whose hash is not in the trusted index is rejected.
Config vs. content
pkm tracks is_config state for files under /etc/, and the config_files table stores each file’s original deployed hash. When an upgrade ships a new config file, pkm attempts a safe merge, or leaves a .new file if it detects the user has modified the active configuration on disk. User configuration is preserved by default.
The signed chain around packages
The package archives sit inside a broader signed integrity chain that InterGenOS ships today: a signed Secure Boot chain, dm-verity integrity for the read-only system image, and signed Unified Kernel Images (UKIs). Content-hash verification ties each installed file back to a known-good value. Together these mean the path from “what the repository published” to “what is running on disk” is checkable at every link, not just at download time. The result is a machine you understand, can modify, and can trust.
Reproducible builds
Reproducible builds are a documented goal for InterGenOS and a security primitive: starting from the same source, the same toolchain, and the same documented build environment, two independent builders should produce byte-identical output. That property lets a third party detect silent backdoor insertion or build-environment tampering that signing alone cannot catch. It is the difference between “we signed the binary” and “the binary is independently verifiable from source.”
The current state is partial. Bit-identical output is the documented 1.0 goal but the full toolchain plumbing is still being built out. SOURCE_DATE_EPOCH is partially honored in the manifest-emission path of the build orchestrator, and the cargo-vendor pipeline (scripts/cargo-vendor-gen.sh) already produces reproducible vendor tarballs using the standard recipe:
tar --sort=name --owner=0 --group=0 --numeric-owner \
--mtime=@${SOURCE_DATE_EPOCH} --format=pax vendor/ | xz -T 1 -9
The .igos.tar.gz archive emitter (scripts/emit-package-archives.py) does not yet apply the same normalization. Python’s tarfile defaults embed source mtimes, the builder’s uid/gid, and a gzip header timestamp, all of which vary between builders. The planned fix normalizes each tar member (uid/gid zeroed, owner/group root, mtime pinned to SOURCE_DATE_EPOCH) and writes the gzip layer separately with a zero timestamp. Other identified gaps include exporting SOURCE_DATE_EPOCH into the chroot so compilers honor it, build-path prefix mapping (-ffile-prefix-map / --remap-path-prefix) to keep absolute chroot paths out of binaries, and pinning LC_ALL=C plus TZ=UTC.
The 1.x target is byte-identical .igos.tar.gz per package across two builders, plus an audit harness (scripts/verify-reproducible.sh, planned) that any contributor can run to confirm the property for a given package. Bootstrap-tier (toolchain) reproducibility and full ISO determinism are scoped beyond 1.x. None of the reproducibility plumbing beyond what is described as current should be read as shipping today.
See also
- FORGE Internals — the installer that lays the built image onto a machine.
- Security Review — the signed-chain and integrity posture in depth.
- FORGE Installer Guide — installing the built image.
FORGE Internals
FORGE is the InterGenOS installer. It takes a booted live environment and turns it into a deployed, bootable, user-configured operating system on a target disk. This page covers its architecture and how to contribute to it.
FORGE is distinct from the build system that produces the ISO. The build system (igos-build) compiles every package from source and assembles the signed image; FORGE consumes that image at install time and writes it to the user’s disk. For the build pipeline that creates the ISO itself, see Building the ISO below.
This is the 1.0-dev release (build id v1.0-dev1). The internals described here reflect what ships today.
Design principles
FORGE is built on three foundations.
- Declarative intent. Frontends collect user choices and emit a serialized YAML state describing the desired system. The backend consumes that YAML, plus the credentials it needs (passwords), and executes the install. The frontend never touches the disk directly.
- Supply-chain integrity. A verification gate runs before any disk write. It checks every package archive against the cryptographically signed release manifest to detect tampering, and halts the install before partitioning on any mismatch. This is the same posture the rest of the system carries: security is not first. It is only.
- Phased execution. The install runs as a linear sequence of phases. A failure halts the pipeline, performs best-effort unmounts, and surfaces the exact point of failure rather than leaving the disk in an unknown state.
Layout
FORGE lives primarily under installer/ and uses a split frontend/backend architecture united by the declarative state model:
installer/frontend/tui.py— the text frontend.installer/frontend/gui/— the graphical frontend.installer/backend/install.py— the backend orchestrator.installer/backend/hooks.py— resource context managers (mounts and similar).installer/init/init.sh— the live boot-time init that activates and verifies the root filesystem.
The two frontends
FORGE ships two user-facing frontends that execute identically against the same backend.
TUI (installer/frontend/tui.py)
A dialog-based text interface. It suits SSH-based installs, headless servers, and keyboard-driven workflows. It emits the declarative install.yaml (written to /var/lib/forge/install.yaml) and, separately, an interactive-state structure (install_io) holding the target disk and credentials, which the backend consumes alongside the YAML.
GUI (installer/frontend/gui/)
A GTK4 / libadwaita application, built as a multi-screen wizard: welcome, keyboard_locale, disk, user, packages, confirm, progress, done. It accumulates selections in installer/frontend/gui/state.py as the user moves through screens.
Security-critical interactions get dedicated handling. integrity_dialog.py disables paste (clipboard, drag-and-drop, and the right-click menu) on the integrity-override-phrase entry. The phrase must be typed in full, ensuring deliberate consent before any integrity-check override is accepted.
The backend pipeline
run_install() in installer/backend/install.py is the backend entry point. It consumes the YAML state and the interactive-state structure, then runs the 13-phase install pipeline (PHASE_ORDER):
- Validate (
PHASE_VALIDATE) — checks the YAML structure and runs deep validations (for example, regex validation of the requested hostname via_validators.py). - Verify (
PHASE_VERIFY) — the core security gate. It computes the SHA-256 of every package archive to be deployed and verifies each againstintergenos-archive-manifest.txt, which is signed by the release keys. A mismatch halts the installer before partitioning, unless the user provides explicit typed confirmation to override. - Partition (
PHASE_PARTITION) — wipes the target disk, writes a new partition table (EFI or BIOS), and formats filesystems. - Mount (
PHASE_MOUNT) — mounts the new root and boot partitions at a staging path (for example/mnt/target). - Virtual FS (
PHASE_VIRTUAL_FS) — bind-mounts the host/dev,/proc, and/sysinto the staging path forchrootoperations. - Packages (
PHASE_PACKAGES) — delegates topkmviapackages.py. Thread-queued execution extracts and registers every package named in the YAMLpackage_groups. Individual package failures are tracked but do not abort the install; FORGE surfaces a partial state instead. - Config (
PHASE_CONFIG) — generates system configuration (/etc/fstab, locale, timezone links) from the YAML intent. - Users (
PHASE_USERS) — sets the root password and creates the initial unprivileged account. - MOK / Secure Boot (
PHASE_MOK) — on an EFI system, generates a Machine Owner Key (MOK) keypair inside the target environment. - Bootloader (
PHASE_BOOTLOADER) — installs GRUB to the target disk. On EFI, GRUB is signed with the MOK keypair generated in the previous phase. - Hooks (
PHASE_HOOKS) — runs package-specific post-install scripts (font-cache updates, gsettings schema compilation, and similar). - Services (
PHASE_SERVICES) — enables the necessarysystemdservices for the target. - Cleanup (
PHASE_CLEANUP) — unmounts virtual filesystems and the target disk, copies the integrity audit log, and reports the result.
Error handling
FORGE prioritizes safe failure modes.
- Context managers. Mounts and similar resource-heavy operations are wrapped in context managers (
installer/backend/hooks.py) so unmounting happens even when an exception is raised. - Phase tracking. The
InstallResultobject tracksphase_completed. On exception, the orchestrator runs a cleanup block (_PHASES_NEEDING_UNMOUNT) scoped to how far the install reached. - User transparency. Non-fatal problems, especially trust-chain ones such as audit-log copy failures, emit warnings to
InstallResult.warnings. These show on the frontend’s final screen so the user always knows the true state of the deployment.
What gets installed
The image FORGE deploys is assembled from packages built across six tiers: toolchain, core, base, desktop, extra, and ai. Counts drift as the system evolves. As of this writing (2026-06-15) the totals are approximately:
| Tier | Packages (approx.) |
|---|---|
| toolchain | 28 |
| core | 272 |
| base | 23 |
| desktop | 420 |
| extra | 112 |
| ai | 2 |
| Total | ~857 |
To derive the live numbers for a given checkout, count the package definitions per tier rather than trusting a static figure.
The desktop that ships today is GNOME 49 on Wayland. The two ai packages are the local assistant InterGen (a tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry) and llama.cpp, the inference engine it runs on. InterGen bundles a security-scanner subsystem, InterGen Sentinel, that defaults to Local-Rules plus Local-Qwen and offers six opt-in cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), and DeepSeek). The cloud-escalation path is called Phone-A-Friend (Frontier/Cloud Escalation) and is opt-in by design.
Building the ISO
The installer is one half of the story; the other is the build system that produces the bootable image. The full build runs 20 phases:
validate -> verify-sources -> setup -> toolchain -> chroot-prep ->
chroot-tools -> core -> config -> core-extra -> base -> kernel ->
desktop -> ai -> extra -> bootloader -> image -> manifest ->
squashfs -> ukis-verity -> iso
A publish phase is optional. The final stage assembles the hybrid UEFI+BIOS ISO from the signed components.
The canonical ISO entry point is scripts/build-iso.sh, usually invoked by scripts/build-intergenos.sh, which sets its variables from its own phase state. It is env-var-driven rather than flag-driven. A representative manual invocation:
SHIM=/path/to/shimx64.efi.signed \
GRUB=/path/to/grubx64.efi.signed \
UKI_LIVE=/path/to/igos-live.efi.signed \
UKI_INSTALL_GUI=/path/to/igos-install-gui.efi.signed \
UKI_INSTALL_TUI=/path/to/igos-install-tui.efi.signed \
SQUASHFS=/path/to/filesystem.squashfs \
OUTPUT=build/intergenos-1.0-dev1.iso \
SOURCE_DATE_EPOCH=$(date -u +%s) \
bash scripts/build-iso.sh
Set SOURCE_DATE_EPOCH explicitly whenever reproducibility matters: the script otherwise falls back to current time with a warning, and a deliberate value makes the ISO bit-identical across rebuilds.
build-iso.sh runs six internal phases: stage the ESP layout, build the FAT32 ESP image (mkfs.vfat -F 32 ... -n IGOS_ESP), stage the ISO9660 root (dropping filesystem.squashfs, filesystem.verity, and filesystem.sha256 under /live/), invoke xorriso (requires 1.5.6+ for SOURCE_DATE_EPOCH), self-verify the GPT and El Torito structures, and emit a <OUTPUT>.manifest recording input/output SHAs and tool versions.
The trust chain
The signature chain shim -> GRUB -> UKI is covered by Secure Boot, but the root filesystem lives outside the UKI at /live/filesystem.squashfs. Without independent verification an attacker could swap the squashfs and still boot a trusted UKI. InterGenOS closes that gap with two paired checkpoints that must stay in lockstep:
- Primary — dm-verity. The live UKI’s sealed cmdline carries
igos.verity.roothash=<HEX>. The merkle hashtree ships on the media at/live/filesystem.verity;init.shactivates a dm-verity device and the kernel verifies each 4 KiB block as it is read. Because the root hash lives inside the Secure-Boot-signed UKI, the squashfs cannot be swapped without invalidating the chain. - Fallback — whole-file sha256.
/live/filesystem.sha256is written and verified, used only when the cmdline lacksigos.verity.roothash=(older or development UKIs). It is slower but reliable.
The build asserts that both filesystem.verity and filesystem.sha256 land non-empty, and fails otherwise. Changing one side of this pairing without the other re-opens the gap. Never remove the build-time assertion on the assumption that boot-time init will catch the problem: that turns a build-VM exit 1 into a kernel-panic-class abort on the user’s machine.
The full ISO build, signing flow, squashfs generation, and test-VM evaluation are documented in the operations topics under docs/operations/.
Contributing
FORGE is meant to be understood and modified. A few orientation points for working on it:
- Start from the phase you are touching. Both the install pipeline (
PHASE_ORDERininstaller/backend/install.py) and the ISO build (scripts/build-iso.sh) are linear and named. Find the phase, read it, change it in isolation. - Keep the two frontends equivalent. The TUI and GUI must produce the same declarative state and execute identically against the backend. A change that touches install behavior belongs in the backend, not in one frontend.
- Never relax the integrity gate quietly. The verify phase and the dm-verity / sha256 pairing are load-bearing for the whole trust model. Changes there need matching changes on the paired side and explicit review.
- Test against a VM before hardware. Build the ISO, boot it under QEMU with Secure Boot enabled, exercise MOK enrollment, and run both install frontends end to end before testing on real disks.
The goal of every change is the same as the goal of the system: a machine you understand, can modify, and can trust.
See also
- FORGE install guide — using the installer.
- Contributing — how to work in the InterGenOS tree.
AI Assistant Internals
This page describes the internals of InterGen, the local AI assistant built into InterGenOS, and InterGen Sentinel, the security layer that guards everything InterGen touches. For the user-facing “what it does and how to set it up” view, start with the FAQ.
InterGen runs entirely on the local machine, with no cloud dependency by default. It is a conversational interface for system administration, configuration, and coding. The design follows the same posture as the rest of the system: a machine you understand, can modify, and can trust.
Design principles
- Local-first. Inference runs on local hardware by default, so your data stays on your machine.
- Hardware-tiered. InterGen detects the host’s RAM and GPU and selects an appropriately sized model automatically.
- Security is only. Every proposed action passes through a safety classifier, and destructive or security-bypassing operations are refused outright.
- Predictable routing. Requests flow through a deterministic, priority-ordered chain that resolves common queries cheaply instead of handing every interaction to the model.
InterGen ships in the ai tier of the build, the smallest of the system’s six package tiers. (The build assembles roughly 857 packages across toolchain, core, base, desktop, extra, and ai as of June 2026; these counts drift over time.)
Model catalog and hardware tiers
InterGen scales to the hardware it detects. intergen/hardware.py probes RAM and GPU and assigns a tier; intergen/model_manager.py holds the canonical model catalog and downloads, verifies, and selects the model for that tier; intergen/llama_manager.py manages the llama-server subprocess (from llama.cpp) that serves the selected model over a local HTTP API.
The shipping tiers, all built on Qwen models:
| Tier | Model | Approx. size | Selected when | Role |
|---|---|---|---|---|
| 1 — Basic | Qwen3.5-2B Q4_K_M | ~1.5 GB | under 8 GB RAM | semantic matching, system queries, keyword extraction; not complex code generation |
| 2 — Standard | Qwen3.5-9B Q4_K_M | ~5.5 GB | 8 to 15 GB RAM | the default daily driver: coding, configuration, reasoning |
| 3 — Advanced | Qwen3.5-35B-A3B Q4_K_M (MoE) | ~21 GB | 16 GB+ RAM with a discrete GPU | deep multi-file analysis, complex architectural reasoning |
On a Tier 2 machine without a discrete GPU, InterGen falls back to the 2B model to keep response latency usable. A small embedding model (nomic-embed-text, Apache-2.0) ships alongside every tier to power the router’s semantic-matching layer. The assistant collects zero telemetry.
The priority router
intergen/router.py is a priority-ordered routing chain. Rather than sending every prompt straight to the model, the router tries to satisfy each request with the cheapest, most predictable method first and escalates only when it has to.
- Priority 0 — Decomposition. Detects compound requests (“update the system, then restart the web server”), splits the prompt into sub-tasks, and routes each one in turn.
- Priority 1 — Keyword/regex match. Fast pattern matches for common system commands (“what’s my IP?”, “check disk space”) dispatch directly to a built-in tool without invoking the model.
- Priority 2 — Semantic embedding match. Lightweight embedding search against a pre-computed catalog of capabilities; a high-confidence match dispatches to the corresponding tool.
- Priority 3 — LLM tool calling. For Tier 2 and above, the query goes to the model with a schema of available system tools. The model selects a tool and arguments; the router executes the call and synthesizes the result.
- Priority 4 — LLM free response. The fallback: the model answers conversationally from its own knowledge and the conversation context.
Safety classification
Every action the router proposes passes through the classifier in intergen/safety.py, which sorts the operation into one of three tiers:
AUTO— Read-only or harmless operations (ls,grep,systemctl status). Executed immediately, without a prompt.CONFIRM— State-changing operations (systemctl restart,pkm install, editing a config file). The assistant pauses and asks you to approve before it runs.BLOCKED— Destructive or security-bypassing operations (rm -rf /, reformatting the root partition). Refused outright, with an explanation.
This classification is what keeps the user in control: nothing that changes the system runs without explicit approval, and the most dangerous commands cannot run at all.
Desktop and tool integration
InterGen exposes its capabilities to the GNOME 49 / Wayland desktop through a D-Bus service (intergen/dbus_daemon.py), so other applications can request completion, summarization, or semantic search over IPC. The D-Bus surface is deliberately narrow: only a small set of vetted interfaces is exposed, which prevents a local unprivileged application from driving arbitrary code execution through dbus-send.
InterGen is also a Model Context Protocol (MCP) client (intergen/mcp_client.py). It can connect to local MCP servers to acquire new capabilities or query data sources, while preserving the boundary between the assistant’s core runtime and the tool-execution environment.
Conversational context is split between intergen/memory.py — a user-controlled store of persistent facts plus a rolling window of recent turns — and intergen/state_cache.py, which caches recent query results so identical prompts are not recomputed. Facts are added and removed by explicit request, stored data is fully inspectable, and all of it is serialized and persisted locally.
InterGen Sentinel — the security layer
InterGen Sentinel is the security scanner that guards InterGen’s interactions with the outside world. It defends both the user and the machine whenever the assistant crosses a trust boundary: an MCP server, a web fetch, a file write, or an outbound request to a frontier model. Sentinel has four cooperating parts.
1. A pluggable scanner engine
The scanner (intergen/scanner/) inspects one piece of content travelling one direction across a trust boundary and returns a verdict. The core interface lives in intergen/interfaces/scanner.py:
ScanDirection—EGRESS(arguments leaving the machine; exfiltration risk) orINGRESS(content arriving before it re-enters the model context; injection risk).ScanDisposition—ALLOW/FLAG/BLOCK, severity-ordered.FLAGmeans “suspicious, hold for human review”;BLOCKmeans “high-confidence malicious, hard refuse.” When multiple verdicts merge, the most severe wins (default-deny).ScanContextandScanVerdictcarry the surface, direction, and tool name alongside a reason, confidence score, and originating scanner.
ScannerPolicy (intergen/scanner/policy.py) composes an always-on deterministic floor with an optional deeper scanner:
LocalRulesScanneralways runs first as the deterministic floor.- A
BLOCKfrom the floor short-circuits without spending the deeper scan. ALLOWat baseline depth passes through.- A
FLAG, or any scan configured at deep depth, escalates to the configured deeper scanner. - Most-severe disposition wins. A scanner that errors fails closed to
FLAG— never a silentALLOW.
The three scanners:
| Scanner | Local? | Role |
|---|---|---|
LocalRulesScanner | yes | always-on deterministic floor: pattern/heuristic rules, no model, no network |
LocalQwenScanner | yes | on-device llama.cpp Qwen classifier; the default deeper scanner, still no network |
CloudScanner | no | opt-in deep tier wrapping a vendor-neutral cloud adapter; off unless you opt in |
The default configuration scans entirely on-device with the rules floor plus the local Qwen classifier. The deep cloud tier is opt-in and backed by one of six providers: Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), or DeepSeek. No cloud provider is configured by default.
2. A single dispatch chokepoint
Every tool call and MCP interaction is dispatched through ToolRegistry.execute (intergen/tool_registry.py), where Sentinel wires in the ScannerPolicy. Scanning is therefore structural, not per-call opt-in: arguments are egress-scanned before they leave toward a surface, returned content is ingress-scanned before it re-enters the model context, a BLOCK refuses or withholds, and a FLAG is raised to a human review modal. The scan composes with the existing provenance gate and spotlight at the same chokepoint, so three defenses layer on the one path everything must traverse.
Turning scanning off requires the human-authenticated path, and the scan policy sits in the protected configuration set that the assistant itself can never edit.
3. Phone-A-Friend (Frontier/Cloud Escalation)
EscalationManager (intergen/escalation.py) implements Phone-A-Friend (Frontier/Cloud Escalation), the consent-first path for handing a request to a more capable frontier model when the local assistant cannot satisfy it. It is distinct from the quality fallback in llm.py (which auto-escalates after the local model fails twice): Phone-A-Friend recognizes that a task is multi-step, sensitive, or slightly outside scope and offers to reach your configured frontier model, sending nothing without explicit consent.
- Modes (config
escalation.mode, defaultASK):NEVER(offline; never offer or send) ·FALLBACK(auto-escalate only on local quality-gate failure) ·ASK(offer on recognition; consent before any send) ·AUTO(decide by confidence, no prompt). - Hybrid recognition. A heuristic considers local confidence, multi-step signals, and query type; a user-invoked affordance (a GUI button with CLI parity) bypasses the heuristic, since the user already asked.
- Show-before-send. The consent modal (
intergen/consent_modal.py) displays the full outbound payload before any send, so consent is informed. - Scan-on-derivation. The initial egress you explicitly authorized is trusted at source; every subsequent derived egress is egress-scanned through the same
ScannerPolicy, so aBLOCKkeeps secrets from shipping to the cloud. - No default provider. With none configured, escalation cannot run and offers degrade to a “configure a provider” note. InterGen ships local-only and ready.
The same six providers are available here, with API keys stored in the system keyring rather than in plain configuration.
4. The destructive-policy never-list
An OpenPGP-signed manifest (intergen/data/destructive-policy-manifest.json, installed read-only under dm-verity) enumerates the paths InterGen’s AI may never perform a destructive operation on. There is no config option to widen it, ever: this is anti-self-tamper plus system-survival and credential/boot integrity. Anything not on the list and not dm-verity read-only is fair game under per-capability opt-in and per-action human consent. The manifest’s system_ai category also covers InterGen’s own config and state directories, so the same enforcement protects the Sentinel, escalation, and provider settings the assistant cannot edit.
Three composing pieces:
- The pure matcher (
intergen/destructive_policy.py) — given a loaded manifest, decides whether a candidate path is protected. No I/O, no signature logic. - The signature-verifying loader — verifies the detached signature against the operator key over the exact bytes read (closing a verify-then-parse race) before trusting the JSON. A manifest that does not verify to the pinned operator key is not trusted; the loader fails closed to an interim floor.
- The chokepoint enforcement — consults the matcher inside the file-write classifier, with a canonicalized immutable-prefix floor as defense-in-depth.
Match semantics resolve symlinks and .. before comparing, so a symlink or path-traversal detour cannot smuggle a write past a prefix entry, and a candidate that cannot be normalized is treated as protected (fail closed).
The vendor-neutral cloud substrate
intergen/cloud/ is the raw-HTTP substrate the CloudScanner and Phone-A-Friend both ride on. It is vendor-neutral and SDK-free: six built-in providers (anthropic, openai, google, microsoft, deepseek, xai) plus a custom adapter for any OpenAI-compatible endpoint, all sharing a raw-HTTPS base with no vendor SDKs (a supply-chain posture that bans third-party packages from the package index). API keys are read from the keyring per call and never cached in process, and a request over a non-TLS transport is refused.
Code map
| Concern | Location |
|---|---|
| Hardware probe and tier selection | intergen/hardware.py |
| Model catalog, download, verify | intergen/model_manager.py |
| llama-server lifecycle | intergen/llama_manager.py |
| Priority router | intergen/router.py |
| Safety classifier | intergen/safety.py |
| D-Bus service | intergen/dbus_daemon.py |
| MCP client | intergen/mcp_client.py |
| Memory and state | intergen/memory.py, intergen/state_cache.py |
| Scanner interface (ABC, types) | intergen/interfaces/scanner.py |
| Scanner engine (3 scanners + policy) | intergen/scanner/ |
| Chokepoint scan-wiring | intergen/tool_registry.py |
| Phone-A-Friend escalation | intergen/escalation.py |
| Consent modal | intergen/consent_modal.py |
| Cloud substrate | intergen/cloud/ |
| Destructive-policy matcher + loader | intergen/destructive_policy.py |
| Signed never-list manifest | intergen/data/destructive-policy-manifest.json |
ROCm-from-Source Build Pipeline
This is the contributor-facing companion to the user page ROCm for AMD. It describes how automated ROCm-from-source enablement is meant to be built and maintained so that it fits the rest of the distribution. It documents intent and the design constraints, not commands that do not yet exist. Where a concrete version, package name, or build flag would be required, it is flagged rather than invented.
Status (1.0-dev, build id
v1.0-dev1). The AI tier that ships today is CPU-only: the local inference engine is compiled without a GPU compute backend, with an explicit instruction-set floor (AVX2-class) and non-native codegen so the binary runs on every supported target rather than only on the build host. A from-source ROCm/HIP compute backend is not part of the shipped tree today. What ships for AMD hardware today is the graphics and diagnostics stack: theamdgpukernel driver and AMD firmware in the base image, Mesa’sradeonsiandradvdrivers, and anamdgpudiagnostics meta-package in theextratier. Everything below describes how the compute pipeline is intended to be built when it lands.
Why this follows the same rules as everything else
InterGenOS is built from source, with pinned, checksum-verified inputs and a deterministic build. A GPU compute stack is one of the largest and most interdependent things a distribution can compile, and it is exactly the class of component where a clean compile can still be wrong at runtime: a backend that links but selects a device the hardware cannot actually drive, a runtime library omitted from a package’s file list, or a hardware-detection heuristic that picks an accelerator path on a GPU that does not support it. None of those is a compile error. Each shows up only when the artifact is installed and the engine is run on real hardware.
So a ROCm-from-source pipeline is held to the same doctrine as the rest of the build: it is not trusted on the strength of a clean compile. It earns trust by being installed and exercised on real AMD hardware, with the detection path validated on the lower-end tier that actually reproduces the awkward cases (integrated GPUs, older compute architectures). When a compute component fails to build, the cause is fixed in the source tree, not worked around: no disabling a feature to dodge a missing dependency, no stub that pretends to work, no package quietly moved to another tier to sidestep a wiring problem. See Build from Source and Contributing to InterGenOS for the broader process.
Where it sits in the lifecycle
InterGenOS is produced as a fixed, ordered build of 20 phases: validate,
verify-sources, setup, toolchain, chroot-prep, chroot-tools, core, config,
core-extra, base, kernel, desktop, ai, extra, bootloader, image, manifest,
squashfs, ukis-verity, iso (with an optional publish step). GPU compute support
belongs in the ai tier, alongside the local inference engine it accelerates.
That placement matters in two ways: the compute stack must be present before the
engine that links against it is built, and both must be in the read-only system
image before the squashfs and ukis-verity phases seal it. A backend slipped in
after the image is sealed would not be covered by the signed integrity chain.
What a from-source ROCm pipeline has to do
A correct pipeline is described by the requirements it must satisfy:
- Pinned, verified inputs. Every source component is pinned to an immutable revision and checksum-verified before use, the same as any other package. Compute stacks pull many interlocking repositories; each one is pinned independently, and a build number a tool reports is never substituted for the revision that actually produced it.
- Built into the system image, then sealed. The runtime libraries, the
device-support files, and anything the engine loads at runtime are installed
before
squashfs/ukis-verity, so they are covered by the same verified- integrity chain as the rest of the system. - Runtime libraries asserted, not assumed. The pipeline asserts that every
shared library the engine dynamically links against is actually installed and in
the right place. The present-but-unloadable defect class — the binary exists,
its libraries do not — passes a binary-only check and fails at first run, so the
package’s verify paths assert the libraries land too. (The shipped CPU engine
already does this, asserting its own
libllama/libggmlshared objects.) - Honest hardware detection. The engine selects a GPU compute path only on hardware that can run it, and falls back to the CPU build otherwise. This is validated on the hardware that reproduces the hard cases, not asserted from a capable development box.
- No silent degradation. If the GPU path is unavailable, the system says so and runs on CPU; it does not quietly ship a broken accelerator path or mask the failure. A masked failure is exactly what the security posture forbids.
The specific source repositories, revisions, build flags, supported compute architectures, the compute package name(s), and its verify paths are intentionally not listed here, because they are not in the shipped tree.
How package counts and tiers are read
Tier contents and package counts drift between builds. As of 2026-06-15 the tree spans six tiers (toolchain, core, base, desktop, ai, extra); the ai tier is small today, and the total across all tiers is in the high hundreds. Derive the live counts from the package tree rather than trusting a fixed number, and check the release notes for the authoritative state.
How it is maintained
When the pipeline lands, it is maintained the way the rest of the build is. A fix to a compute component is made in the source tree, never as a manual edit on a running target, and it is not done until a clean from-scratch build reproduces the corrected behavior with no manual steps. A rebuilt package can be slipstreamed onto an already-booted image for fast diagnosis, but that surgical edit must be saved to the tree and prove itself on the next from-scratch build before it counts. Because GPU and graphics paths are timing- and firmware-sensitive, detection and first-run behavior are cleared over several consecutive cold boots on representative hardware, not a single warm reboot.
How this relates to the local assistant
The accelerator exists to serve the on-device assistant. InterGen is the tiered, hardware-detected, offline-first local assistant; it runs entirely on the machine, sizes the model (Qwen) it loads to the hardware it finds, and reports no telemetry. A from-source GPU compute backend is what would let InterGen run larger models faster on capable AMD hardware while still falling back cleanly to the shipped CPU engine everywhere else. The opt-in frontier-model escalation path, Phone-A-Friend (Frontier/Cloud Escalation), is unrelated to local acceleration; nothing about a GPU backend changes the offline-first, telemetry- free posture of the local assistant. The same holds for the security scanner, InterGen Sentinel: its default backends are local (Local-Rules and Local-Qwen), with cloud providers as an explicit opt-in. Local acceleration serves the local default; it introduces no network dependency.
Principles that govern this work
A machine you understand, can modify, and can trust is the goal, and a GPU compute stack — large, opaque, and easy to ship in a degraded state — is precisely where that is tested. The pipeline is built from source, sealed inside the integrity chain, verified on real hardware, and honest about when the accelerator is and is not available. Until those properties hold on a clean build, the GPU path does not ship, and this page does not claim it has.
See also
- ROCm for AMD (user page)
- GPU Compute overview and backend selection
- Vulkan (default, vendor-neutral backend)
- Build from Source
- Contributing to InterGenOS
- FAQ
Security Review & Advisory Process
This page describes how InterGenOS receives vulnerability reports, triages them, fixes them, and publishes advisories. It is written for contributors and for users who want to understand the discipline behind the trust chain.
Every decision below exists to give you a machine you understand, can modify, and can trust.
Project status. InterGenOS is at 1.0-dev (build id
v1.0-dev1) and in active development toward its 1.0 release. The reporting and response process described here applies to all InterGenOS code and infrastructure. No public ISO has shipped yet, so the advisories published to date document vulnerabilities mitigated before any public installation existed.
Where the canonical policy lives
The authoritative, version-controlled policy is SECURITY.md at the repository root. This page summarizes that policy and the day-to-day process around it. When the two disagree, SECURITY.md wins. Users looking for the human-readable advisory list should also see the Security Advisories release-notes page; the broader hardening posture is covered in the Security Handbook.
Reporting a vulnerability
There are two intake channels:
- Primary: email
security@intergenstudios.com. - Alternative: open a private security advisory on the project’s GitHub repository.
Machine-readable contact information is published per RFC 9116 at https://intergenstudios.com/.well-known/security.txt.
Anonymous reports are accepted. Good-faith reporters are never retaliated against. Encrypted submissions are fully supported and encouraged; the canonical PGP fingerprint for the project’s release and encryption keys is published in the repository’s signing-key documentation, alongside the armored public key.
There is no bug bounty program at this time. Researchers are credited publicly (see Reporter credit below), but monetary rewards are not offered. This may change as the project grows.
Scope
What this policy covers:
- InterGenOS core packages and distribution artifacts
- The
pkmpackage manager and repository infrastructure - Signing keys and related trust infrastructure
intergenstudios.comweb properties
What it does not cover:
- Upstream projects InterGenOS packages (report to them directly; the project coordinates — see Upstream coordination)
- Third-party software a user installs after install
Two response tracks
Reports route into one of two tracks depending on what is at stake. The first is the ordinary software-vulnerability track. The second is reserved for the foundation of the trust chain: a signing-key compromise.
Track 1 — Software vulnerability response
Acknowledgment. Within 48 hours of receipt, the report is confirmed and triage begins.
Triage. Triage assigns a severity, which sets the fix target. Severities and their targets:
| Severity | Examples | Target (from triage) |
|---|---|---|
| Critical | remote code execution, authentication bypass, Secure Boot chain break | 14 days |
| High | local privilege escalation, cryptographic weakness | 30 days |
| Medium | denial of service, information disclosure | 60 days |
| Low | defense-in-depth gaps | 90 days, or with the following release |
Public disclosure. At fix release or 90 days from acknowledgment, whichever comes first. The 90-day cap is a deliberate safety net: unresolved vulnerabilities are not sat on indefinitely.
Track 2 — Trust-anchor compromise
A signing-key compromise is not a bug. It is a break in the foundation of trust, and the ordinary framework above does not apply. This track is dedicated and aggressive. The key-custody architecture that defends against compromise, and the user-side recovery procedure, are documented in the repository’s signing-procedure, signing-key-ceremony, and repository-trust documents.
What counts as confirmed. A confirmed compromise requires evidence, not a claim:
- (a) Direct evidence — exposure of private-key material, a device-tampering indicator, or a credential leak, or
- (b) Anomalous signature — a valid signature observed in the wild that the project did not authorize.
Mere claims route back to the standard 48-hour triage and are likely closed without action.
Response on confirmed compromise:
| Timing | Action |
|---|---|
| Immediate | Acknowledgment |
| Within 12 hours | Revocation published, new keyring package available |
| Simultaneous with revocation | Public disclosure — no embargo, no delay |
The target is that users who run pkm sync within 24 hours of the incident receive the new keyring and revoke trust in the compromised key.
Trust-anchor compromises are never embargoed. The update path is the attack when a signing key is compromised, so revocation cannot wait on convenience. If there is any doubt about key integrity, the key is revoked; re-issuing unnecessarily is preferable to leaving users exposed.
Upstream coordination
When a vulnerability lives in upstream code (kernel, systemd, glibc, and so on), the project coordinates with the upstream embargo. InterGenOS users receive the fix on the same timeline as upstream users, never later.
In practice this is the common case, because InterGenOS is built from source across six tiers (toolchain, core, base, desktop, ai, extra). The package set is large and drifts as the build evolves; derive the live count from the build manifest rather than treating any single number as permanent.
How a kernel fix actually lands
Both published advisories to date are upstream kernel issues, and they illustrate the standard pattern: a primary in-tree patch plus a defense-in-depth layer.
- In-tree kernel patch. Patches live in
packages/core/linux-kernel/patches/. The kernel package’sbuild.shapplies every*.patchin alphabetical order at configure time, so any future build picks up the fix automatically — no manual step beyond rebuilding the kernel (and the UKI, since the kernel image changed). - Defense-in-depth. Where a subsystem is rarely needed on a desktop, the affected modules are additionally blacklisted via a file under
/etc/modprobe.d/. This holds even if a patch regresses or a fallback boots an unpatched kernel. - User control is preserved. Blacklist files are plainly visible and user-editable. A user who needs the affected functionality can remove the file or load the module manually. The trade-off — convenience for a few against security for everyone — is resolved in favor of security, consistent with the security-only posture.
Mitigations take effect on the next kernel rebuild and ISO rebuild; they are not retroactively active on already-built artifacts.
Advisory content
Published software advisories include:
- CVE number (assigned via MITRE)
- CVSS score
- Affected versions
- Mitigation steps
- Patch commit reference
- Timeline (reported / triaged / fixed / disclosed)
- Reporter credit
Trust-anchor advisories instead include the fingerprint of the compromised key, the first known compromised-signature timestamp (if determinable), downstream artifacts suspected tampered, the replacement key fingerprint, verification instructions, and the incident timeline.
Where advisories are stored
Advisory source files live under docs/security/advisories/ in the repository, and the summary table in SECURITY.md indexes them. Two advisories are published as of this writing:
- CVE-2026-31431 — “Copy Fail” (
algif_aeadlocal privilege escalation). CVSS 7.8 HIGH. Disclosed 2026-04-29; mitigated the same day. Layer 1 is the upstream kernel patch reverting the vulnerable in-place optimization in thecrypto/af_alg.cfamily; layer 2 blacklists thealgif_aeadmodule. Verified to have zero impact on dm-crypt/LUKS, kTLS/IPsec/XFRM, OpenSSL/GnuTLS/NSS, SSH, or kernel-keyring crypto, since those use the in-kernel crypto API directly rather thanAF_ALG. - IGOS-SA-2026-002 — “Dirty Frag + Fragnesia” (CVE-2026-43284, CVE-2026-43500, CVE-2026-46300). A cluster of local-privilege-escalation bugs in the kernel
sk_buffshared-fragment path, disclosed between 2026-05-07 and 2026-05-13. Mitigated with three in-tree patches plus amodprobe.dblacklist ofesp4,esp6, andrxrpc. TheCVE-2026-43500fix is an InterGenOS-authored backport, because the upstream mainline commit targets file locations that do not exist in the pinned kernel; the structurally equivalent site was located and patched innet/rxrpc/io_thread.c. The kernel version pin is binding for the 1.0 release line, so the chosen path is to backport fixes rather than bump the kernel.
The second advisory is the clearest argument for the defense-in-depth layer: Fragnesia was itself proof that the first Dirty Frag patches missed a related code path. The module blacklist blocks the affected modules regardless of patch state, which is exactly the failure mode the extra layer pays for.
Reporter credit
Accepted reports are credited in the advisory and on the project’s Hall of Fame page, unless anonymity is requested. Rejected reports default to anonymity; a reporter who wants public credit for a rejected or duplicate report may request it.
See also
- Security Advisories — the user-facing advisory list
- Security Handbook — the hardening baseline and posture
- Verified Boot & Secure Boot — the signed boot chain, dm-verity, and UKI signing that the trust-anchor track defends
- Contributing to InterGenOS — how to get involved with the source tree
Localization & i18n
InterGenOS is built entirely from source, and that extends to how the system handles language, region, and translation. This page describes how localization works in the current release and how contributors can help expand it.
The project is at version 1.0-dev (build id v1.0-dev1). Today the desktop is
GNOME 49 on Wayland, which carries its own mature internationalization stack.
The notes below distinguish what ships today from what is open for
contribution.
How localization works today
Localization in InterGenOS rides on the standard components that the from-source toolchain produces and the desktop consumes:
- Locale data comes from the C library’s locale definitions, generated at build time. Region, date, number, and currency formatting all derive from the active locale.
- The desktop environment is GNOME 49, which uses gettext message catalogs for its translations. Most user-visible GNOME strings are already translated upstream by the GNOME translation community.
- Per-application translations ship with each application package, in the catalogs that upstream provides.
Because the system is assembled package by package, the set of available languages reflects what the included packages carry. As the package set grows across the six tiers (toolchain, core, base, desktop, ai, and extra), so does the breadth of available translations.
InterGenOS-authored components
A few components are written for InterGenOS rather than pulled from upstream. These are where project-specific localization matters most:
- pkm — the package manager
- Forge — the installer
- InterGen — the tiered, hardware-detected, offline-first local assistant (built on Qwen models, with zero telemetry)
- InterGen Sentinel — the pluggable security scanner, which defaults to Local-Rules plus Local-Qwen and offers six opt-in cloud providers, including the Phone-A-Friend (Frontier/Cloud Escalation) path
User-facing text in these components is the highest-value target for translation work, because it is unique to the project and not covered by any upstream translation community.
Contributing translations
There is no separate translation submission process. Translation contributions follow the same path as any other code contribution, and the general workflow from the project’s contributing guidelines applies.
- Open an issue first to discuss the language or component you want to work on. InterGenOS is maintained by a single developer, so coordinating up front avoids duplicated effort.
- Fork the repository and create a branch.
- Follow the existing code style. No surprises, no restructuring beyond the change at hand.
- Test your changes. If you cannot verify that a translation renders correctly, do not submit it. The build must remain reproducible.
- Submit a pull request with a clear description of what you translated and how you verified it.
Every commit must carry a Signed-off-by: trailer certifying the Developer
Certificate of Origin (DCO) 1.1. Add it with:
git commit -s
Pull requests whose commits are not all signed off will fail the audit workflow and cannot merge.
Translations and packages
For applications pulled from upstream, translations live with the package and
are updated when the package is updated. Package templates are the most
impactful contribution to the project, and each one lives under
packages/<tier>/<name>/ with two files:
package.yml— metadata: source URL, SHA256, dependencies, and build stylebuild.sh— the bash functionsconfigure(),build(),check(), anddo_install()
If a package’s upstream catalogs are out of date or missing a language, the right fix is usually upstream. Coordinate through an issue before changing how a package handles its own translations, so the build stays reproducible and the package stays close to its source.
The public-content audit
Every pull request to master is scanned by an automated public-content audit.
Translation contributions are no exception: keep host-specific paths, internal
file references, and credential-like strings out of message catalogs and commit
messages. If the audit flags a file, amend it and push again. Legitimate public
content that happens to match a flagged pattern can be added to the audit
allowlist.
What we value
The same standards that govern all contributions govern translations:
- Transparency — no hidden behavior, no surprising defaults.
- Simplicity over cleverness — if there is a simpler way to handle a string or a locale, use it.
- Tested changes — verify that text renders correctly before you submit.
These standards exist because the project’s purpose is a machine you understand, can modify, and can trust. In that posture, security is not first. It is only: translation work must never weaken the system’s integrity, and the audit and review gates apply to localized strings exactly as they apply to code.
See also
Community Notes (unverified tier)
This section holds the community-notes tier of the InterGenOS wiki. The pages here are written and maintained by the wider community rather than drawn directly from the project’s source tree, build system, or maintainer documentation. They are clearly labeled as a separate, lighter-bar tier so you always know which kind of content you are reading.
This tier still goes through review. “Lighter bar” does not mean “no bar.” It means the standard of proof is different from the verified documentation, and the distinction is made explicit on every page.
Two tiers, one wiki
InterGenOS documentation comes in two tiers:
-
Verified documentation — the rest of this wiki. These pages describe what the system actually does today, checked against the source tree, the build phases, package metadata, and the shipped behavior of the current build (version 1.0-dev, build id
v1.0-dev1). When a verified page makes a concrete claim, that claim is meant to be reproducible from the system itself. -
Community notes (this tier, unverified) — tips, walkthroughs, workarounds, hardware reports, and field experience contributed by users. These pages are useful and welcome, but they are not held to the same line-by-line ground-truth standard as the verified documentation, and they may describe a setup, version, or hardware combination that differs from yours.
The reason for the split is the project’s guiding principle: a machine you understand, can modify, and can trust. Trust depends on knowing where a statement came from. Mixing maintainer-verified facts with community experience under a single label would blur that line, so the two are kept apart and clearly marked.
What “unverified” means here
A page in this tier has been reviewed for accuracy, safety, and fit with the project’s goals, but it has not necessarily been verified against the source tree the way the core documentation is. In practice:
- The advice may be correct for the contributor’s setup and not for yours.
- A note may lag behind the current build. InterGenOS is in active development, and package counts, defaults, and behavior drift between builds.
- Commands, package names, and file paths in a community note should be treated as starting points to confirm, not as guaranteed-current reference. When in doubt, cross-check against the verified documentation and the system in front of you.
Security-relevant claims get extra scrutiny. Any community note that would weaken the security posture of the system, suggest disabling integrity protections, or work around a build failure by removing functionality is rejected, the same way such a change would be rejected in code.
What belongs in the community tier
Good candidates for a community note include:
- Hardware compatibility reports and field notes (what worked, what did not, on a specific machine).
- Step-by-step walkthroughs for tasks that sit on top of the verified documentation rather than replacing it.
- Configuration recipes and customizations that respect the system’s defaults and security chain.
- Troubleshooting experience and workarounds, clearly dated and scoped to a build or hardware combination.
Content that belongs in the verified documentation instead — because it
describes core system behavior — includes the build pipeline, the package manager
(pkm), the Forge installer, the signed Secure Boot chain, dm-verity integrity,
UKI signing, and the local AI assistant. If your note is really a correction or
addition to how one of those works, it should go through the standard contribution
path so it can be verified.
What does not belong here
- Anything that weakens the security posture of the system.
- Workarounds that disable a feature or drop a dependency to dodge a build failure, instead of fixing the root cause.
- Unverified source tarballs, missing or incorrect checksums, or instructions that fetch software from untrusted origins.
- Internal development artifacts: host-specific paths, machine names, or credential-like strings. All contributions to the public repository are scanned by an automated public-content audit, and the same standard applies to wiki notes.
Current system at a glance
So community notes are read in the right context, here is what the project ships today (version 1.0-dev):
- Desktop: GNOME 49 on Wayland. KDE/Plasma and switchable desktops are planned, not shipped. A community note that assumes a different desktop is describing a setup InterGenOS does not currently provide.
- Packages: the build is organized into six tiers (toolchain, core, base, desktop, ai, extra), on the order of 850 packages as of this writing. These counts drift between builds; derive the live number from the system rather than trusting a fixed figure in a note.
- AI: “InterGen” is a tiered, hardware-detected, offline-first local assistant built on Qwen models, with zero telemetry. “InterGen Sentinel” is a pluggable security scanner that defaults to Local-Rules plus Local-Qwen, with six opt-in cloud providers (Claude (Anthropic), Gemini (Google), Copilot (Microsoft), ChatGPT (OpenAI), Grok (xAI), DeepSeek). The cloud escalation path is called Phone-A-Friend (Frontier/Cloud Escalation) and is opt-in. A community note should never present any cloud provider as on-by-default.
How to contribute a note
Community notes follow the same project values as code contributions: research before writing, simplicity over cleverness, transparency with no hidden behavior, and only submitting what you can actually verify on your own machine. Contributions to the project are made under the GNU General Public License v3.0 or later, and code commits carry a Developer Certificate of Origin sign-off.
If you are not sure whether something belongs in the community tier or the verified documentation, open an issue and ask first.
See also
InterGenOS Artwork
The visual identity of InterGenOS is built around one idea: a single blue pulse
crossing a black field. It is an ECG trace — a heartbeat — rendered in
#0099FF on black, and it recurs everywhere from the app icon to the first-boot
animation. This page collects the project’s marks, wordmarks, and wallpapers in
one place.
Using these: the logo, icon, and wordmark are the InterGenOS project’s identity — please don’t alter them or use them to imply endorsement. The wallpapers are here for InterGenOS users to enjoy on their own machines.
Logo & Icon
The icon is the pulse on a rounded-square field; the logo stretches the same pulse into a horizontal lockup. Each ships in three variants — solid (black field), transparent, and white (for dark surfaces).
App icon — full
Variants: transparent · white
App icon — simple
Variant: transparent
Logo lockup
Variants: transparent · white
Alternate logo (perspective)

Wordmark
The wordmark sets the project name in the brand type, with and without the tagline.



The pulse-and-tagline lockup — the heartbeat crossing into the wordmark over “Security is not first. It is only” — shown across the brand’s surface treatments.





Wallpapers
The default desktop wallpaper plus the logo and pulse treatments and the concept set explored during the visual-identity work.
Default

Logo wallpaper

Pulse wallpaper

Hero

Concepts




Brand Elements
The pulse motif on its own, and the artwork that fronts the site’s 404 page.

