@node9/proxy 1.0.12 → 1.0.14
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 +121 -114
- package/dist/cli.js +736 -360
- package/dist/cli.mjs +731 -355
- package/dist/index.js +441 -123
- package/dist/index.mjs +441 -123
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@node9/proxy)
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
|
+
[](https://huggingface.co/spaces/Node9ai/node9-security-demo)
|
|
7
8
|
|
|
8
9
|
**Node9** is the execution security layer for the Agentic Era. It encases autonomous AI Agents (Claude Code, Gemini CLI, Cursor, MCP Servers) in a deterministic security wrapper, intercepting dangerous shell commands and tool calls before they execute.
|
|
9
10
|
|
|
@@ -28,7 +29,7 @@ While others try to _guess_ if a prompt is malicious (Semantic Security), Node9
|
|
|
28
29
|
|
|
29
30
|
---
|
|
30
31
|
|
|
31
|
-
## ⚡ Key
|
|
32
|
+
## ⚡ Key Features
|
|
32
33
|
|
|
33
34
|
### 🏁 The Multi-Channel Race Engine
|
|
34
35
|
|
|
@@ -41,7 +42,7 @@ Node9 initiates a **Concurrent Race** across all enabled channels. The first cha
|
|
|
41
42
|
|
|
42
43
|
### 🧠 AI Negotiation Loop
|
|
43
44
|
|
|
44
|
-
Node9 doesn't just "cut the wire." When a command is blocked, it injects a **Structured Negotiation Prompt** back into the AI
|
|
45
|
+
Node9 doesn't just "cut the wire." When a command is blocked, it injects a **Structured Negotiation Prompt** back into the AI's context window. This teaches the AI why it was stopped and instructs it to pivot to a safer alternative.
|
|
45
46
|
|
|
46
47
|
### ⏪ Shadow Git Snapshots (Auto-Undo)
|
|
47
48
|
|
|
@@ -55,35 +56,13 @@ node9 undo
|
|
|
55
56
|
node9 undo --steps 3
|
|
56
57
|
```
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
⏪ Node9 Undo
|
|
62
|
-
Tool: str_replace_based_edit_tool → src/app.ts
|
|
63
|
-
When: 2m ago
|
|
64
|
-
Dir: /home/user/my-project
|
|
65
|
-
|
|
66
|
-
--- src/app.ts (snapshot)
|
|
67
|
-
+++ src/app.ts (current)
|
|
68
|
-
@@ -1,4 +1,6 @@
|
|
69
|
-
-const x = 1;
|
|
70
|
-
+const x = 99;
|
|
71
|
-
+const y = "hello";
|
|
72
|
-
|
|
73
|
-
Revert to this snapshot? [y/N]
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Node9 keeps the last 10 snapshots. Snapshots are only taken for file-writing tools (`write_file`, `edit_file`, `str_replace_based_edit_tool`, `create_file`) — not for read-only or shell commands.
|
|
59
|
+
---
|
|
77
60
|
|
|
78
|
-
|
|
61
|
+
## 🎮 Try it Live
|
|
79
62
|
|
|
80
|
-
|
|
63
|
+
No install needed — test Node9's policy engine against real commands in the browser:
|
|
81
64
|
|
|
82
|
-
|
|
83
|
-
2. **Cloud (SaaS):** Global organization "Locks" that cannot be bypassed locally.
|
|
84
|
-
3. **Project Config:** Repository-specific rules (`node9.config.json`).
|
|
85
|
-
4. **Global Config:** Personal UI preferences (`~/.node9/config.json`).
|
|
86
|
-
5. **Defaults:** The built-in safety net.
|
|
65
|
+
[](https://huggingface.co/spaces/Node9ai/node9-security-demo)
|
|
87
66
|
|
|
88
67
|
---
|
|
89
68
|
|
|
@@ -97,19 +76,52 @@ brew install node9
|
|
|
97
76
|
# Or via npm
|
|
98
77
|
npm install -g @node9/proxy
|
|
99
78
|
|
|
100
|
-
# 1.
|
|
79
|
+
# 1. Wire Node9 to your agent
|
|
101
80
|
node9 setup # interactive menu — picks the right agent for you
|
|
102
81
|
node9 addto claude # or wire directly
|
|
103
82
|
node9 addto gemini
|
|
104
83
|
|
|
105
|
-
# 2.
|
|
106
|
-
node9
|
|
84
|
+
# 2. Enable shields for the services you use
|
|
85
|
+
node9 shield enable postgres
|
|
86
|
+
node9 shield enable aws
|
|
107
87
|
|
|
108
88
|
# 3. Verify everything is wired correctly
|
|
109
89
|
node9 doctor
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 🛡️ How Protection Works
|
|
95
|
+
|
|
96
|
+
Node9 has two layers of protection. You get Layer 1 automatically. Layer 2 is one command per service.
|
|
97
|
+
|
|
98
|
+
### Layer 1 — Core Protection (Always On)
|
|
110
99
|
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
Built into the binary. Zero configuration required. Protects the tools every developer uses.
|
|
101
|
+
|
|
102
|
+
| What it protects | Example blocked action |
|
|
103
|
+
| :--------------- | :------------------------------------------------------ |
|
|
104
|
+
| **Git** | `git push --force`, `git reset --hard`, `git clean -fd` |
|
|
105
|
+
| **Shell** | `curl ... \| bash`, `sudo` commands |
|
|
106
|
+
| **SQL** | `DELETE` / `UPDATE` without a `WHERE` clause |
|
|
107
|
+
| **Filesystem** | `rm -rf` targeting home directory |
|
|
108
|
+
|
|
109
|
+
### Layer 2 — Shields (Opt-in, Per Service)
|
|
110
|
+
|
|
111
|
+
Shields add protection for specific infrastructure and services — only relevant if you actually use them.
|
|
112
|
+
|
|
113
|
+
| Shield | What it protects |
|
|
114
|
+
| :----------- | :---------------------------------------------------------------------------- |
|
|
115
|
+
| `postgres` | Blocks `DROP TABLE`, `TRUNCATE`, `DROP COLUMN`; reviews `GRANT`/`REVOKE` |
|
|
116
|
+
| `github` | Blocks `gh repo delete`; reviews remote branch deletion |
|
|
117
|
+
| `aws` | Blocks S3 bucket deletion, EC2 termination; reviews IAM changes, RDS deletion |
|
|
118
|
+
| `filesystem` | Reviews `chmod 777`, writes to `/etc/` |
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
node9 shield enable postgres # protect your database
|
|
122
|
+
node9 shield enable aws # protect your cloud infrastructure
|
|
123
|
+
node9 shield list # see all available shields
|
|
124
|
+
node9 shield status # see what's currently active
|
|
113
125
|
```
|
|
114
126
|
|
|
115
127
|
---
|
|
@@ -124,78 +136,55 @@ node9 status
|
|
|
124
136
|
|
|
125
137
|
---
|
|
126
138
|
|
|
127
|
-
##
|
|
139
|
+
## 🔗 Configuration Precedence
|
|
140
|
+
|
|
141
|
+
Node9 merges configuration from multiple sources in priority order. Higher tiers win:
|
|
142
|
+
|
|
143
|
+
| Tier | Source | Notes |
|
|
144
|
+
| :--- | :------------------------ | :-------------------------------------------------------- |
|
|
145
|
+
| 1 | **Environment variables** | `NODE9_MODE=strict` overrides everything |
|
|
146
|
+
| 2 | **Cloud / Org policy** | Set in the Node9 dashboard — cannot be overridden locally |
|
|
147
|
+
| 3 | **Project config** | `node9.config.json` in the working directory |
|
|
148
|
+
| 4 | **Global config** | `~/.node9/config.json` |
|
|
149
|
+
| 5 | **Built-in defaults** | Always active, no config needed |
|
|
128
150
|
|
|
129
|
-
|
|
151
|
+
**Settings** (mode, approvers, timeouts) follow the table above — higher tier wins. A project config overrides a global config.
|
|
152
|
+
|
|
153
|
+
**Smart rules** work differently. All layers are concatenated into a single ordered list and evaluated first-match-wins:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
built-in defaults → global config → project config → shields → advisory defaults
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Because built-in `block` rules sit at the front of this list, they always fire before any user-defined `allow` rule. **A project or global config cannot bypass Layer 1 protection.** Within the user layers, a project `block` rule fires before a shield `block` rule — so project policy can tighten or selectively override a shield.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## ⚙️ Custom Rules (Advanced)
|
|
164
|
+
|
|
165
|
+
Most users never need this. If you need protection beyond Layer 1 and the available shields, add **Smart Rules** to `node9.config.json` in your project root or `~/.node9/config.json` globally.
|
|
166
|
+
|
|
167
|
+
Smart Rules match on **raw tool arguments** using structured conditions:
|
|
130
168
|
|
|
131
169
|
```json
|
|
132
170
|
{
|
|
133
|
-
"settings": {
|
|
134
|
-
"mode": "standard",
|
|
135
|
-
"enableUndo": true,
|
|
136
|
-
"approvalTimeoutMs": 30000,
|
|
137
|
-
"approvers": {
|
|
138
|
-
"native": true,
|
|
139
|
-
"browser": true,
|
|
140
|
-
"cloud": true,
|
|
141
|
-
"terminal": true
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
171
|
"policy": {
|
|
145
|
-
"sandboxPaths": ["/tmp/**", "**/test-results/**"],
|
|
146
|
-
"dangerousWords": ["drop", "destroy", "purge", "push --force"],
|
|
147
|
-
"ignoredTools": ["list_*", "get_*", "read_*"],
|
|
148
|
-
"toolInspection": {
|
|
149
|
-
"bash": "command",
|
|
150
|
-
"postgres:query": "sql"
|
|
151
|
-
},
|
|
152
|
-
"rules": [
|
|
153
|
-
{ "action": "rm", "allowPaths": ["**/node_modules/**", "dist/**"] },
|
|
154
|
-
{ "action": "push", "blockPaths": ["**"] }
|
|
155
|
-
],
|
|
156
172
|
"smartRules": [
|
|
157
173
|
{
|
|
158
|
-
"name": "
|
|
159
|
-
"tool": "
|
|
174
|
+
"name": "block-prod-deploy",
|
|
175
|
+
"tool": "bash",
|
|
160
176
|
"conditions": [
|
|
161
|
-
{ "field": "
|
|
162
|
-
{ "field": "sql", "op": "notMatches", "value": "\\bWHERE\\b", "flags": "i" }
|
|
177
|
+
{ "field": "command", "op": "matches", "value": "kubectl.*--namespace=production" }
|
|
163
178
|
],
|
|
164
|
-
"verdict": "
|
|
165
|
-
"reason": "
|
|
179
|
+
"verdict": "block",
|
|
180
|
+
"reason": "Deploying to production requires a manual release process"
|
|
166
181
|
}
|
|
167
182
|
]
|
|
168
183
|
}
|
|
169
184
|
}
|
|
170
185
|
```
|
|
171
186
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
| Key | Default | Description |
|
|
175
|
-
| :------------------- | :----------- | :----------------------------------------------------------- |
|
|
176
|
-
| `mode` | `"standard"` | `standard` \| `strict` \| `audit` |
|
|
177
|
-
| `enableUndo` | `true` | Take git snapshots before every AI file edit |
|
|
178
|
-
| `approvalTimeoutMs` | `0` | Auto-deny after N ms if no human responds (0 = wait forever) |
|
|
179
|
-
| `approvers.native` | `true` | OS-native popup |
|
|
180
|
-
| `approvers.browser` | `true` | Browser dashboard (`node9 daemon`) |
|
|
181
|
-
| `approvers.cloud` | `true` | Slack / SaaS approval |
|
|
182
|
-
| `approvers.terminal` | `true` | `[Y/n]` prompt in terminal |
|
|
183
|
-
|
|
184
|
-
### 🧠 Smart Rules
|
|
185
|
-
|
|
186
|
-
Smart rules match on **raw tool arguments** using structured conditions — more powerful than `dangerousWords` or `rules`, which only see extracted tokens.
|
|
187
|
-
|
|
188
|
-
```json
|
|
189
|
-
{
|
|
190
|
-
"name": "curl-pipe-to-shell",
|
|
191
|
-
"tool": "bash",
|
|
192
|
-
"conditions": [{ "field": "command", "op": "matches", "value": "curl.+\\|.*(bash|sh)" }],
|
|
193
|
-
"verdict": "block",
|
|
194
|
-
"reason": "curl piped to shell — remote code execution risk"
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
**Fields:**
|
|
187
|
+
**Smart Rule fields:**
|
|
199
188
|
|
|
200
189
|
| Field | Description |
|
|
201
190
|
| :-------------- | :----------------------------------------------------------------------------------- |
|
|
@@ -207,33 +196,50 @@ Smart rules match on **raw tool arguments** using structured conditions — more
|
|
|
207
196
|
|
|
208
197
|
**Condition operators:**
|
|
209
198
|
|
|
210
|
-
| `op`
|
|
211
|
-
|
|
|
212
|
-
| `matches`
|
|
213
|
-
| `notMatches`
|
|
214
|
-
| `contains`
|
|
215
|
-
| `notContains`
|
|
216
|
-
| `exists`
|
|
217
|
-
| `notExists`
|
|
199
|
+
| `op` | Meaning |
|
|
200
|
+
| :--------------- | :------------------------------------------------------------------------- |
|
|
201
|
+
| `matches` | Field value matches regex (`value` = pattern, `flags` = e.g. `"i"`) |
|
|
202
|
+
| `notMatches` | Field value does not match regex (`value` = pattern, `flags` optional) |
|
|
203
|
+
| `contains` | Field value contains substring |
|
|
204
|
+
| `notContains` | Field value does not contain substring |
|
|
205
|
+
| `exists` | Field is present and non-empty |
|
|
206
|
+
| `notExists` | Field is absent or empty |
|
|
207
|
+
| `matchesGlob` | Field value matches a glob pattern (`value` = e.g. `"**/node_modules/**"`) |
|
|
208
|
+
| `notMatchesGlob` | Field value does not match a glob pattern |
|
|
218
209
|
|
|
219
210
|
The `field` key supports dot-notation for nested args: `"params.query.sql"`.
|
|
220
211
|
|
|
221
|
-
|
|
212
|
+
Use `node9 explain <tool> <args>` to dry-run any tool call and see exactly which rule would trigger.
|
|
213
|
+
|
|
214
|
+
### Settings
|
|
222
215
|
|
|
223
216
|
```json
|
|
224
217
|
{
|
|
225
|
-
"
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
218
|
+
"settings": {
|
|
219
|
+
"mode": "standard",
|
|
220
|
+
"enableUndo": true,
|
|
221
|
+
"approvalTimeoutMs": 30000,
|
|
222
|
+
"approvers": {
|
|
223
|
+
"native": true,
|
|
224
|
+
"browser": true,
|
|
225
|
+
"cloud": true,
|
|
226
|
+
"terminal": true
|
|
227
|
+
}
|
|
228
|
+
}
|
|
233
229
|
}
|
|
234
230
|
```
|
|
235
231
|
|
|
236
|
-
|
|
232
|
+
| Key | Default | Description |
|
|
233
|
+
| :------------------- | :----------- | :----------------------------------------------------------- |
|
|
234
|
+
| `mode` | `"standard"` | `standard` \| `strict` \| `audit` |
|
|
235
|
+
| `enableUndo` | `true` | Take git snapshots before every AI file edit |
|
|
236
|
+
| `approvalTimeoutMs` | `0` | Auto-deny after N ms if no human responds (0 = wait forever) |
|
|
237
|
+
| `approvers.native` | `true` | OS-native popup |
|
|
238
|
+
| `approvers.browser` | `true` | Browser dashboard (`node9 daemon`) |
|
|
239
|
+
| `approvers.cloud` | `true` | Slack / SaaS approval |
|
|
240
|
+
| `approvers.terminal` | `true` | `[Y/n]` prompt in terminal |
|
|
241
|
+
|
|
242
|
+
---
|
|
237
243
|
|
|
238
244
|
## 🖥️ CLI Reference
|
|
239
245
|
|
|
@@ -244,14 +250,13 @@ Use `node9 explain <tool> <args>` to dry-run any tool call and see exactly which
|
|
|
244
250
|
| `node9 init` | Create default `~/.node9/config.json` |
|
|
245
251
|
| `node9 status` | Show current protection status and active rules |
|
|
246
252
|
| `node9 doctor` | Health check — verifies binaries, config, credentials, and all agent hooks |
|
|
253
|
+
| `node9 shield <cmd>` | Manage shields (`enable`, `disable`, `list`, `status`) |
|
|
247
254
|
| `node9 explain <tool> [args]` | Trace the policy waterfall for a given tool call (dry-run, no approval prompt) |
|
|
248
255
|
| `node9 undo [--steps N]` | Revert the last N AI file edits using shadow Git snapshots |
|
|
249
256
|
| `node9 check` | Called by agent hooks; evaluates a pending tool call and exits 0 (allow) or 1 (block) |
|
|
250
257
|
|
|
251
258
|
### `node9 doctor`
|
|
252
259
|
|
|
253
|
-
Runs a full self-test and exits 1 if any required check fails:
|
|
254
|
-
|
|
255
260
|
```
|
|
256
261
|
Node9 Doctor v1.2.0
|
|
257
262
|
────────────────────────────────────────
|
|
@@ -274,7 +279,7 @@ All checks passed ✅
|
|
|
274
279
|
|
|
275
280
|
### `node9 explain`
|
|
276
281
|
|
|
277
|
-
Dry-runs the policy engine and prints exactly which rule
|
|
282
|
+
Dry-runs the policy engine and prints exactly which rule would fire — useful for debugging:
|
|
278
283
|
|
|
279
284
|
```bash
|
|
280
285
|
node9 explain bash '{"command":"rm -rf /tmp/build"}'
|
|
@@ -285,9 +290,6 @@ Policy Waterfall for: bash
|
|
|
285
290
|
──────────────────────────────────────────────
|
|
286
291
|
Tier 1 · Cloud Org Policy SKIP (no org policy loaded)
|
|
287
292
|
Tier 2 · Dangerous Words BLOCK ← matched "rm -rf"
|
|
288
|
-
Tier 3 · Path Block –
|
|
289
|
-
Tier 4 · Inline Exec –
|
|
290
|
-
Tier 5 · Rule Match –
|
|
291
293
|
──────────────────────────────────────────────
|
|
292
294
|
Verdict: BLOCK (dangerous word: rm -rf)
|
|
293
295
|
```
|
|
@@ -315,6 +317,11 @@ A corporate policy has locked this action. You must click the "Approve" button i
|
|
|
315
317
|
- [x] **Native OS Dialogs** (Sub-second approval via Mac/Win/Linux system windows)
|
|
316
318
|
- [x] **Shadow Git Snapshots** (1-click Undo for AI hallucinations)
|
|
317
319
|
- [x] **Identity-Aware Execution** (Differentiates between Human vs. AI risk levels)
|
|
320
|
+
- [x] **Shield Templates** (`node9 shield enable <service>` — one-click protection for Postgres, GitHub, AWS)
|
|
321
|
+
- [ ] **Content Scanner / DLP** (Detect and block secrets like AWS keys and Bearer tokens in-flight)
|
|
322
|
+
- [ ] **Universal MCP Gateway** (Standalone security tunnel for LangChain, CrewAI, and any agent without native hooks)
|
|
323
|
+
- [ ] **Cursor & Windsurf Hook** (Native hook support for AI-first IDEs)
|
|
324
|
+
- [ ] **VS Code Extension** (Approval requests in a native sidebar — no more OS popups)
|
|
318
325
|
- [ ] **Execution Sandboxing** (Simulate dangerous commands in a virtual FS before applying)
|
|
319
326
|
- [ ] **Multi-Admin Quorum** (Require 2+ human signatures for high-stakes production actions)
|
|
320
327
|
- [ ] **SOC2 Tamper-proof Audit Trail** (Cryptographically signed, cloud-managed logs)
|