Skip to content

Permissions

Workers execute task code, so permission policy controls what those workers can access at runtime.

Set permission in createPool(...):

import { createPool, isMain, task } from "knitting";
export const work = task({
f: async (x: number) => x * 2,
});
if (isMain) {
using pool = createPool({
threads: 2,
permission: { mode: "strict" },
})({ work });
console.log(await pool.call.work(21)); // 42
}
  • omit permission strict defaults plus allowImport: true (web imports allowed).
  • permission: {} or permission: { mode: "strict" } conservative defaults in explicit strict mode.
  • permission: "unsafe" disables permission flags and strips inherited Node permission flags.

console can be set in object mode for compatibility. Default is false in strict mode and true in unsafe mode.

createPool({ permission: { mode: "strict", console: true } })({ work });
createPool({ permission: "unsafe" })({ work });

In object mode you grant exactly what your tasks need — anything you don’t list stays denied:

createPool({
permission: {
mode: "strict",
allowImport: true, // allow task-module imports
read: ["./data"], // path allow-list (or `true` for all)
write: ["./out"],
net: ["api.example.com"], // host allow-list (or `true` for all)
env: { allow: ["NODE_ENV"] },
run: ["git"], // subprocess allow-list
console: true,
},
})({ work });
FieldMeaning
read / writePath allow-lists. true means unrestricted.
denyRead / denyWriteExplicit deny entries layered on top.
net / denyNetNetwork host allow / deny lists.
allowImportModules the worker may import. true allows all.
env{ allow, deny, files } for environment-variable access.
run / denyRunSubprocess execution allow / deny lists.
consoleLet worker console.* reach the host.

Enforcement uses each runtime’s native mechanism, so coverage varies (see Runtime mapping). Treat permissions as a guardrail, not the only boundary for hostile code — for that, combine them with process workers.

Strict mode computes a conservative profile:

  • read/write rooted at current cwd
  • deny-write for node_modules
  • deny read/write for sensitive paths: .env, .git, .npmrc, .docker, .secrets, ~/.ssh, ~/.gnupg, ~/.aws, ~/.azure, ~/.config/gcloud, ~/.kube
  • deny read/write for POSIX-sensitive paths: /proc, /proc/self, /proc/self/environ, /proc/self/mem, /sys, /dev, /etc
  • read support for deno.lock and bun.lock*

permission: "unsafe" disables runtime permission flags and strips inherited Node permission flags from worker execArgv.

Permission protocol values are mapped to each runtime differently.

Workers receive --permission / --experimental-permission plus:

  • --allow-fs-read
  • --allow-fs-write
  • --allow-worker
  • --allow-child-process
  • --allow-addons
  • --allow-wasi

Node worker flags are allow-list based, so protocol deny lists are not expressible as Node worker flags.

Workers receive Worker.deno.permissions when enabled.

This is applied only when one of these is true:

  • --unstable-worker-options is detected (Linux /proc probe), or
  • KNITTING_DENO_WORKER_PERMISSIONS=1 is set.

Bun currently has no worker permission flags. Protocol values are accepted for API compatibility but are not enforced by Bun runtime flags.

Object mode supports runtime-specific process execution overrides:

  • node.allowChildProcess?: boolean
  • deno.allowRun?: boolean — legacy, superseded by the top-level run allow-list.

Both default to false in strict mode.