@node9/proxy 2.9.3 → 2.11.0

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.
@@ -0,0 +1,29 @@
1
+ # node9 per agent
2
+
3
+ One page per agent: what node9 wires into it, what that covers, and what it does not. The
4
+ "what is not covered" section is the one to read before you tell your team an agent is governed.
5
+
6
+ | Agent | Control model | Prompt scan | Guide |
7
+ | --------------------------- | ------------- | ----------- | -------------------------------------- |
8
+ | Claude Code | hooks + MCP | yes | [claude-code.md](claude-code.md) |
9
+ | Codex CLI | hooks + MCP | yes | [codex.md](codex.md) |
10
+ | GitHub Copilot CLI | hooks + MCP | yes | [copilot-cli.md](copilot-cli.md) |
11
+ | Gemini CLI | hooks + MCP | no | [gemini-cli.md](gemini-cli.md) |
12
+ | Antigravity | hooks + MCP | no | [antigravity.md](antigravity.md) |
13
+ | Hermes Agent | hooks | no | [hermes.md](hermes.md) |
14
+ | OpenCode | plugin | yes | [opencode.md](opencode.md) |
15
+ | Pi | extension | yes | [pi.md](pi.md) |
16
+ | Cursor | MCP only | no | [cursor.md](cursor.md) |
17
+ | Windsurf | MCP only | no | [windsurf.md](windsurf.md) |
18
+ | VS Code (Copilot extension) | MCP only | no | [vscode.md](vscode.md) |
19
+ | Claude Desktop | MCP only | no | [claude-desktop.md](claude-desktop.md) |
20
+
21
+ "Hooks" means node9 sees every tool call before it runs. "MCP only" means node9 sees the tools
22
+ that go through MCP servers and nothing the editor does on its own.
23
+
24
+ Every page ends with the same two commands, and they are the real check:
25
+
26
+ ```bash
27
+ node9 doctor
28
+ node9 explain Bash 'cat ~/.ssh/id_rsa'
29
+ ```
@@ -0,0 +1,33 @@
1
+ # node9 with Antigravity
2
+
3
+ | Surface | How node9 is wired | What it does |
4
+ | ----------------- | ------------------------------------------------------ | ------------------------------------------- |
5
+ | Every tool call | `PreToolUse` hook in `~/.gemini/config/hooks.json` | allow / review / block before the tool runs |
6
+ | Every tool result | `PostToolUse` hook | audit record |
7
+ | MCP servers | `~/.gemini/config/mcp_config.json` entries are wrapped | per-tool allow / review / block |
8
+
9
+ Payload shape verified against Antigravity 1.0.6.
10
+
11
+ ## Set it up
12
+
13
+ ```bash
14
+ node9 agents add antigravity
15
+ ```
16
+
17
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
18
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
19
+
20
+ ## What is not covered
21
+
22
+ - **No prompt scan.** There is no prompt event to hook.
23
+ - Cost is not tracked for Antigravity.
24
+
25
+ ## Verify it on this machine
26
+
27
+ ```bash
28
+ node9 doctor # is the hook (or MCP wrap) actually in place?
29
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
30
+ ```
31
+
32
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
33
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,40 @@
1
+ # node9 with Claude Code
2
+
3
+ Claude Code is the most fully covered agent.
4
+
5
+ | Surface | How node9 is wired | What it does |
6
+ | ----------------- | ----------------------------------------------------------------- | --------------------------------------------------------- |
7
+ | Every tool call | `PreToolUse` hook in `~/.claude/settings.json` | allow / review / block before the tool runs |
8
+ | Every tool result | `PostToolUse` hook | writes the audit record |
9
+ | Pasted prompts | `UserPromptSubmit` hook | secret pasted into the prompt is caught before it is sent |
10
+ | MCP servers | entries in `~/.claude.json` are wrapped through the node9 gateway | per-tool allow / review / block |
11
+ | Cost | reads `~/.claude/projects` session logs | per-project spend in `node9 report` |
12
+
13
+ The `PreToolUse` hook runs in every Claude Code permission mode, including
14
+ `--dangerously-skip-permissions`. That was verified with a standalone probe, and it is
15
+ undocumented behaviour, so treat it as a fact about today's Claude Code rather than a guarantee.
16
+
17
+ ## Set it up
18
+
19
+ ```bash
20
+ node9 agents add claude
21
+ ```
22
+
23
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
24
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
25
+
26
+ ## What is not covered
27
+
28
+ - Tool **output** is observed, not gated. Claude Code's `PostToolUse` cannot suppress a
29
+ result, so a secret or an injected instruction inside a tool result is recorded and the
30
+ session is tainted for review on the next call; it is not stripped before Claude sees it.
31
+
32
+ ## Verify it on this machine
33
+
34
+ ```bash
35
+ node9 doctor # is the hook (or MCP wrap) actually in place?
36
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
37
+ ```
38
+
39
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
40
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,32 @@
1
+ # node9 with Claude Desktop
2
+
3
+ Claude Desktop only calls tools through MCP, so wrapping its servers covers every tool it
4
+ can use.
5
+
6
+ | Surface | How node9 is wired | What it does |
7
+ | ----------- | ----------------------------------------------------------------------------- | ------------------------------- |
8
+ | MCP servers | entries in `claude_desktop_config.json` are wrapped through the node9 gateway | per-tool allow / review / block |
9
+
10
+ ## Set it up
11
+
12
+ ```bash
13
+ node9 agents add claudeDesktop
14
+ ```
15
+
16
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
17
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
18
+
19
+ ## What is not covered
20
+
21
+ - No prompt scan and no cost tracking.
22
+ - `node9 doctor` and `node9 status` do not list Claude Desktop yet.
23
+
24
+ ## Verify it on this machine
25
+
26
+ ```bash
27
+ node9 doctor # is the hook (or MCP wrap) actually in place?
28
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
29
+ ```
30
+
31
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
32
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,37 @@
1
+ # node9 with Codex CLI
2
+
3
+ Codex gets the same pre-tool gate as Claude Code.
4
+
5
+ | Surface | How node9 is wired | What it does |
6
+ | ----------------- | --------------------------------------------------- | -------------------------------------------------- |
7
+ | Every tool call | `PreToolUse` hook in `~/.codex/hooks.json` | allow / review / block before the tool runs |
8
+ | Pasted prompts | `UserPromptSubmit` hook | prompt secret scan |
9
+ | Every tool result | `PostToolUse` hook | audit record; verified against real Codex sessions |
10
+ | MCP servers | `mcp_servers` in `~/.codex/config.toml` are wrapped | per-tool allow / review / block |
11
+
12
+ Headless `codex exec` runs the same hooks. Verified with a nonce probe against the real
13
+ trusted-hooks config: both the pre and post hook fired.
14
+
15
+ ## Set it up
16
+
17
+ ```bash
18
+ node9 agents add codex
19
+ ```
20
+
21
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
22
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
23
+
24
+ ## What is not covered
25
+
26
+ - Cost is not tracked for Codex. `node9 report` cost figures are Claude Code only today.
27
+ - Tool output is observed, not gated (same as Claude Code).
28
+
29
+ ## Verify it on this machine
30
+
31
+ ```bash
32
+ node9 doctor # is the hook (or MCP wrap) actually in place?
33
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
34
+ ```
35
+
36
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
37
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,34 @@
1
+ # node9 with GitHub Copilot CLI
2
+
3
+ Copilot CLI is wired on three events, which makes it one of the strongest integrations.
4
+
5
+ | Surface | How node9 is wired | What it does |
6
+ | ----------------- | ------------------------------------------------ | ------------------------------------------- |
7
+ | Every tool call | `PreToolUse` in `~/.copilot/hooks/node9.json` | allow / review / block before the tool runs |
8
+ | Every tool result | `PostToolUse` | audit record |
9
+ | Pasted prompts | `UserPromptSubmit` | prompt secret scan |
10
+ | MCP servers | `~/.copilot/mcp-config.json` entries are wrapped | per-tool allow / review / block |
11
+
12
+ ## Set it up
13
+
14
+ ```bash
15
+ node9 agents add copilot
16
+ ```
17
+
18
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
19
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
20
+
21
+ ## What is not covered
22
+
23
+ - Cost is not tracked for Copilot.
24
+ - Tool output is observed, not gated.
25
+
26
+ ## Verify it on this machine
27
+
28
+ ```bash
29
+ node9 doctor # is the hook (or MCP wrap) actually in place?
30
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
31
+ ```
32
+
33
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
34
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,36 @@
1
+ # node9 with Cursor
2
+
3
+ Cursor has no pre-execution hook, so node9 protects it through MCP only.
4
+
5
+ | Surface | How node9 is wired | What it does |
6
+ | ----------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
7
+ | MCP servers | `~/.cursor/mcp.json` entries are wrapped through the node9 gateway | every `tools/call` is authorized, pinned and env-scrubbed before it reaches the server |
8
+
9
+ For tools that go through MCP this is the same allow / review / block gate every other agent
10
+ gets.
11
+
12
+ ## Set it up
13
+
14
+ ```bash
15
+ node9 agents add cursor
16
+ ```
17
+
18
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
19
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
20
+
21
+ ## What is not covered
22
+
23
+ - **Cursor's own terminal and file edits are not gated.** Nothing in Cursor exposes them to a
24
+ hook today. If Cursor runs `cat ~/.ssh/id_rsa` in its built-in terminal, node9 does not see it.
25
+ - No prompt scan, no audit of native tool calls, no cost tracking.
26
+ - Say this plainly to your team: with Cursor, node9 governs the MCP surface, not the editor.
27
+
28
+ ## Verify it on this machine
29
+
30
+ ```bash
31
+ node9 doctor # is the hook (or MCP wrap) actually in place?
32
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
33
+ ```
34
+
35
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
36
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,34 @@
1
+ # node9 with Gemini CLI
2
+
3
+ | Surface | How node9 is wired | What it does |
4
+ | ----------------- | ----------------------------------------------------- | ------------------------------------------- |
5
+ | Every tool call | `BeforeTool` hook in `~/.gemini/settings.json` | allow / review / block before the tool runs |
6
+ | Every tool result | `AfterTool` hook | audit record |
7
+ | MCP servers | `mcpServers` in `~/.gemini/settings.json` are wrapped | per-tool allow / review / block |
8
+
9
+ ## Set it up
10
+
11
+ ```bash
12
+ node9 agents add gemini
13
+ ```
14
+
15
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
16
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
17
+
18
+ ## What is not covered
19
+
20
+ - **No prompt scan.** Gemini CLI has no prompt-submit hook, so a secret pasted into the prompt
21
+ is not caught until it shows up in a tool call.
22
+ - The session id Gemini sends drifts across resumes, so a review taint set before a resume can
23
+ be orphaned. Within one session it works.
24
+ - Cost is not tracked for Gemini.
25
+
26
+ ## Verify it on this machine
27
+
28
+ ```bash
29
+ node9 doctor # is the hook (or MCP wrap) actually in place?
30
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
31
+ ```
32
+
33
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
34
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,35 @@
1
+ # node9 with Hermes Agent
2
+
3
+ | Surface | How node9 is wired | What it does |
4
+ | ----------------- | ------------------------------------------------------ | ------------------------------------------- |
5
+ | Every tool call | `pre_tool_call` command hook in the Hermes YAML config | allow / review / block before the tool runs |
6
+ | Every tool result | `post_tool_call` command hook | audit record |
7
+
8
+ Run `node9 status` to see the exact config path on your machine.
9
+
10
+ ## Set it up
11
+
12
+ ```bash
13
+ node9 agents add hermes
14
+ ```
15
+
16
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
17
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
18
+
19
+ ## What is not covered
20
+
21
+ - **No prompt scan.** Hermes has no prompt event.
22
+ - **No MCP wrapping.** Hermes' MCP servers are not routed through the node9 gateway.
23
+ - Hermes sends an empty session id on the pre-tool hook, so the output-taint review gate
24
+ does not work for Hermes. Upstream issue: NousResearch/hermes-agent#48311.
25
+ - Cost is not tracked for Hermes.
26
+
27
+ ## Verify it on this machine
28
+
29
+ ```bash
30
+ node9 doctor # is the hook (or MCP wrap) actually in place?
31
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
32
+ ```
33
+
34
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
35
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,36 @@
1
+ # node9 with OpenCode
2
+
3
+ OpenCode is protected by a node9 plugin rather than hooks or MCP.
4
+
5
+ | Surface | How node9 is wired | What it does |
6
+ | ----------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------- |
7
+ | Every tool call | `tool.execute.before` in the node9 plugin under the OpenCode config directory (`plugins/node9.js`) | allow / review / block before the tool runs |
8
+ | Prompts | `chat.message` | prompt secret scan |
9
+ | Every tool result | `tool.execute.after` | audit record, and output redaction in place |
10
+
11
+ Because the plugin can mutate tool output, secrets in a result are redacted before the model
12
+ sees them. That is stronger than the observe-only agents.
13
+
14
+ ## Set it up
15
+
16
+ ```bash
17
+ node9 agents add opencode
18
+ ```
19
+
20
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
21
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
22
+
23
+ ## What is not covered
24
+
25
+ - MCP servers are not wrapped for OpenCode; the plugin gates tool calls directly.
26
+ - Cost is not tracked for OpenCode.
27
+
28
+ ## Verify it on this machine
29
+
30
+ ```bash
31
+ node9 doctor # is the hook (or MCP wrap) actually in place?
32
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
33
+ ```
34
+
35
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
36
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,34 @@
1
+ # node9 with Pi
2
+
3
+ Pi is protected by a node9 extension rather than hooks or MCP.
4
+
5
+ | Surface | How node9 is wired | What it does |
6
+ | --------------------------------- | ------------------------------------------------ | ------------------------------------------- |
7
+ | Every tool call | `tool_call` in `~/.pi/agent/extensions/node9.js` | allow / review / block before the tool runs |
8
+ | Prompts | `input` | prompt secret scan |
9
+ | The `!` / `!!` shell side channel | `user_bash` | gated like any other command |
10
+ | Every tool result | `tool_result` | audit record, and output redaction in place |
11
+
12
+ ## Set it up
13
+
14
+ ```bash
15
+ node9 agents add pi
16
+ ```
17
+
18
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
19
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
20
+
21
+ ## What is not covered
22
+
23
+ - MCP servers are not wrapped for Pi.
24
+ - Cost is not tracked for Pi.
25
+
26
+ ## Verify it on this machine
27
+
28
+ ```bash
29
+ node9 doctor # is the hook (or MCP wrap) actually in place?
30
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
31
+ ```
32
+
33
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
34
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,33 @@
1
+ # node9 with VS Code (Copilot extension)
2
+
3
+ The VS Code Copilot extension exposes no hook, so node9 wraps its MCP servers only. This is
4
+ a different integration from the Copilot **CLI**, which has full hooks; see
5
+ [copilot-cli.md](copilot-cli.md).
6
+
7
+ | Surface | How node9 is wired | What it does |
8
+ | ----------- | ------------------------------------------------------------------ | ------------------------------- |
9
+ | MCP servers | VS Code's MCP config entries are wrapped through the node9 gateway | per-tool allow / review / block |
10
+
11
+ ## Set it up
12
+
13
+ ```bash
14
+ node9 agents add vscode
15
+ ```
16
+
17
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
18
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
19
+
20
+ ## What is not covered
21
+
22
+ - The editor's own terminal and edits are not gated.
23
+ - `node9 doctor` and `node9 status` do not list VS Code yet.
24
+
25
+ ## Verify it on this machine
26
+
27
+ ```bash
28
+ node9 doctor # is the hook (or MCP wrap) actually in place?
29
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
30
+ ```
31
+
32
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
33
+ says the agent is not wired, the guard is not running, whatever the config looks like.
@@ -0,0 +1,31 @@
1
+ # node9 with Windsurf
2
+
3
+ Windsurf exposes no pre-execution hook, so node9 wraps its MCP servers and nothing else.
4
+
5
+ | Surface | How node9 is wired | What it does |
6
+ | ----------- | ------------------------------------------------------------------- | ------------------------------- |
7
+ | MCP servers | Windsurf's MCP config entries are wrapped through the node9 gateway | per-tool allow / review / block |
8
+
9
+ ## Set it up
10
+
11
+ ```bash
12
+ node9 agents add windsurf
13
+ ```
14
+
15
+ `node9 init` does this for every agent it detects on the machine. Either command is safe to
16
+ re-run; it repairs a hook that an agent update removed and leaves everything else alone.
17
+
18
+ ## What is not covered
19
+
20
+ - Windsurf's own terminal and edits are not gated, and there is no audit of them.
21
+ - `node9 doctor` and `node9 status` do not list Windsurf yet; check the MCP config by hand.
22
+
23
+ ## Verify it on this machine
24
+
25
+ ```bash
26
+ node9 doctor # is the hook (or MCP wrap) actually in place?
27
+ node9 explain Bash 'cat ~/.ssh/id_rsa' # shows the verdict the live hook enforces: BLOCK
28
+ ```
29
+
30
+ `node9 explain` prints the exact rule that fires and where the decision came from. If `doctor`
31
+ says the agent is not wired, the guard is not running, whatever the config looks like.
package/docs/badges.md ADDED
@@ -0,0 +1,98 @@
1
+ # node9 badges
2
+
3
+ Drop-in Markdown for showing that a project's agent-security surface is checked by node9.
4
+
5
+ Two badges ship. One is for projects that use node9; the other is reserved for this repository.
6
+
7
+ ## `scanned by node9`
8
+
9
+ Use this on any public project where the node9 Action runs in CI. It says that the repo's
10
+ committed agent configuration — CI workflows, agent settings, MCP servers, instruction files — is
11
+ inspected on every pull request, and it links readers back to node9 so they can judge what the
12
+ badge is worth.
13
+
14
+ ![scanned by node9](https://img.shields.io/badge/scanned%20by-node9-a855f7?style=flat&labelColor=%231A1A2E&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNCAxNCI+PHBhdGggZmlsbD0iI0Y1RTlGRiIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDAuNCAxLjYgMi41djQuMmMwIDMuMSAyLjMgNS42IDUuNCA2LjkgMy4xLTEuMyA1LjQtMy44IDUuNC02LjlWMi41TDcgMC40Wm0wIDEuNSAzLjkgMS41djMuM2MwIDIuMy0xLjYgNC4yLTMuOSA1LjMtMi4zLTEuMS0zLjktMy0zLjktNS4zVjMuNEw3IDEuOVptMCAyLjJhMS45IDEuOSAwIDAgMC0xIDMuNXYxLjZoMlY3LjZhMS45IDEuOSAwIDAgMC0xLTMuNVoiLz48L3N2Zz4K)
15
+
16
+ ### Requirements
17
+
18
+ Only display this badge if the node9 Action genuinely runs on every pull request. The honest CI
19
+ wiring is the signal; the badge is only a surface for it. A badge on a repo that does not run the
20
+ check is misleading, and it devalues the badge for everyone who does.
21
+
22
+ The minimum is a job that runs `node9-ai/node9-proxy@v2` on `pull_request`:
23
+
24
+ ```yaml
25
+ # .github/workflows/agent-security.yml
26
+ name: node9 agent-security
27
+ on: pull_request
28
+ permissions:
29
+ contents: read
30
+ pull-requests: write
31
+ checks: write
32
+ jobs:
33
+ scan:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: node9-ai/node9-proxy@v2
37
+ with:
38
+ fail-on: high # 'never' to comment without gating
39
+ ```
40
+
41
+ `fail-on: never` still counts as running the check: the badge claims the surface is _inspected_,
42
+ not that merges are blocked.
43
+
44
+ ### Markdown
45
+
46
+ ```markdown
47
+ [![scanned by node9](https://img.shields.io/badge/scanned%20by-node9-a855f7?style=flat&labelColor=%231A1A2E&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNCAxNCI+PHBhdGggZmlsbD0iI0Y1RTlGRiIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDAuNCAxLjYgMi41djQuMmMwIDMuMSAyLjMgNS42IDUuNCA2LjkgMy4xLTEuMyA1LjQtMy44IDUuNC02LjlWMi41TDcgMC40Wm0wIDEuNSAzLjkgMS41djMuM2MwIDIuMy0xLjYgNC4yLTMuOSA1LjMtMi4zLTEuMS0zLjktMy0zLjktNS4zVjMuNEw3IDEuOVptMCAyLjJhMS45IDEuOSAwIDAgMC0xIDMuNXYxLjZoMlY3LjZhMS45IDEuOSAwIDAgMC0xLTMuNVoiLz48L3N2Zz4K)](https://github.com/node9-ai/node9-proxy)
48
+ ```
49
+
50
+ ### HTML
51
+
52
+ ```html
53
+ <a href="https://github.com/node9-ai/node9-proxy">
54
+ <img
55
+ alt="scanned by node9"
56
+ src="https://img.shields.io/badge/scanned%20by-node9-a855f7?style=flat&labelColor=%231A1A2E&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNCAxNCI+PHBhdGggZmlsbD0iI0Y1RTlGRiIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDAuNCAxLjYgMi41djQuMmMwIDMuMSAyLjMgNS42IDUuNCA2LjkgMy4xLTEuMyA1LjQtMy44IDUuNC02LjlWMi41TDcgMC40Wm0wIDEuNSAzLjkgMS41djMuM2MwIDIuMy0xLjYgNC4yLTMuOSA1LjMtMi4zLTEuMS0zLjktMy0zLjktNS4zVjMuNEw3IDEuOVptMCAyLjJhMS45IDEuOSAwIDAgMC0xIDMuNXYxLjZoMlY3LjZhMS45IDEuOSAwIDAgMC0xLTMuNVoiLz48L3N2Zz4K"
57
+ />
58
+ </a>
59
+ ```
60
+
61
+ ### Placement
62
+
63
+ Put it with the other status badges at the top of the README. It follows the standard shields.io
64
+ layout, so it sits cleanly next to CI, coverage, and license badges.
65
+
66
+ ### Link target
67
+
68
+ Link the badge to `https://github.com/node9-ai/node9-proxy` so a reader can click through and find out what it asserts. Linking to
69
+ your own passing CI run instead is also fine.
70
+
71
+ ## `node9 self-scanned`
72
+
73
+ **Reserved for this repository.** It says that node9 runs its own Action against its own source on
74
+ every pull request, and gates merges on the result — dogfooding in public. It links to the workflow
75
+ that does it, so the claim is checkable in one click.
76
+
77
+ ![node9 self-scanned](https://img.shields.io/badge/node9-self--scanned-a855f7?style=flat&labelColor=%231A1A2E&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNCAxNCI+PHBhdGggZmlsbD0iI0Y1RTlGRiIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDAuNCAxLjYgMi41djQuMmMwIDMuMSAyLjMgNS42IDUuNCA2LjkgMy4xLTEuMyA1LjQtMy44IDUuNC02LjlWMi41TDcgMC40Wm0wIDEuNSAzLjkgMS41djMuM2MwIDIuMy0xLjYgNC4yLTMuOSA1LjMtMi4zLTEuMS0zLjktMy0zLjktNS4zVjMuNEw3IDEuOVptMCAyLjJhMS45IDEuOSAwIDAgMC0xIDMuNXYxLjZoMlY3LjZhMS45IDEuOSAwIDAgMC0xLTMuNVoiLz48L3N2Zz4K)
78
+
79
+ ```markdown
80
+ [![node9 self-scanned](https://img.shields.io/badge/node9-self--scanned-a855f7?style=flat&labelColor=%231A1A2E&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNCAxNCI+PHBhdGggZmlsbD0iI0Y1RTlGRiIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDAuNCAxLjYgMi41djQuMmMwIDMuMSAyLjMgNS42IDUuNCA2LjkgMy4xLTEuMyA1LjQtMy44IDUuNC02LjlWMi41TDcgMC40Wm0wIDEuNSAzLjkgMS41djMuM2MwIDIuMy0xLjYgNC4yLTMuOSA1LjMtMi4zLTEuMS0zLjktMy0zLjktNS4zVjMuNEw3IDEuOVptMCAyLjJhMS45IDEuOSAwIDAgMC0xIDMuNXYxLjZoMlY3LjZhMS45IDEuOSAwIDAgMC0xLTMuNVoiLz48L3N2Zz4K)](https://github.com/node9-ai/node9-proxy/blob/main/.github/workflows/agent-security.yml)
81
+ ```
82
+
83
+ On any other project, use `scanned by node9` above. This wording is only honest here.
84
+
85
+ ## Brand
86
+
87
+ - Label background: `#1A1A2E`
88
+ - Message background: `#a855f7` (the node9 accent)
89
+ - Logo: `#F5E9FF`, a shield glyph inlined as an SVG data URI
90
+
91
+ shields.io renders an inlined SVG verbatim rather than tinting it, so the fill is baked into the
92
+ glyph. Do not change the colours or substitute a different logo. The consistency is the point: a
93
+ badge is only recognisable if it looks the same everywhere.
94
+
95
+ ## Problems
96
+
97
+ If the badge renders oddly in your README, open an issue on
98
+ [node9-ai/node9-proxy](https://github.com/node9-ai/node9-proxy/issues) with the rendered image and your README source.
@@ -0,0 +1,66 @@
1
+ # Where node9 sits among agent-security tools
2
+
3
+ Most comparisons in this space grade tools on runtime mediation: where the allow / deny decision
4
+ is computed, where it is enforced, and what evidence the tool emits. That is a fair axis and
5
+ node9 is not the strongest tool on it. This page grades on a second axis that the same
6
+ comparisons leave out: **what a tool can see before an agent ever runs**.
7
+
8
+ Every claim below about node9 is code-verified against this repository. Claims about other
9
+ tools come from their own public documentation as of September 2026; if one is wrong, open an
10
+ issue and it will be corrected.
11
+
12
+ ## Two questions, two fields
13
+
14
+ | Question | Who answers it |
15
+ | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
16
+ | At runtime, can a mediator stop this action and prove it did? | pipelock, CAPSEM, Signet, AgentMint, Cupcake, agentsh, Docker MCP gateway, Microsoft AGT, Invariant, **node9** |
17
+ | Before any run, is this repository's committed agent surface hijackable? | **node9 `scan-repo`**, and in narrow slices Snyk `mcp-scan` (MCP tool definitions) and Trail of Bits `mcp-context-protector` (MCP drift) |
18
+
19
+ The first field is crowded and well served. The second is nearly empty.
20
+
21
+ ## The committed agent surface
22
+
23
+ An agent wired into a repository leaves configuration behind: hook files, workflow YAML, MCP
24
+ server pins, instruction files. That configuration decides what an outsider can make the agent
25
+ do, and it is reviewable without running anything.
26
+
27
+ | Check | What it reads | What it flags | Nearest alternative |
28
+ | ----- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
29
+ | CI-1 | `.claude/settings.json` and hooks | committed config that pre-authorizes broad tools or runs remote hooks | none |
30
+ | CI-2 | `.github/workflows/*.yml` | an agent that an outsider can trigger with the repository's secrets in reach (`pull_request_target`, untrusted checkout, no actor gate) | none |
31
+ | CI-3 | `.mcp.json`, `.cursor/mcp.json` | unpinned or `@latest` MCP servers, inline credentials | Snyk `mcp-scan` (definitions, not pins) |
32
+ | CI-4 | workflow YAML | secrets an injected agent could exfiltrate, given the shell it has | none |
33
+ | CI-6 | `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `copilot-instructions.md`, `.windsurfrules`, `.clinerules` | poisoned or dangerous instructions, including concealed text | none |
34
+
35
+ Not built: CI-5, drift of these files over time. `mcp-context-protector` does drift for MCP tool
36
+ descriptions; nobody does it for the rest of the surface, including node9.
37
+
38
+ Runs as `npx node9-ai scan-repo <owner/repo>` on any public repository with no install and no
39
+ token, or as a GitHub Action that fails the PR. This repository runs it on itself on every pull
40
+ request.
41
+
42
+ ## Runtime: what node9 is and is not
43
+
44
+ node9 gates tool calls in the agent's own hook system (Claude Code, Codex, Copilot CLI, Gemini
45
+ CLI, Antigravity, Hermes, OpenCode, Pi) or at the MCP boundary (Cursor, Windsurf, VS Code,
46
+ Claude Desktop). Shell commands are parsed as an AST, so `$(cat ~/.aws/credentials | base64)`
47
+ is a credential read, not a string that happens to contain the word `cat`.
48
+
49
+ Where the runtime tools are ahead of node9, in their own words and ours:
50
+
51
+ | Capability | Strongest tool on it | node9 today |
52
+ | ------------------------------------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
53
+ | Offline-verifiable, signed evidence per decision | pipelock (Ed25519, hash-chained receipts) | audit log with privacy hashing; release artifacts are signed, decisions are not |
54
+ | Content scanning of HTTP and WebSocket egress | pipelock | egress is a destination gate, off by default; no wire-level content scan |
55
+ | Kernel or container boundary | agentsh, pipelock containment, CAPSEM | `node9 sandbox` is a first-phase container run |
56
+ | Prompt-injection detection on tool output | pipelock, Invariant | observed and quarantined on hook agents, redacted in place on OpenCode and Pi; not blocked before the model sees it on Claude Code or Codex |
57
+
58
+ Where node9 is ahead: per-agent wiring across twelve agents with one `node9 doctor` that tells
59
+ you which hook is actually in place, and the repository scan above.
60
+
61
+ ## How to read this page
62
+
63
+ If your risk is an agent that is already running, pick from the first field and compare
64
+ evidence models. If your risk is a repository that wires an agent into CI, there is one tool
65
+ that reads that surface, and this is it. Most teams have both risks, and node9 is the only one
66
+ of the set that tries to cover both, which is also why it is not the deepest on either.