← Back to Plugins
Tools

Fence

Use-Tusk By Use-Tusk 👁 76 views ▲ 0 votes

Fence plugin for OpenClaw

GitHub

Install

openclaw plugins install @use-tusk/openclaw-fence

Configuration Example

{
  "plugins": {
    "entries": {
      "openclaw-fence": {
        "enabled": true,
        "config": {
          "template": "openclaw"
        }
      }
    }
  }
}

README

# Fence Sandbox Plugin for OpenClaw

OpenClaw plugin that routes coding-agent tool calls (`exec`/`bash`, `write`, `edit`, `apply_patch`, `web_fetch`) through [Fence](https://github.com/Use-Tusk/fence) for command, filesystem, and network policy enforcement.

Fence is a lightweight, container-free process sandbox. This plugin makes Fence's policy engine apply to every tool call OpenClaw's agents issue, in addition to (or instead of) running the OpenClaw gateway under a wrap-mode `fence` sandbox.

## What it does

For every `before_tool_call` event for one of these tools, the plugin asks Fence to evaluate the call against your active config:

| OpenClaw tool | Fence policy domain | Reads |
|---|---|---|
| `exec` (alias `bash`) | `command.deny` / `command.allow` | `params.command` |
| `write`, `edit`, `apply_patch` | `filesystem.allowWrite` / `denyWrite` (+ dangerous-files) | `params.path` |
| `web_fetch` | `network.allowedDomains` / `deniedDomains` | `params.url` |

Two outcomes:

- **Deny**: the plugin returns `{ block: true, blockReason }`; OpenClaw surfaces the reason in the UI and the tool does not run.
- **Allow**: the plugin returns nothing and the tool runs normally.

Tools outside this table (`gateway`, `sessions_*`, `image_*`, `media_*`, channel sends, MCP, and so on) are passed through unchanged. Run OpenClaw under wrap-mode Fence (`fence -t openclaw -- openclaw gateway run`) if you want network/filesystem policy applied to those surfaces too.

## Why use this

Fence's command policy is enforced at two points:

1. **Preflight:** once, on whatever command is given to `fence` (e.g. `fence -- openclaw` only preflights `openclaw`).
2. **Runtime exec:** at the kernel exec boundary, against descendant processes.

Runtime exec on macOS, and Linux without `runtimeExecPolicy: "argv"`, only handles single-token denies (e.g. `sudo`). Multi-token rules like `gh repo create`, `git push`, and `npm publish` are preflight-only, so when OpenClaw's coding agent spawns one of those after Fence has already preflighted `openclaw`, the deny rule does not fire.

This plugin closes that gap by re-running preflight on every tool invocation OpenClaw's agent issues, before the call runs. See Fence's [Enforcement Across Child Processes](https://github.com/Use-Tusk/fence/blob/main/docs/configuration.md#enforcement-across-child-processes) for the full model.

## Installation

### Prerequisite

Install [Fence](https://github.com/Use-Tusk/fence) and confirm it's on your `PATH`:

```bash
fence --version
```

You need Fence v0.2.x or later for the `--openclaw-pre-tool-use` subcommand the plugin spawns.

### Install the plugin

OpenClaw uses an imperative plugin manager, so there is no Fence-side install command for OpenClaw. Run OpenClaw's own install:

```bash
openclaw plugins install @use-tusk/openclaw-fence
openclaw gateway restart
```

OpenClaw fetches the package, validates the manifest, and registers the `before_tool_call` handler on next gateway start.

### Recommended Fence config

Use the bundled `openclaw` template as a starting point:

```bash
fence config show --template openclaw
```

It extends Fence's `code` template with OpenClaw-specific writable directories (`~/.openclaw/**`) and channel/provider domains. Save a project copy or pin it via plugin options below.

## Configuration

Plugin options are read from `plugins.entries.openclaw-fence.config` in your OpenClaw config file:

```jsonc
{
  "plugins": {
    "entries": {
      "openclaw-fence": {
        "enabled": true,
        "config": {
          "template": "openclaw"
        }
      }
    }
  }
}
```

| Option | Type | Default | Description |
|---|---|---|---|
| `fenceBinary` | string | `"fence"` | Path to the fence executable. |
| `settingsPath` | string | (auto-discovered) | Pin a specific Fence settings file. Mutually exclusive with `template`. |
| `template` | string | (auto-discovered) | Pin a Fence built-in template (e.g. `"openclaw"`, `"code"`). Mutually exclusive with `settingsPath`. |
| `failOpenOnRunnerError` | boolean | `false` | If true, allow the tool when fence cannot be invoked. **Local development only** - silent fail-open turns the policy into a no-op. |
| `priority` | number | `0` | Hook priority. Higher runs first. Use e.g. `100` if Fence's policy must win over other plugins' decisions. |

### Composing with whole-agent wrapping

You can (and should) run OpenClaw itself under Fence:

```bash
fence -t openclaw -- openclaw gateway run
```

…and additionally enable this plugin. Wrap mode handles filesystem and network policy at the OS layer for *all* OpenClaw tools (channel sends, MCP, browser, etc., not just the five this plugin checks). The plugin handles multi-token command denies on platforms where Fence's runtime exec deny can't.

## Limitations

### Hook scope is intent-time, not traffic-time

This plugin sees what the agent declared it wants to do (which command, path, or URL) and decides against your config. It does not sit in the syscall or HTTP path. If a tool's actual implementation does something different from its declared arguments (`web_fetch` follows a redirect to a blocked host, for example), the hook can't catch that. For traffic-time enforcement, also wrap the gateway with `fence -- openclaw`.

### Spawn cost per tool call

The plugin spawns `fence` once per gated tool call. Fence's preflight is fast (sub-100ms in our benchmarks), but cold OS-level process spawn cost adds up if the agent is hammering tools in tight loops. If this becomes a problem in practice, let us know.

### Curated tool list

Today we gate `exec`, `bash`, `write`, `edit`, `apply_patch`, and `web_fetch`. Tools needing their own policy vocabulary (channel sends, MCP, subagent spawning, image generation) are passed through. Wrap mode covers their network traffic.

## Contributing

See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup, local-development install patterns, and the release process.

Bug reports, feature requests, and PRs welcome.
tools

Comments

Sign in to leave a comment

Loading comments...