Skip to main content

Kernel backend

The kernel's Motoko module is the trusted core of the canister. It is the only component permitted to use the privileged compiler surface, and it is shaped like an app so that it can be installed like one.

Module shape

Like any app, the kernel exposes an Init class. Unlike ordinary apps, its manifest declares positional init_arg constructor resources: the kernel and activation memory roots, generated deployment id, active app-instance inventory, and the actor's own principal.

Its methods are annotated the same way app methods are, and the assembler generates its wrappers from the same template. The difference is what those methods are allowed to do inside.

Memory model

Kernel memory is a managed root like any other, subject to the same schema and migration rules. It holds:

  • the authorized principal set
  • the certified asset store and its index
  • package metadata and the app registry
  • the install journal and staged deployment state
  • capability registry entries, reservations, and broker state
  • per-installation usage telemetry
  • settings snapshots

Because it is managed memory with a declared owner, an app declaring a memory root named kernel is a level-4 disclosure: it is attempting to replace kernel memory.

Authorization storage

A flat set of principals. The generated wrapper's is_authorized check consults it before any ordinary app method runs.

The kernel's add method scrubs anonymous, because Motoko supplies anonymous for the actor-class installer binding during post_upgrade — without scrubbing, every upgrade would try to authorize the anonymous principal.

The current implementation does not distinguish the human owner from installer or technical authorities, and does not attach labels. Every entry is treated as one of the same owner's full-trust credentials. Settings presents the set separately from IC controllers and describes controllers as the stronger capability, since they can replace code, change settings, stop, or delete the canister.

The active browser principal cannot remove its own authorization, and the Neutron canister cannot remove itself as a controller.

Static asset storage

Assets are stored chunked, with content type and content encoding recorded per file. Uploads are performed one file operation — or one subsequent chunk for that file — per update call. The implementation never puts multiple files in one update.

Identical Motoko modules resolving to one content-addressed /mo/ path are reused; a conflicting body for that path fails. Mutable install targets are required to be unique within a deployment.

Reads go out over certified HTTP with a v2 certification expression. Actor initialization reconciles public v2 leaves for existing stored assets, so upgrading from an older build does not require re-uploading unchanged data.

See HTTP and assets.

Self-upgrade

For a module that fits the ingress envelope, kernel_install_code calls the management canister's install_code in #upgrade mode against the Neutron canister itself. Larger modules use the checked chunked path: kernel_install_wasm_chunk stages hash-bound chunks and kernel_install_code_chunked dispatches install_chunked_code with the exact ordered chunk hashes and full module hash.

This requires the canister to be a controller of itself. The provisioner establishes and verifies that during IC creation and local installation; the dispenser adds the created Neutron as its own controller during install.

These are ordinary wrapped methods, so they are protected by the same generated owner-authorization assert as everything else.

Install journal and activation

The journal is stable state recorded before the one-way upgrade. Its client request carries the target app inventory plus the exact asset copy and clear plan; the Kernel snapshots the committed inventory into the journal. The bounded obsolete-module list is a separate deployment-scoped staged asset that only the journal's verified commit consumes.

After activation, the kernel exposes kernel_runtime_info reporting deployment, assembler, and compiler ids plus per-app versions, capability-plan fingerprints, and memory schema hashes. Commit promotes staged metadata only when that matches.

Recovery resumes commit after a reload. A protected dispatch marker prevents aborting an upgrade that is merely queued, and a management-queue fence permits abort only after the old actor proves the dispatched installation is terminal.

Before commit, every non-kernel app scope stays inactive — a deliberate brief pause that prevents replacement code or new public ingress from running before the target registry and assets are committed.

See Install transaction.

Settings snapshot

The kernel exposes a settings snapshot and an app-usage snapshot that the frontend reads independently of the registry, so a slow read does not blank the whole page.

The usage snapshot carries separately typed instruction, execution, and outgoing cycle fields plus rolling 30-day buckets and a separately typed total of cycles accepted by paid public updates. Settings joins telemetry by exact app id and installation uid, and renders a low-side estimate labelled in TC.

A missing usage row renders as zero measured use for an active installation — not as a load failure.

Public API surface

Kernel methods fall into three groups:

GroupExamplesAccess
Owner-authorizedasset writes, kernel_install_code, runtime info, snapshots, static queriesGenerated authorization assert
Reviewed unauthorizedhttp_request, http_request_update, the authorization check itselfallow: "unauthorized" — kernel-only
Generated dispatchersapp public-ingress and POST handler wrappersBroker-enforced admission

kernel_static_query remains authorization-protected specifically to provide the bounded /mo/ key list the compiler needs. Module bodies are fetched over certified HTTP, which is why that query lists keys only.

http_request receives no injected authority arguments. http_request_update receives the real caller, so the backend can exempt kernel-authorized principals from external request windows without trusting request data.

Cycle accounting

The kernel reserves before it spends. Every outgoing broker call first reserves its gross explicit attachment and financial allowance. A single-use commit immediately before dispatch records the fixed call base; duplicate commit is rejected without another mutation, and a known pre-dispatch cancellation unwinds the reservation without that base. After dispatch, finalisation records the retained amount from the observed refund.

Instruction and execution totals use saturating Nat64; cycle totals use exact unbounded Nat at day, window, and lifetime scope.

note

Arithmetic exactness does not make the attribution billing-grade. It deliberately omits variable byte fees, response-callback bases, shared global-timer dispatch, storage, and compute allocation.