Use Cases
Plugin Systems
Run user-authored plugins in isolation with per-plugin permissions and timeouts using Secure Exec.
Plugins, user scripts, formulas, and webhooks-as-code all share one problem: the author is not you. Secure Exec lets each one run with exactly the access you decide, and no way to affect the others.
Declare what a plugin gets
// Plugins are user-authored source you do not trust. Each one declares what it
// needs, and you decide what it gets.
interface Plugin {
name: string;
source: string;
network: boolean;
}
const plugins: Plugin[] = [
{
name: "shout",
source: `(() => inputs.text.toUpperCase())()`,
network: false,
},
{
name: "spin",
source: `(() => { while (true) {} })()`,
network: false,
},
];
Run each plugin in its own VM
// Every plugin runs in its own VM, so plugins cannot see each other's state, and
// a plugin that hangs or crashes only fails its own call.
for (const plugin of plugins) {
const result = await evaluate<string>(plugin.source, {
inputs: { text: "hello" },
permissions: { network: plugin.network ? "allow" : "deny" },
timeoutMs: 1_000,
});
console.log(
plugin.name,
result.outcome === "succeeded" ? result.value : result.outcome,
);
}
// shout HELLO
// spin timed_out
- No shared state. Each call is a fresh VM, so one plugin cannot read or corrupt another’s data.
- Failures stay contained. A plugin that hangs returns
timed_out. A plugin that throws returnsfailed. Your process keeps running. - Per-plugin policy.
permissions,limits, andmountsare set per call, so a trusted plugin can have the network while the rest cannot.
Giving plugins files and packages
Mount read-only data or a shared node_modules with
mounts. For plugins that keep state across
invocations, give each plugin its own VM.