Plugin Security Model
Mostly Modular’s approach to mod/plugin security. Honest about what we guarantee,
honest about what we can’t.
>
See also: [MOD-CURATION.md](./MOD-CURATION.md) for trust tiers, [DISTRIBUTION.md](./DISTRIBUTION.md) for marketplace.
Design Principle
The sandbox is structural, not behavioral.
Most modding systems rely on trust: “we hope modders don’t do bad things.” MM’s
WASM sandbox doesn’t rely on hope — it physically removes capabilities from the
guest environment. A plugin can’t access the filesystem because no filesystem API
exists in its sandbox. There’s no lock to pick because there’s no door.
That said: no security model is perfect. We document what we protect against,
what we mitigate, and what remains the user’s responsibility.
What WASM Sandboxing Prevents
These are structural guarantees enforced by the wasmtime runtime at the CPU level.
A plugin author cannot work around them regardless of language, cleverness, or intent.
| Threat | Status | Why |
|——–|——–|—–|
| Filesystem access (read or write) | Prevented | No filesystem APIs in sandbox. No WASI FS capability granted below Tier 2. |
| Network access (HTTP, sockets, DNS) | Prevented | No network APIs in sandbox. No WASI net capability granted below Tier 1. |
| OS API calls (registry, processes, services) | Prevented | WASM has no FFI to native code. |
| Access other plugins’ memory | Prevented | Each WASM instance has its own linear memory. Hardware-isolated. |
| Execute arbitrary native code | Prevented | WASM is a bytecode VM. Cannot JIT or exec native instructions. |
| Keylogging / input capture at OS level | Prevented | No access to OS input APIs. Plugin receives only events the kernel explicitly sends. |
| Crypto mining / background computation | Prevented | CPU budget enforced per frame. Kernel kills plugins exceeding cpu_ms_per_frame. |
What We Mitigate (Reduced Risk, Not Eliminated)
| Threat | Mitigation | Residual Risk |
|——–|———–|—————|
| Resource exhaustion (RAM) | memory_mb budget per trust tier. Kernel terminates plugins exceeding allocation. | A plugin at its budget limit may still cause frame drops. |
| Resource exhaustion (CPU) | cpu_ms_per_frame budget. Kernel measures and enforces. | Measurement granularity — plugin could spike briefly between checks. |
| Event bus data observation | Plugins only receive events they declared in manifest (events.consumes). Tier 3+ restricted to declared_only. | A plugin that legitimately subscribes to an event sees all its data. Game developers should avoid putting sensitive data in broadly-consumed events. |
| Malicious updates to trusted plugins | Automated scanning on every publish. Behavioral diff flagged if capabilities change between versions. | Sophisticated attacks that stay within declared capabilities may pass automated scanning. Community reporting is the backstop. |
| Social engineering via in-game UI | UI capability restricted by tier. Tier 5 has no UI access. Tier 3-4 limited. | A plugin with UI permission could display misleading content. This is a moderation problem, not a sandbox problem. |
What Remains the User’s Responsibility
| Risk | Our Position |
|——|————-|
| Choosing to sideload (Tier 5) unvetted WASM | We warn clearly. Sandbox still protects, but no scanning was performed. |
| Granting elevated trust to a plugin | Tier promotion requires action. We document what each tier allows. |
| Game developer exposing sensitive host functions | See “Host Function Audit” below — this is on game devs AND on us for engine-level functions. |
The Host Function Attack Surface
This is our most important ongoing security responsibility.
WASM plugins can only interact with the outside world through host functions —
functions the kernel explicitly exposes to the plugin sandbox. Every host function
is a potential security boundary.
Current Host Functions (Kernel)
Each function listed with its security implications:
| Function | Purpose | Risk Level | Rate-Limited | Notes |
|———-|———|———–|————-|——-|
| kernel_log | Plugin writes to debug log (with prefix) | Low | ✅ 1000/frame | Could spam logs. Silent drop after limit. |
| kernel_print | Plugin writes clean output to stdout | Low | ✅ 1000/frame | Interactive text games use this. Same policy as kernel_log. |
| kernel_read_line | Plugin reads one line from stdin | Medium | ❌ | Blocks kernel thread. Sideloaded plugins trigger security warning. |
| kernel_random | Returns random integer in [min, max] | None | ❌ | Pure function. No side effects. |
| event_register | Register a new event kind by name | Low | ❌ | Could pollute registry but no security boundary crossed. |
| event_subscribe | Subscribe to an event kind | Medium | ❌ | DeclaredOnly enforced for Tier 3+ by Vogon Customs. |
| event_emit | Emit an event to all subscribers | Medium | ❌ | DeclaredOnly enforced for Tier 3+. CPU budget is rate-limiting mechanism. |
| kernel_theme_get | Synchronous theme string lookup (Babel Fish) | Low | ❌ | Read-only. No secrets should be in theme store. |
| kernel_action_pressed | Synchronous input action poll (Babel Map) | Low | ❌ | Read-only. Does not expose OS-level input. |
Host Function Rules
Game Developer Host Functions
Game developers can expose their own host functions to plugins. We provide guidelines:
Periodic Security Audits
“We’re the ones writing the host functions — we’re our own biggest attack surface.”
Quarterly Self-Audit Checklist
Audit Log
| Date | Auditor | Findings | Actions |
|——|———|———-|———|
| 2026-03-21 | Ada (autonomous) | All 9 host functions cataloged in VogonAuditBureau. kernel_log/kernel_print rate-limited. Sideloaded stdin warns. No High-risk functions found. event_emit/subscribe are Medium — Vogon Customs (DeclaredOnly) already mitigates. | Rate limiting implemented. /api/security/audit route added. Audit checklist baseline established. |
Messaging Guidelines
When communicating MM’s security to users, developers, or press:
Do Say
Don’t Say
The Honest Pitch
*”Mostly Modular uses WebAssembly sandboxing to structurally prevent entire classes
of mod security threats — like filesystem access, network exfiltration, and keylogging —
that other engines can’t protect against. Combined with tiered trust levels and
automated scanning, it’s the strongest mod security model in game engines today.
No security system is perfect, which is why we also conduct regular audits and
maintain a community reporting pipeline.”*
*Planned for: Implementation alongside Spikes 9 (Milliways) and 11 (Steam Workshop).
Audit process begins when host function API stabilizes (post-Spike 6).*
