Skip to main content
OpenClaw uses @openclaw/fs-safe for security-sensitive local file operations: root-bounded reads/writes, atomic replacement, archive extraction, temp workspaces, JSON state, and secret-file handling. It is a library guardrail for trusted OpenClaw code that receives untrusted path names, not a sandbox. Host filesystem permissions, OS users, containers, and the agent/tool policy still define the real blast radius.

Default: JavaScript fallback

OpenClaw sets fs-safe’s optional native helper to off by default:
  • native platform packages are optional and may be absent from minimal installs;
  • the guarded JavaScript paths support OpenClaw’s normal filesystem operations;
  • disabling native loading keeps runtime behavior deterministic across desktop, Docker, CI, and bundled-app environments.
OpenClaw only changes the default. An explicit setting always wins:
The generic fs-safe environment name also works: FS_SAFE_NATIVE_MODE. fs-safe 0.5 temporarily maps the retired FS_SAFE_PYTHON_MODE and OPENCLAW_FS_SAFE_PYTHON_MODE values to native modes and emits a deprecation warning. Migrate those names before fs-safe 0.6; Python interpreter path settings are no longer used. Use require (not auto) when native primitives are part of your security posture. auto uses the guarded JavaScript implementation when the platform binding is unavailable.

What stays protected without native acceleration

With the helper off, OpenClaw still gets fs-safe’s Node-only guardrails:
  • rejects relative-path escapes (..), absolute paths, and path separators where only bare names are allowed;
  • resolves operations through a trusted root handle instead of ad-hoc path.resolve(...).startsWith(...) checks;
  • refuses symlink and hardlink patterns on APIs that require that policy;
  • opens files with identity checks where the API returns or consumes file contents;
  • writes state/config files via atomic sibling-temp + rename;
  • enforces byte limits for reads and archive extraction;
  • applies private file modes for secrets and state files where the API requires them.
This covers OpenClaw’s normal threat model: trusted gateway code handling untrusted model/plugin/channel path input inside a single trusted operator boundary.

What native acceleration adds

The optional platform package provides policy-free filesystem primitives used by fs-safe for create-only writes, guarded hard-link publication, asynchronous sidecar creation, and explicit no-replace rename publication. Linux uses openat2 and renameat2; macOS uses descriptor-relative component checks and renameatx_np; Windows uses handle-relative operations and replacement-disabled rename. The TypeScript layer still owns policy, validation, retries, cleanup, and fallback decisions. Native support narrows filesystem race windows; it does not turn fs-safe into a sandbox. If your deployment requires those native primitives, install the matching optional platform package and set:

Plugin and core guidance

  • Plugin-facing file access should go through openclaw/plugin-sdk/* helpers, not raw fs, when a path comes from a message, model output, config, or plugin input.
  • Core code should use the fs-safe wrappers under src/infra/* so OpenClaw’s process policy applies consistently.
  • Archive extraction should use the fs-safe archive helpers with explicit size, entry-count, link, and destination limits.
  • Secrets should use OpenClaw secret helpers or fs-safe secret/private-state helpers; do not hand-roll mode checks around fs.writeFile.
  • For hostile local-user isolation, do not rely on fs-safe alone. Run separate gateways under separate OS users/hosts, or use sandboxing.
Related: Security, Sandboxing, Exec approvals, Secrets.