Secure Process Execution
Use services.process.run() to run an operator-approved local program from a step. It is useful for tests, build tools, database utilities, and infrastructure commands. Process execution is disabled until an operator grants it.
Run a supervised command
Place this step inside a workflow's <steps>:
<step id="runTests" name="Run project tests">
<script>
const result = await services.process.run({
executable: "bun",
args: ["test"],
cwd: ".",
timeout: "5m",
output: { stdout: "capture", stderr: "capture", maxBytes: 65536 }
}, { name: "project-tests" });
return { passed: result.exitCode === 0 };
</script>
</step>executable is a policy alias, not an arbitrary path. Arguments are literal strings; WOML does not invoke a shell. A non-accepted exit code fails the step. Avoid returning captured output unless another step needs it, because step results become durable context.
Grant only the needed authority
For a reviewed foreground test, use a temporary alias grant:
woml test workflow.woml --allow-process bunFor background or production operation, use an operator-owned Process Policy:
woml run workflows/ --process-policy ./process-policy.json --backgroundThe policy pins aliases to executables and bounds working directories, environment names, concurrency, time, and output. A workflow cannot enlarge those limits. Keep the executable and policy files outside the workflow author's control.
Failure and recovery boundary
WOML cancels or times out the contained process tree and stores bounded outcome metadata. It cannot prove an interrupted external command had no side effect. If the result is uncertain, recovery fails closed rather than replaying blindly.