# Plugin SDK tool policy and sandbox helpers

> toolPolicy matchers, tool-group expansion, and splitSandboxBindSpec

- 网址：https://funcoding.ai/agents/openclaw/plugins/sdk-entrypoints/tool-policy-and-sandbox/
- 来源：OpenClaw 官方文档原文（英文），MIT 许可，同步于 2026-10-11
- 官方原文：https://docs.openclaw.ai/zh-CN/plugins/sdk-entrypoints/tool-policy-and-sandbox

---
The synchronous policy and sandbox parsing primitives that
`openclaw/plugin-sdk/agent-harness-runtime` exposes to plugins. Part of the
[Plugin entry points](https://funcoding.ai/agents/openclaw/plugins/sdk-entrypoints/) reference.

## Tool policy vocabulary

`openclaw/plugin-sdk/agent-harness-runtime` exposes core's synchronous policy
primitives through `toolPolicy`:

- `toolPolicy.expandToolGroups(list?)` normalizes tool aliases, drops blank entries, expands
  core groups, and returns unique tool ids in first-seen order. Members of each
  expanded group follow that group's catalog order.
- `toolPolicy.createToolPolicyMatcher(policy?, writeAllowsApplyPatch = true)` returns a
  matcher for tool names. Deny entries win, an empty allow list is unrestricted,
  and `*` patterns and aliases use core normalization. Set the second argument
  to `false` to disable the runtime compatibility where allowing `write` also
  allows `apply_patch`.

For conformance coverage, negate a matcher built with `{ deny: entries }`;
this keeps an empty coverage list false and avoids allow-side compatibility.
Prepare matchers for one synchronous operation; do not retain an authorization
decision across awaited work.

## Runtime tool allowlists

`applyEmbeddedAttemptToolsAllow(tools, toolsAllow?, options?)` filters concrete
runtime tools using the shared aliases, groups, and wildcard matching. An
undefined allowlist keeps all tools; an explicit empty list disables them.
Independent restrictions must each permit a tool.

Use `options.toolMeta(tool)` to supply its owning `pluginId` for plugin-group
matching. A harness that exposes a tool under another name can supply
`options.toolAliases(tool)` with its accepted policy aliases. Each restriction
can match the original name or an alias; the result retains the original tool
objects and their execution wrappers.

## Sandbox bind parsing

`openclaw/plugin-sdk/agent-harness-runtime` exports
`splitSandboxBindSpec(spec, options?)`. It returns raw `{ host, container, options }`
segments, or `null` when no host/container separator exists. Windows host drive
prefixes are always preserved. Pass `{ allowWindowsContainerPath: true }` to
preserve drive prefixes in container paths too, as Policy does for its existing
Windows bind grammar. The default keeps POSIX container parsing unchanged.
This helper splits text; it does not validate or authorize a mount.

## Sandbox filesystem mappings

`SandboxContext`, exported by `openclaw/plugin-sdk/agent-harness-runtime`, exposes
its filesystem bridge through `fsBridge`. That bridge accepts optional readonly
`pathMappings`: `{ hostRoot, containerRoot }` pairs from the backend's prepared
mounts. Include workspace, agent-workspace, and protected-resource projections.
The container root declares the path syntax: POSIX roots retain literal
backslashes; Windows drive and UNC roots use Windows containment and preserve
filename case. The deepest matching root wins; equal roots use the supplied
order.

Workspace-only file tools use these mappings for admission. Bridge operations
still enforce physical boundaries, mount visibility, and read-only policy.
A supplied empty list admits no paths, and an unmatched path never falls back
to host-root admission. Older external bridges that omit the property retain
the host-root compatibility exposed in v2026.9.4. New implementations should
supply the mappings; removal of that compatibility requires a breaking SDK
contract that makes the property required.

Host-backed bridges can additionally expose `resolveReadPolicyPath()` to map
an existing read target into that caller-facing mount namespace. When present,
`readFile()` and `stat()` must reject an `expectedPolicyPath` that no longer
names their final opened target. This keeps
the bridge, not its caller, responsible for physical alias resolution.
Expected-policy metadata comes from the admitted descriptor; bridges can keep
their existing pathname metadata behavior when this optional contract is unused.

## Directory listing metadata

`SandboxContext.fsBridge.readDirectory` returns directory entry records. Providers
may include `isFile`, `size`, and `mtimeMs`
from their no-follow directory listing. File browsers use this metadata without
an additional stat request for each child; providers that omit any of these fields
use the stat-based path. Unknown file types are never inferred from `isDirectory`. `isFile: false` with `isDirectory: false` identifies
an entry such as a symlink that the browser should not treat as a regular file.
Listing metadata never grants permission to read an entry. File reads continue
to enforce the provider's path policy, byte limits, and active workspace binding.

Paired nodes that supply file types avoid per-entry stat requests. With older
nodes, the browser skips entries whose stat explicitly rejects a symlink or
unsupported file type. Permission, transport, and workspace-lifetime errors still
fail the request. A structured `FILE_TOO_LARGE` refusal during a read is reported
as the preview limit, including when the file grew after stat.

Session file requests retain their existing live read authorization before each
workspace operation and before returning a response. Revocation stops subsequent
workspace operations; it cannot retract an operation already dispatched.
