Skip to main content

The kernel

The kernel is two things at once, and holding both in mind explains most of Neutron's structure.

It is the core an operating system is built on. It owns identity, the authorization set, certified asset storage, HTTP serving, the capability brokers, the install journal, self-upgrade, and the entire browser shell. The kernel package and the compiler-generated actor and wrapper form the trusted Motoko surface; ordinary app source is not permitted to use it.

It is also just a package. Its manifest is neutron.json. Its frontend assets are packed under web/. Its backend is a Motoko module. It is installed through the same install transaction as any app. It appears in the app registry, but as the special non-launchable root entry rather than an ordinary app row.

Why that matters

Because the kernel is a package, a package whose manifest id is kernel is a kernel replacement. Installing one replaces the root web assets, the root package metadata, and the kernel module in the next combined actor compile.

Anyone can author one. This is intentional: forking the kernel, changing its rules or UI, and installing that fork into your own canister is a supported action. A distro is exactly this — a kernel, whether the stock one or a fork, plus the apps, assets, and runtime configuration seeded on top of it. The protection is not a closed distribution channel — it is that the install is explicit, requires owner authorization, and is disclosed at the highest severity level the permission display has.

The consequence for security review is direct: a kernel package is evaluated as an operating-system replacement request, not as an app that ordinary app rules should confine. The static Motoko policy still computes findings for kernel modules, but permits them, because kernel code legitimately needs actor construction, cycles, timers, raw stable memory, and certification.

What the kernel backend owns

AreaResponsibility
AuthorizationThe principal set, add/remove, and the is_authorized check the generated wrapper calls
AssetsChunked certified static storage and the HTTP read path
HTTPRequest admission, response certification, app-scoped routes, POST update handlers
UpgradeInline kernel_install_code or the chunked-Wasm variant, both calling the management canister in #upgrade mode against itself
JournalStaged install state, activation verification, atomic commit, and recovery
BrokersOutbound calls, randomness, HTTPS outcalls, chain-key signing, stable store, vetKeys, certified assets
Registry/system/apps.json and the capability plan projection Settings reads
TelemetryPer-installation instruction and cycle accounting

See Kernel backend runtime for detail.

What the kernel frontend owns

The shell is a tiling workspace manager, in the spirit of a keyboard-driven window manager: up to 20 sequential workspaces, a binary split-tree layout, drag-to-resize and drag-to-move, and a launcher.

It also owns everything trusted that an app must never be able to imitate:

  • Internet Identity login and the authorization screen
  • Install review dialogs and their permission disclosure
  • Canister-call consent dialogs
  • Cross-app tool request dialogs
  • The app tray — buttons, badges, popover chrome, placement, close behaviour
  • Full-page Settings, including capability toggles and access/recovery controls

App code cannot render into any of those surfaces. It can only occupy an iframe. The design system explicitly forbids apps from imitating kernel approval, install, authorization, or signature dialogs.

See Kernel frontend runtime for detail.

The kernel's manifest privileges

Several manifest resources exist only for the kernel:

  • init_arg — positional constructor resources. An ordinary app manifest containing this field is rejected outright.
  • Function argument this — the actual Neutron actor reference used by reviewed management and self-call paths. Ordinary apps may request the immutable canister_principal scalar, but never the actor value.
  • allow: "unauthorized" — omitting the owner-authorization assert on a method. Reserved for reviewed whole-canister entrypoints such as HTTP handling and the authorization check itself. Ordinary apps are rejected and must use the brokered public ingress path instead.

Ordinary apps may declare the public vetkeys capability and select its backend.capabilities.vetkeys_public interface; the compiler injects only that attenuated public-information handle, not raw threshold authority. Apps cannot inject raw module references or the Neutron actor, or reach NeutronKernel from generated code. Guessing a compiler-local name does not add it to the structural environment an app receives.