Skip to main content

Security

Neutron installs third-party code into a canister you own, and that code is not separated from other apps by a canister boundary. The security model therefore has to be constructed, and it is worth understanding exactly what constructs it.

PageCovers
Security modelThe threat model, the four mechanisms, and what is not claimed
Static checksWhich Motoko APIs are blocked, why, and which aliasing forms the analysis covers
CapabilitiesThe declared/derived capability inventory and which entries reach runtime brokers
Frame isolationOpaque origins, credentialless iframes, private ports, and dedicated origins
ConsentInstall disclosure, call approval, grants, and revocation

The four mechanisms, in one place

Since apps share one actor, isolation comes from:

  1. Generated wrappers and manifest validation. Ordinary app methods are compiler-generated and scoped to the installed app. Their owner-facing wrappers assert that the caller is in the kernel's authorization set. Compiler-generated public-ingress dispatchers are intentionally public and instead apply their declared route policy; a cycles-aware ingress handler has no ordinary wrapper.
  2. Static Motoko analysis. The reviewed dangerous acquisitions are rejected in final package modules and again across modules reachable at compile time.
  3. Capability plans and brokers. A canonical plan records declared and compiler-derived authority for install disclosure. Brokered resources add typed policy, quotas, installation scope, and—where projected into the runtime registry—live disable/revoke checks. Structural and browser-only plan entries are not all runtime switches.
  4. Browser frame isolation. Tiles, trays, and ordinary backgrounds use opaque, credentialless sandboxed frames. A background can instead receive a disclosed dedicated-origin mode. Operational kernel RPC uses a private MessagePort; window messaging only bootstraps that port.

Reading these pages honestly

The source documentation this site is derived from deliberately separates implementation facts from inferred design intent, and it names its own gaps. That convention is preserved here.

These pages distinguish checks visible in the reviewed source from design goals and deployment assumptions. That distinction is important: a static denylist is not a proof that every future language feature is confined, a registry flag is not hardware attestation by the canister, and a UI disclosure is not an authorization check unless the broker also enforces it. Boundaries that are not claimed—the browser, an active controller, a kernel replacement, and replica-visible plaintext—are limits to design around.