Skip to content

0002 – Two plugin runtimes: in process and sandbox container

Status: accepted

Plugins range from device drivers with real-time audio (must be fast and closely integrated) to foreign code or code generated by the assistant itself (must not be able to do anything unexpected).

  • builtin/trusted plugins run in the core process, but only through a permission-checked PluginContext.
  • untrusted plugins (all uploaded and all generated ones) run in the sandbox container: own internal network without internet and LAN, read-only, cap_drop: ALL, own UID, rlimits per plugin process. Access to core functions only through a gateway with a plugin-bound token that checks every operation against the granted permissions. HTTP is executed by the core (allowlist, no private targets).
  • Certain permissions (devices.provide, devices.control, ai.provide, network.lan, …) are always excluded for untrusted plugins.
  • Untrusted plugins may register event types in their namespace and run background jobs (at least 60 s apart, at most 5); both are announced to the core, which registers the event types in its catalog.
  • Everything in process with Python sandboxing (RestrictedPython or similar): cannot be secured reliably in Python.
  • One container per plugin: stronger isolation, but the core would need Docker socket access (itself a security risk) and a lot of resources.
  • WebAssembly: the Python ecosystem in WASM is still limited.
  • Untrusted plugins cannot be device drivers or AI providers.
  • Plugins share the sandbox container; rlimits and separate processes limit mutual interference but do not replace a VM (SECURITY.md).