Skip to main content

Installing Plugins

Plugins are a mechanism to integrate additional containers running on the same device with SPR's API and UI. Many of the built-in containers are deployed as plugins, and third party plugins are fully supported.

Plugin isolation and API access

SPR provides separate isolation controls for a plugin's runtime, browser UI, and API access.

KVM isolation with krun

Plugins can run under KVM with the spr-krun runtime. Each KVM plugin runs with its own Linux kernel instead of sharing the host kernel like a standard container. This provides an additional isolation boundary for networking software, which frequently processes attacker-controlled traffic and may contain privilege-escalation or container-escape vulnerabilities.

A plugin selects this mode with "Runtime": "kvm". Plugins that support both modes can also provide standard Docker and KVM compose files, allowing SPR to offer the standard runtime when KVM support is unavailable.

Sandboxed plugin UIs

Plugin UIs run in a sandboxed iframe by default. A sandboxed UI does not receive the user's SPR credential or a general-purpose SPR API token.

When a user opens a sandboxed plugin, SPR creates a short-lived plugin session token. The token is valid only for that plugin's route, such as /plugins/spr-tor and its child paths. It cannot call other plugins, regular SPR API routes, token-management routes, or WebSockets. SPR issues the session only after authenticating the user, so the plugin route acts as an authenticated reverse proxy to the plugin's Unix socket.

The plugin backend does not receive the browser's bearer token; SPR removes it before forwarding the request over the Unix socket.

Backend access to the SPR API

If the plugin backend must call SPR API routes outside its own plugin route, it can request an install token with InstallTokenPath and ScopedPaths. Do not set InstallTokenPath when the backend does not use the SPR API. Scope install tokens to read-only access with :r wherever possible, and use :rw only for routes the plugin must modify.

Legacy unsandboxed UIs

Legacy plugins can explicitly set "SandboxedUI": false. This removes the iframe sandbox and allows the plugin UI to use the signed-in user's direct SPR API access. SPR warns the user before opening an unsandboxed UI. Use this compatibility mode only for trusted legacy plugins; new plugins should remain sandboxed.

Community Plugins

See the plugin catalog

Plugin Installation

A plugin can be enabled by navigating to the Plugins page and selecting Add Plugin.

extensions-plugin

Name: this is the plugin name

URI: This is used when the plugin extends the SPR API with additional API calls.

  • Ex: specifying nexmon means that the API calls the plugin adds will be reachable under http://spr/plugins/nexmon

UNIX Path: This is the API's path to the unix socket the plugin provides

  • Ex: /state/plugins/nexmon/socket

ComposeFilePath: This is the relative path to the docker compose path, so SPR auto-starts the plugin

  • Ex: plugins/spr-nexmon/docker-compose.yml
  • The SPR UI adds this path to configs/base/custom_compose_paths.json automatically. When configuring a plugin manually from the command line, add the path to that file yourself.

Runtime: Set to kvm to run the plugin with spr-krun and its own Linux kernel, or default for the standard container runtime.

HasUI: Set to true when the plugin publishes a web UI.

SandboxedUI: Plugin UIs are sandboxed by default. Set this explicitly to false only for a trusted legacy UI that requires direct access as the signed-in user.

InstallTokenPath: Optional path under /configs/plugins/ where SPR writes a backend API token during installation. Omit this when the plugin backend does not call the SPR API.

ScopedPaths: API routes allowed for the install token. Append :r for read-only access or :rw for read/write access.

Auto-starting a plugin

SPR permits plugins to start only from compose paths listed in configs/base/custom_compose_paths.json. The Plugins UI manages this list automatically during installation. If you configure a plugin manually from the command line or edit configs/base/api.json directly, you must also add its compose path to:

configs/base/custom_compose_paths.json

  • Example
    ["plugins/spr-nexmon/docker-compose.yml", "plugins/test/docker-compose.yml"]