Architecture Note: Mattermost Plugin Framework Design and Isolation
An architecture note covering Mattermost’s plugin framework: requirements, minimal design, trust boundaries, operational checks, failure modes, and factors that would alter the design.
12 Feb 2026, 04:11 UTC

Requirements
Mattermost must allow third‑party developers to extend the server with slash commands, custom UI components, and background jobs without touching core code. The extension mechanism needs to keep the server stable, isolate plugins from each other and from the host, and provide a clear lifecycle for loading, unloading, and updating plugins.
Smallest Suitable Design
The current design uses a Go‑based plugin API. Each plugin is compiled as a shared object (.so) and placed in a directory configured via PluginsDirectory in config.json. At startup the Mattermost server spawns a separate process for each plugin and communicates through a gRPC broker over a Unix socket located under the plugin’s working directory (e.g., /opt/mattermost/data/plugins//plugin.socket). The plugin process is limited by OS‑level capabilities, seccomp filters, and cgroups.
Example configuration
{
"PluginsDirectory": "/opt/mattermost/data/plugins",
"EnablePlugins": true,
"PluginStates": {
"com.example.slashcommand": {
"Enable": true
}
}
}
After placing the compiled plugin in /opt/mattermost/data/plugins/com.example.slashcommand and restarting the server, the plugin registers its slash command via the gRPC API.
Trust and Data Boundaries
- Each plugin runs in its own process with a distinct UID/GID (same as the Mattermost server unless additional sandboxing is applied).
- File system view: read‑only access to the plugin’s asset directory, write‑only access to a dedicated data directory (
data/plugins/). No direct access to the Mattermost database or other plugins’ memory. - All inter‑process communication is mediated by the server’s gRPC broker; each connection is authenticated with a short‑lived token issued at plugin start.
- Network access is blocked by default; plugins can only make outbound calls if the administrator explicitly adds allowed endpoints via the plugin manifest.
Operational Checks
- Health endpoint (
/api/v4/plugins/health) reports the status (running, crashed, missing) of each loaded plugin. - The server monitors plugin processes and automatically restarts them on crash.
- Resource limits are enforced through cgroups: memory and CPU quotas are set in the plugin’s service unit (or via
systemd-run) and can be inspected withcat /sys/fs/cgroup/mattermost/plugins//memory.max. - Audit logs (
audit.log) contain entries for plugin load, unload, start, stop, and any denied system calls.
Verification example
To confirm isolation, run:
# Find the plugin process PID
ps -eo pid,user,cmd | grep mattermost-plugin-\
# Check its cgroup
cat /proc/$(pgrep -f mattermost-plugin-)/cgroup
# Verify limited filesystem view
nsenter --mount --target $(pgrep -f mattermost-plugin-) mount | grep "data/plugins"
If the output shows the plugin’s data directory mounted read‑write and no other Mattermost paths, the sandbox is active.
Failure Modes
- Plugin panic: the plugin process exits; the core server continues serving WebSocket connections because the plugin runs in a separate process.
- Resource exhaustion: a misbehaving plugin consumes CPU or memory; cgroup throttling limits the impact, and the server health API flags high usage.
- Privilege escalation attempt: blocked by seccomp profiles and capabilities; any denied syscall appears in the audit log with
permission denied.
Conditions That Would Change the Design
- Adopting a language‑agnostic model (e.g., WebAssembly) would replace the gRPC/Unix‑socket bridge with a WASM runtime embedded in the server.
- Regulatory pressure for stricter data isolation could require encrypted per‑plugin volumes, moving plugin state outside the shared data directory.
- A shift to a fully serverless deployment would move plugin execution to a FaaS platform, eliminating the need for local plugin processes and changing the trust boundary to the cloud provider’s isolation mechanisms.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.