@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.
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.
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 usesopenat2 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 rawfs, 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.