squad-openclaw 2026.2.1905 → 2026.2.2001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -0
- package/dist/index.js +732 -701
- package/openclaw.plugin.json +4 -3
- package/package.json +4 -2
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# squad-openclaw
|
|
2
|
+
|
|
3
|
+
OpenClaw gateway plugin for [Squad](https://squad.ceo) — provides entity registry, filesystem tools, SQL queries, version management, and a cloud relay client for remote browser access.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
| Tool / Method | Description |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `entity_list`, `entity_search`, `entity_sync` | In-memory entity registry with filesystem watching (agents, skills, plugins, tools, media) |
|
|
10
|
+
| `fs_read`, `fs_write`, `fs_list`, `fs_delete`, `fs_rename`, `fs_mkdir` | Remote filesystem access for browser clients (subject to security restrictions below) |
|
|
11
|
+
| `sql_query` | Restricted SQLite query tool — `sqlite3` only, scoped to `~/.openclaw/squad-ceo-data/` |
|
|
12
|
+
| `squad.version.check`, `squad.version.update` | Plugin version management and self-update |
|
|
13
|
+
| `tools.invoke` | RPC-based tool invocation for relay mode (WebSocket) |
|
|
14
|
+
| Cloud relay client | **Disabled by default (opt-in).** Connects outbound to `relay.squad.ceo` for remote browser access |
|
|
15
|
+
|
|
16
|
+
## Security Model
|
|
17
|
+
|
|
18
|
+
This plugin enforces a **defense-in-depth** security model with four independent layers. All security rules are hard-coded and non-configurable (except `allowedRoots`) so they can be verified by reading the source code. The bundle is intentionally **not minified** to allow security auditing of the distributed code.
|
|
19
|
+
|
|
20
|
+
### Layer 1: Blocked Directories (hardcoded, non-configurable)
|
|
21
|
+
|
|
22
|
+
These directories are **completely blocked** from all filesystem operations (read, write, list, delete, rename):
|
|
23
|
+
|
|
24
|
+
| Path | Contents |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `~/.openclaw/credentials/` | OAuth tokens, API keys |
|
|
27
|
+
| `~/.openclaw/devices/` | Device pairing secrets, private keys |
|
|
28
|
+
| `~/.openclaw/identity/` | Operator identity material |
|
|
29
|
+
|
|
30
|
+
### Layer 1b: Blocked Files (hardcoded, non-configurable)
|
|
31
|
+
|
|
32
|
+
| Path | Reason |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `~/.openclaw/squad-ceo-data/squad-relay.json` | Contains ed25519 private key for relay device identity |
|
|
35
|
+
| `~/.openclaw/*.bak` | Backup files at the top level contain unredacted config (tokens, keys) that would bypass redaction |
|
|
36
|
+
|
|
37
|
+
### Layer 2: Redacted Files (hardcoded, non-configurable)
|
|
38
|
+
|
|
39
|
+
`~/.openclaw/openclaw.json` is **readable** but with sensitive fields replaced with `"[REDACTED]"` before returning to clients:
|
|
40
|
+
|
|
41
|
+
- `channels.*.botToken` — channel bot tokens
|
|
42
|
+
- `gateway.auth.*` — all auth keys
|
|
43
|
+
- `gateway.token` — legacy token location
|
|
44
|
+
- `gateway.remote.token` — legacy remote token
|
|
45
|
+
|
|
46
|
+
### Layer 3: Allowed Roots (configurable, defaults to `~/.openclaw`)
|
|
47
|
+
|
|
48
|
+
Filesystem operations are restricted to configured root directories. By default, only `~/.openclaw/` is accessible — covering all SPA needs:
|
|
49
|
+
|
|
50
|
+
- `~/.openclaw/squad-ceo-data/` — entity databases, data files
|
|
51
|
+
- `~/.openclaw/media/` — asset uploads
|
|
52
|
+
- `~/.openclaw/workspace*/` — agent workspaces
|
|
53
|
+
- `~/.openclaw/skills/` — skill definitions
|
|
54
|
+
- `~/.openclaw/extensions/` — plugin manifests
|
|
55
|
+
|
|
56
|
+
Operators can customize via the `fs.allowedRoots` config option.
|
|
57
|
+
|
|
58
|
+
### Layer 4: Write Protection (hardcoded, non-configurable)
|
|
59
|
+
|
|
60
|
+
These files/directories cannot be written to, even if they fall within `allowedRoots`:
|
|
61
|
+
|
|
62
|
+
- `~/.openclaw/openclaw.json` — operator configuration (read-only with redaction)
|
|
63
|
+
- `~/.openclaw/squad-ceo-data/squad-relay.json` — relay device private key
|
|
64
|
+
- All blocked directories above (credentials, devices, identity)
|
|
65
|
+
- All `.bak` files at `~/.openclaw/` top level
|
|
66
|
+
|
|
67
|
+
## Relay Security
|
|
68
|
+
|
|
69
|
+
> **The cloud relay is DISABLED by default. No outbound connections are made unless the operator explicitly sets `relay.enabled: true`.** Installing this plugin alone does NOT create any network surface — the relay code is never executed until opted in.
|
|
70
|
+
|
|
71
|
+
The cloud relay enables remote browser access to the gateway through `relay.squad.ceo`.
|
|
72
|
+
|
|
73
|
+
### Opt-in Only
|
|
74
|
+
|
|
75
|
+
The relay is **disabled by default** (`relay.enabled` defaults to `false`). The plugin entry point checks this flag **before** calling `startRelayClient()` — if the flag is not set or is `false`, no relay code runs, no WebSocket is opened, and no connection metadata is sent anywhere. The operator must explicitly enable it by setting `relay.enabled: true` in the plugin configuration.
|
|
76
|
+
|
|
77
|
+
### Authentication
|
|
78
|
+
|
|
79
|
+
- **Browser to Relay:** JWT authentication (email/password or Google OAuth)
|
|
80
|
+
- **Relay to Gateway:** Single-use claim token (24h expiry) for first connection, stored room ID for reconnection
|
|
81
|
+
- Claim tokens are generated per-user during setup — **not** open access
|
|
82
|
+
|
|
83
|
+
### Device Pairing
|
|
84
|
+
|
|
85
|
+
The relay-client's device identity must be **explicitly approved by the operator** before it can proxy user connections to the gateway. The plugin does **not** auto-pair or self-approve. During the onboarding flow, the AI guides the user through reading the device identity and confirming approval.
|
|
86
|
+
|
|
87
|
+
### E2E Encryption
|
|
88
|
+
|
|
89
|
+
- **Protocol:** ECDH (P-256) key exchange + AES-256-GCM message encryption
|
|
90
|
+
- **No plaintext fallback:** If encryption fails after E2E is established, messages are dropped — never sent as plaintext
|
|
91
|
+
- **Status:** Implemented in the plugin. Currently disabled at the relay level (Durable Object) due to multi-tab session safety. When per-session E2E is enabled at the relay, the plugin is already hardened.
|
|
92
|
+
|
|
93
|
+
### Operator Token
|
|
94
|
+
|
|
95
|
+
The relay-client reads `gateway.auth.token` from `~/.openclaw/openclaw.json` via direct `fs.readFileSync`. This is intentional and safe:
|
|
96
|
+
|
|
97
|
+
- The relay-client runs **server-side, in the gateway's own process** — equivalent to the gateway reading its own config
|
|
98
|
+
- The token is **never sent to the relay server or the browser** — it is only injected into **local** `localhost:18789` WebSocket connections on the same machine
|
|
99
|
+
- The token is **never exposed through the filesystem tool API** — `gateway.auth.*` is redacted in `filesystem.ts`
|
|
100
|
+
- Direct file read is used because the plugin config API doesn't expose the full gateway config
|
|
101
|
+
|
|
102
|
+
**Token flow (important for security auditing):**
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
Browser ──[connect request]──> relay.squad.ceo ──[relay.forward]──> relay-client
|
|
106
|
+
│
|
|
107
|
+
Token is injected HERE, in memory, │
|
|
108
|
+
into the connect request. │
|
|
109
|
+
▼
|
|
110
|
+
relay-client ──[modified request]──> localhost:18789 (gateway)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The relay server only sees the outer `relay.forward` envelope. It **never** receives the modified request containing the token. The token injection happens entirely within the relay-client process, and the modified message is sent over a **local loopback** connection to the gateway. A compromised relay server cannot intercept the operator token because it never traverses the relay — it only exists on the `localhost:18789` path.
|
|
114
|
+
|
|
115
|
+
## SQL Query Tool
|
|
116
|
+
|
|
117
|
+
The `sql_query` tool provides restricted SQLite access:
|
|
118
|
+
|
|
119
|
+
- **Path restriction:** Database files must be within `~/.openclaw/squad-ceo-data/`
|
|
120
|
+
- **No shell:** Uses `execFile` (not `exec`) — arguments are passed as an argv array, preventing command injection
|
|
121
|
+
- **No arbitrary commands:** Only `sqlite3` is executed
|
|
122
|
+
|
|
123
|
+
## Build Transparency
|
|
124
|
+
|
|
125
|
+
The build configuration (`tsup.config.ts`) is optimized for security auditing:
|
|
126
|
+
|
|
127
|
+
| Setting | Value | Reason |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| `minify` | `false` | Unminified bundle for human/AI security review |
|
|
130
|
+
| `sourcemap` | `false` | No internal path exposure |
|
|
131
|
+
| `treeshake` | `false` | All code preserved for complete auditing |
|
|
132
|
+
|
|
133
|
+
## Configuration
|
|
134
|
+
|
|
135
|
+
Configure in your gateway's `openclaw.json` under the plugin section:
|
|
136
|
+
|
|
137
|
+
| Key | Type | Default | Description |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| `relay.enabled` | `boolean` | `false` | Enable cloud relay. Opt-in required. |
|
|
140
|
+
| `relay.url` | `string` | `wss://relay.squad.ceo` | Cloud relay WebSocket URL |
|
|
141
|
+
| `fs.allowedRoots` | `string[]` | `["~/.openclaw"]` | Restrict filesystem operations to these directories |
|
|
142
|
+
|
|
143
|
+
## Source Code
|
|
144
|
+
|
|
145
|
+
- **Repository:** [github.com/WorldBrain/squad](https://github.com/WorldBrain/squad)
|
|
146
|
+
- **Plugin directory:** `extensions/squad-openclaw/`
|
|
147
|
+
- **Security-critical files:**
|
|
148
|
+
- `src/filesystem.ts` — path blocking, redaction, write protection
|
|
149
|
+
- `src/sql.ts` — restricted SQL execution
|
|
150
|
+
- `src/relay-client.ts` — relay authentication, E2E encryption, device identity
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|