@aimarket/warden 0.16.0 → 0.18.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.
- package/CHANGELOG.md +40 -1
- package/README-es.md +20 -15
- package/README-fr.md +20 -15
- package/README-ru.md +20 -15
- package/README-zh.md +20 -15
- package/README.md +20 -15
- package/dist/claude-hook.d.ts +4 -0
- package/dist/claude-hook.d.ts.map +1 -1
- package/dist/claude-hook.js +42 -18
- package/dist/claude-hook.js.map +1 -1
- package/dist/flow-guard.d.ts +133 -0
- package/dist/flow-guard.d.ts.map +1 -0
- package/dist/flow-guard.js +1062 -0
- package/dist/flow-guard.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-tools.d.ts.map +1 -1
- package/dist/mcp-tools.js +118 -26
- package/dist/mcp-tools.js.map +1 -1
- package/dist/review-diff.d.ts +51 -0
- package/dist/review-diff.d.ts.map +1 -0
- package/dist/review-diff.js +237 -0
- package/dist/review-diff.js.map +1 -0
- package/dist/static-scan.d.ts +1 -1
- package/dist/static-scan.d.ts.map +1 -1
- package/dist/static-scan.js +78 -2
- package/dist/static-scan.js.map +1 -1
- package/dist/wrap-cli.d.ts +3 -0
- package/dist/wrap-cli.d.ts.map +1 -1
- package/dist/wrap-cli.js +8 -2
- package/dist/wrap-cli.js.map +1 -1
- package/dist/wrap-state.d.ts.map +1 -1
- package/dist/wrap-state.js +5 -0
- package/dist/wrap-state.js.map +1 -1
- package/dist/wrap.d.ts.map +1 -1
- package/dist/wrap.js +28 -1
- package/dist/wrap.js.map +1 -1
- package/docs/flow-guard.es.md +214 -0
- package/docs/flow-guard.fr.md +220 -0
- package/docs/flow-guard.md +224 -0
- package/docs/flow-guard.ru.md +210 -0
- package/docs/flow-guard.zh.md +159 -0
- package/docs/gates.es.md +27 -3
- package/docs/gates.fr.md +28 -2
- package/docs/gates.md +26 -3
- package/docs/gates.ru.md +26 -3
- package/docs/gates.zh.md +15 -2
- package/docs/scan.es.md +30 -28
- package/docs/scan.fr.md +30 -28
- package/docs/scan.md +30 -28
- package/docs/scan.ru.md +30 -28
- package/docs/scan.zh.md +30 -28
- package/docs/scanner-comparison.es.md +289 -174
- package/docs/scanner-comparison.fr.md +292 -178
- package/docs/scanner-comparison.md +234 -140
- package/docs/scanner-comparison.ru.md +279 -165
- package/docs/scanner-comparison.zh.md +237 -90
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.18.0 — unreleased
|
|
4
|
+
|
|
5
|
+
Re-approval shows what changed, field by field.
|
|
6
|
+
|
|
7
|
+
- **`pins status|approve|revoke` and `status_mcp_server` show a field-level diff** before the full definitions: every changed value with its path, the words added `{+…+}` and removed `[-…-]` inside descriptions, schema values `before → after`, which entries of a list such as `required` or `enum` came and went, and which tools were added or removed. A change made only of digits, separators or whitespace (a live counter, a date, a limit) is marked "numbers only" and still needs approval: a number can be a limit. `status_mcp_server` returns it as `changes` (structured) and `reviewText` (escaped lines); the library exports `diffToolDefinitions`, `formatDefinitionDiff` and `wordDiff`.
|
|
8
|
+
- Why: in HISTOR's snapshot of 2026-10-20 (23,821 recorded changes over four weeks), 52% changed description text and 23% added or removed tools, while about one in eight changed nothing but numbers, whitespace or schema metadata. Two full JSON blobs per change made those look alike. The pin itself is unchanged: any change still needs a human, as before.
|
|
9
|
+
- Long rewrites fall back to "common start and end, middle replaced" instead of a quadratic word diff; a review lists at most 200 changed values per tool and then points to the full definitions.
|
|
10
|
+
|
|
11
|
+
## 0.17.0 — 2026-10-18
|
|
12
|
+
|
|
13
|
+
### Approval explanations (2026-10-18; local tests only)
|
|
14
|
+
|
|
15
|
+
- Approval reasons now identify the proposed tool and bounded destination arguments, including channel names and nested recipients. Sensitive targets are redacted; URL credentials, paths and queries, message bodies and shell programs are not included in the preview. Unrecognized target text is omitted.
|
|
16
|
+
- Fingerprint matches no longer cite the most recently read files as if they were the matching source. The prompt explicitly says that the source was not retained; destination provenance remains untracked. Outside-text context names the tools whose results were read.
|
|
17
|
+
- Decision logs include a stable reason and distinguish `approval_requested`, `refused` and `audit_only`, including `wrap --flow`. `approvalOutcome` remains `unknown`: neither an emitted request nor a subsequent tool result proves a human approved. These changes do not relax decisions or establish reduced approval fatigue. No new model or corpus measurements.
|
|
18
|
+
|
|
19
|
+
### Security audit follow-up (2026-10-18; no new benchmark runs)
|
|
20
|
+
|
|
21
|
+
- Gate opaque shell code even for named/allowed destinations; protect expanded and symlinked policy paths and Git hooks/config; reject recognized credential-file uploads.
|
|
22
|
+
- Parse URL authority, check all destinations and real target arguments, and match complete user-typed values. Body links no longer authorize unrelated recipients.
|
|
23
|
+
- Resolve contacts only through explicit `contactTools`, structured name/email records and unambiguous full names; discard implicit contact authority from older state.
|
|
24
|
+
- Record MCP JSON-RPC and tool errors as outside text; withhold responses when tracking fails, and deny pre-tool checks on corrupt state.
|
|
25
|
+
- Static ruleset v14 narrows `keyStaysLocal`: remote storage is not local custody. This changes the ruleset identity without claiming new corpus or MCPTox measurements.
|
|
26
|
+
- Pin Auten's follow-up with paired synthetic tool fixtures: a saved login name remains allowed, while a signing key supplied by value remains blocked even with the same local-use assurance. Cover advisory thresholds, both tools on one server, and a separate private-key request. No scanner rule changes or new benchmark runs.
|
|
27
|
+
- Existing AgentDojo results and policy artifacts remain unchanged and describe pre-audit builds. Only local regression tests validate this follow-up.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
The Claude Code plugin adds a flow guard at tool-call boundaries. The entries and measurements below describe its initial, pre-audit implementation.
|
|
31
|
+
|
|
32
|
+
- **Flow guard** (`src/flow-guard.ts`, plugin hooks `PreToolUse`, `PostToolUse`, `UserPromptSubmit`; CLI `warden-mcp hook pre-tool-use|post-tool-use|user-prompt-submit`). It keeps per-session state of outside text (web fetches, network commands, MCP results, foreign files, files with injection phrasing, MCP servers the session-start scan blocked or could not check) and of private data, fingerprinted on three levels: secrets, personal numbers (card, passport, account, phone) and ordinary private text. After outside text, a call that sends data out or acts for you to a destination you did not name asks; a secret leaving is denied, whatever its encoding (URL, base64, hex); a personal number you did not type asks even to a destination you named; changes to WARDEN's policy or Claude Code's hook and MCP settings are denied. A destination you named is one in what you typed this session. Modes `ask` (default), `deny`, `audit`, `off`; a user-level policy (`~/.local/state/warden/flow-policy.json`) with operator labels, trusted sources, allowed destinations and destination arguments. The plugin runs a byte-identical copy of the compiled module, checked by a test.
|
|
33
|
+
- **Measured on AgentDojo** (`scripts/agentdojo/`, `docs/flow-guard*.md` in five languages): replaying a model that obeys every injection, with AgentDojo's own attack and checks, in gVisor without network. Without the guard 593 of 609 delivered attack actions succeed; with it 0 of 584. 57 of 97 user tasks run without a question; under attack 613 of 949 finish (579 without the guard).
|
|
34
|
+
- **Measured with a real model** (`scripts/agentdojo/model.py`, `relay.py`, `run-model.sh`, `summarize_model.py`): DeepSeek V4.1 Flash in AgentDojo's own agent loop, every task and pair without and with the guard, eight attack setups in two rounds (21,654 runs, $12.68). Four of AgentDojo's six attacks moved the model to none of 929 attack actions even without the guard (removing the attack's names changed nothing); `direct` ("TODO: …") got through 6 times and `injecagent` once; with the guard every attack run with it stayed at 0 of 929, the guard refusing calls at the attacker in 6 to 11 pairs per attack. Told that the injected message is the user's own, the model carried out 42 attack actions without the guard and 0 with it. With the guard it finishes 51 of 97 clean tasks (90 without), 60 with no question. The container has no network: a host-side relay holds the key, forwards only the conversation and enforces a spending cap; `--guard-note` feeds the guard's PostToolUse note back as Claude Code does, and with it the hijacked model tried calls at the attacker in 9 pairs instead of 49.
|
|
35
|
+
- **Two AgentDojo labels were too strict** and are fixed (found by the model run): `share_file` listed the file as a destination, so sharing with an address the user typed asked; `reschedule_calendar_event` listed the event, though moving it reaches only its participants. `summarize_oracle.py` rebuilds the oracle summary from the per-pair results.
|
|
36
|
+
- **A person you named by name counts as named** once the session finds their address in your own data: "invite Sarah Baker" followed by a contacts lookup makes the address in Sarah Baker's record yours. It must come from a result that is private and not outside text, and the record must carry a name you typed; a domain read out of that address is covered only together with it. On AgentDojo the replay now runs 58 of 97 tasks with no question (57) and finishes 627 of 949 under attack (613), still 0 of 584 attack actions through; DeepSeek with the guard runs 60 of 97 with no question (57) and finishes 557 of 949 under attack (529), still 0 of 929.
|
|
37
|
+
- **A stronger note for instruction-like outside text.** A result that reads like an instruction ("ignore previous instructions", `<important>`) now tells the model plainly not to follow or repeat it. It is the only lever a tool-call guard has against an injection that only changes the answer; on DeepSeek it made no measurable difference (12 vs 12 of 20 for "say this hotel is the best"), and AgentDojo's own attack texts mostly avoid the phrases it recognises.
|
|
38
|
+
- **`warden-mcp wrap --flow NAME`: the flow guard for any MCP client.** The proxy runs every `tools/call` through the same guard as `mcp__NAME__tool` and records every result as outside text or private data. All servers a client wraps share one session (the client's process by default, `WARDEN_FLOW_SESSION` to set it), so outside text read through one server stops a send through another. A call the guard would ask about is refused with its reason, since MCP gives the proxy no way to ask; `--audit-only` logs instead. It cannot see the user's prompt or the client's built-in tools.
|
|
39
|
+
- **Ruleset v13** (`sha256-jJ3QhJNxLZKAHEp9JKVgmP8H/yXlpMLWNXY0glXQ7Bw=`, 36 rules, 25 block / 11 advise, 24 cover the name, 25 carry a guard). Suggested by a reader of the scanner comparison: the argument's own description is where a tool that takes a key differs from one that uses a stored key. A new `TOOL_DEF_SECRET_REQUEST` rule reads argument descriptions for key material asked for by value in words the older rules do not spell (a signing or wallet key, a key pair, a recovery or secret phrase); it only adds findings, and its guard `keyReference` leaves a reference to a key alone (id, name, path, public half, an argument named `*_name`/`*_id`, a key the tool creates, a key as the unit of a count). It skips tool descriptions, where the same words blocked six honest servers. Writing it found a hole every ruleset had since v4 (2026-08-24): `identifierFragment` read the full stop in "Send me your private key." as part of an identifier, so the sentence passed while the same words without the period blocked; v13 reads an edge dot or hyphen as punctuation, and the guard `keyStaysLocal` leaves alone a key that signs or that the user keeps unless something moves it. On the committed corpus v13 blocks 4 servers (v12: 3, none lost; the new one takes a new mint key pair's 64-byte secret key as an argument); on MCPTox it changes nothing (171 of 218 held-out, 0 of 45 clean, reproduced exactly). Tests: `test/ruleset-v13.test.ts`.
|
|
40
|
+
- **`status_mcp_server`, `approve_mcp_server` and `revoke_mcp_server` each describe themselves.** The three were generated from one template, so their descriptions were nearly identical and each one explained what `status_mcp_server` returns (Glama scored `status_mcp_server` 3.8/5 for it). Each now says what it does, when an operator calls it and which sibling to use instead, where it reads or writes, and that the two writes need `WARDEN_ALLOW_PIN_CHANGES=1`. Their output schemas now list every field (they were an untyped object), and `previous_pin_revision` says where its value comes from. `static_scan_tools` no longer calls the 35-rule table a 25-rule one. `lhm.plugin.json` carries the current definitions.
|
|
41
|
+
|
|
42
|
+
## 0.16.0 — 2026-10-14
|
|
4
43
|
|
|
5
44
|
For a server's publisher: declare the tool sets your server lists where HISTOR's sandbox cannot see them, in a file on your own domain that changes with every runner release.
|
|
6
45
|
|
package/README-es.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
|
|
9
9
|
<a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
|
|
10
10
|
<img src="docs/badges/deps.svg" alt="Cero dependencias de ejecución" />
|
|
11
|
-
<img src="docs/badges/tests.svg" alt="
|
|
11
|
+
<img src="docs/badges/tests.svg" alt="532 pruebas en verde" />
|
|
12
12
|
<img src="docs/badges/node.svg" alt="Node >= 20" />
|
|
13
13
|
<a href="LICENSE"><img src="docs/badges/license.svg" alt="Licencia: MIT" /></a>
|
|
14
14
|
</p>
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
**Revisa todos los servidores MCP de tu máquina.** Sin cuenta, sin clave de API, sin modelo. El único tráfico de red va a los servidores de tu configuración.
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
npx -y @aimarket/warden@0.
|
|
32
|
+
npx -y @aimarket/warden@0.18.0 scan
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
```text
|
|
36
|
-
WARDEN scan 0.
|
|
36
|
+
WARDEN scan 0.18.0 · ruleset 11 sha256-RDXs+TaQoehA… · block at high
|
|
37
37
|
read .mcp.json (claude-code, 3 servers)
|
|
38
38
|
|
|
39
39
|
✓ allow notes claude-code 1 tool · score 0.90
|
|
@@ -44,9 +44,13 @@ WARDEN scan 0.16.0 · ruleset 11 sha256-RDXs+TaQoehA… · block at high
|
|
|
44
44
|
Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Frente a otros
|
|
47
|
+
Frente a otros cuatro escáneres de código abierto sobre los mismos servidores, cada uno en un contenedor gVisor sin red: en la mitad reservada de MCPTox (un benchmark de AAAI 2026; las reglas de WARDEN se escribieron con la otra mitad) WARDEN bloquea 171 de 218 herramientas envenenadas, los demás entre 8 y 41. En 986 servidores públicos WARDEN bloquea 3 y en 14 933 paquetes de npm y PyPI, 369; mcp-shield bloquea 343 y 5354. [Método y todas las cifras](docs/scanner-comparison.es.md) · [guía de scan](docs/scan.es.md).
|
|
48
48
|
<!-- /warden-try -->
|
|
49
49
|
|
|
50
|
+
**Guardia de flujo (fuente aún sin publicar).** Comprobaciones reforzadas tras la auditoría del 2026-10-18. Las medidas anteriores (replay 0/584; modelo secuestrado 42 → 0/929) no miden este código. Sin nuevos benchmarks. [Comportamiento y límites actuales](docs/flow-guard.es.md).
|
|
51
|
+
|
|
52
|
+
Las cifras de corpus y MCPTox del escáner estático también corresponden a rulesets anteriores; v14 solo tiene pruebas locales de regresión, sin nuevo recorrido del corpus.
|
|
53
|
+
|
|
50
54
|
> [Seguridad y migración de 0.7.0](docs/security-hardening.es.md): `vetLaunch`, durable pins, anti-rollback, ruleset v6, runtime revalidation.
|
|
51
55
|
|
|
52
56
|
**Un servidor MCP. Cortafuegos de las definiciones de herramienta anunciadas. Biblioteca incluida.**
|
|
@@ -86,14 +90,14 @@ delante de tu propio host MCP sin adoptar un agente.
|
|
|
86
90
|
"mcpServers": {
|
|
87
91
|
"filesystem": {
|
|
88
92
|
"command": "npx",
|
|
89
|
-
"args": ["-y", "@aimarket/warden@0.
|
|
93
|
+
"args": ["-y", "@aimarket/warden@0.18.0", "wrap", "--id", "filesystem", "--",
|
|
90
94
|
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
```
|
|
95
99
|
|
|
96
|
-
Especifique siempre `--id`: sin él, cambiar los argumentos crea otra identidad y otro primer contacto. Con un ID estable, cambiar el comando o una ruta produce `SERVER_IDENTITY_DRIFT`. El hijo hereda el entorno, excluido de la identidad. `npm install -g @aimarket/warden@0.
|
|
100
|
+
Especifique siempre `--id`: sin él, cambiar los argumentos crea otra identidad y otro primer contacto. Con un ID estable, cambiar el comando o una ruta produce `SERVER_IDENTITY_DRIFT`. El hijo hereda el entorno, excluido de la identidad. `npm install -g @aimarket/warden@0.18.0` y el comando `warden-mcp` evitan arranques fríos repetidos de `npx`.
|
|
97
101
|
|
|
98
102
|
La política predeterminada bloquea **todo el servidor** desde gravedad high, fija definiciones y permite servidores declarados. No hay modo parcial. La primera comprobación correcta crea un pin TOFU persistente. Cualquier cambio posterior, incluso inocuo, exige aprobación humana. Con la política explícita `{"pinToolDefs":false}`, los cambios limpios se notifican tras verificarlos. Una notificación sin cambios también pasa tras verificarse.
|
|
99
103
|
|
|
@@ -103,7 +107,7 @@ warden-mcp pins approve --id filesystem
|
|
|
103
107
|
warden-mcp pins revoke --id filesystem
|
|
104
108
|
```
|
|
105
109
|
|
|
106
|
-
Ejecute los comandos de pins en una terminal: los tres exigen TTY en stdin. approve/revoke muestran las definiciones anteriores y nuevas y piden escribir acción e ID. La escritura compara tanto el candidato observado como el pin anterior. Revocar conserva una denegación hasta aprobar de nuevo. Si el cambio de identidad impidió arrancar, se muestra el comando nuevo con las definiciones **anteriores**; el próximo arranque verifica las nuevas. TTY es una barrera de interacción, no autenticación: un proceso local puede crear un PTY o editar el estado.
|
|
110
|
+
Ejecute los comandos de pins en una terminal: los tres exigen TTY en stdin. approve/revoke muestran qué cambió campo por campo (palabras añadidas `{+…+}` y quitadas `[-…-]` en las descripciones; valores del esquema `antes → después`; un cambio solo de números se marca, nunca se omite: un número puede ser un límite), después las definiciones completas anteriores y nuevas, y piden escribir acción e ID. `status_mcp_server` devuelve lo mismo en `changes` y `reviewText`. La escritura compara tanto el candidato observado como el pin anterior. Revocar conserva una denegación hasta aprobar de nuevo. Si el cambio de identidad impidió arrancar, se muestra el comando nuevo con las definiciones **anteriores**; el próximo arranque verifica las nuevas. TTY es una barrera de interacción, no autenticación: un proceso local puede crear un PTY o editar el estado.
|
|
107
111
|
|
|
108
112
|
Claude Desktop en macOS: `~/Library/Logs/Claude/mcp-server-<nombre>.log`. En Cursor: [View → Output → MCP Logs](https://prod.cursor.com/help/customization/mcp); los archivos de sesión están en `~/Library/Application Support/Cursor/logs/` (nombres variables según versión). Un bloqueo devuelve error JSON-RPC, nunca una lista vacía. Salidas: `2` para opciones/política inválidas, `3` para bloqueo de arranque, o el código del hijo. El error incluye códigos de reglas y `pins status`.
|
|
109
113
|
|
|
@@ -118,12 +122,12 @@ Claude Desktop en macOS: `~/Library/Logs/Claude/mcp-server-<nombre>.log`. En Cur
|
|
|
118
122
|
## Analiza todos los servidores que inician tus clientes
|
|
119
123
|
|
|
120
124
|
```bash
|
|
121
|
-
npx -y @aimarket/warden@0.
|
|
125
|
+
npx -y @aimarket/warden@0.18.0 scan
|
|
122
126
|
```
|
|
123
127
|
|
|
124
|
-
Lee las configuraciones MCP de Claude Code, Claude Desktop, Cursor, VS Code y Windsurf, se conecta a cada servidor que inician y revisa las definiciones de herramientas antes de que un modelo las vea. Imprime una tabla, JSON, SARIF o Markdown, y sale con 1 cuando bloquea un servidor; `--no-launch` no inicia nada. En un repositorio, `warden.lock.json` convierte un cambio en las definiciones en un diff revisable, y la CI falla ante un servidor nuevo o modificado. También como GitHub Action (`uses: alexar76/warden@v0.
|
|
128
|
+
Lee las configuraciones MCP de Claude Code, Claude Desktop, Cursor, VS Code y Windsurf, se conecta a cada servidor que inician y revisa las definiciones de herramientas antes de que un modelo las vea. Imprime una tabla, JSON, SARIF o Markdown, y sale con 1 cuando bloquea un servidor; `--no-launch` no inicia nada. En un repositorio, `warden.lock.json` convierte un cambio en las definiciones en un diff revisable, y la CI falla ante un servidor nuevo o modificado. También como GitHub Action (`uses: alexar76/warden@v0.18.0`), hooks de pre-commit y plugin de Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` pregunta al registro público HISTOR si un servidor te sirve lo mismo que a todos; para un servidor remoto envía el endpoint y un digest; para un servidor stdio que arranca desde npm o PyPI, el nombre del paquete (`npm:<nombre>`, `pypi:<nombre>`, que HISTOR ejecuta en un sandbox gVisor) y un digest; nunca el texto de las herramientas. Un clasificador opcional (`--classifier-url`, `--classifier-model`) añade la lectura de un modelo que tú eliges, local o alojado, para lo que ninguna regla nombra. Consulta la [guía de scan](docs/scan.es.md). Cómo se compara con otros dos escáneres sobre los mismos servidores: [comparación de escáneres](docs/scanner-comparison.es.md).
|
|
125
129
|
|
|
126
|
-
**Para el editor de un servidor.** Si tu servidor lista otras herramientas donde está instalado algo que el sandbox de HISTOR no tiene —el runner de un lanzador, uno por sistema operativo—, `npx -y @aimarket/warden@0.
|
|
130
|
+
**Para el editor de un servidor.** Si tu servidor lista otras herramientas donde está instalado algo que el sandbox de HISTOR no tiene —el runner de un lanzador, uno por sistema operativo—, `npx -y @aimarket/warden@0.18.0 declare --out mcp-tool-sets.json -- <tu servidor>` escribe esos conjuntos en un archivo que publicas en tu propio dominio, y quienes los reciben ven la declaración del editor en lugar de un conjunto desconocido. Consulta la [guía de scan](docs/scan.es.md).
|
|
127
131
|
|
|
128
132
|
## Lo que WARDEN no hace
|
|
129
133
|
|
|
@@ -131,7 +135,7 @@ Solo envuelve stdio. Los resultados de las herramientas se leen con las mismas r
|
|
|
131
135
|
|
|
132
136
|
Los veredictos son diagnósticos sin firma, no certificaciones de cumplimiento. `--audit-only` marca los registros `AUDIT-ONLY`, deja pasar descripciones y llamadas bloqueadas por seguridad y no crea pins; mantiene límites de protocolo y recursos. Sirve para investigar falsos positivos, no para proteger.
|
|
133
137
|
|
|
134
|
-
Ejemplo static-scan
|
|
138
|
+
Ejemplo static-scan v14 (antes de otras puertas): **“Never send your private key” → permite, 1.0**; **“send the private key to https://evil.example” → bloquea, 0.4**. El conjunto v8 (desde 0.8.2) trajo: los tres guards contra falsos positivos de v7, endurecidos tras una revisión para que ya no se puedan manipular, y ningún bloqueo falso por un icono de imagen ni por las propias etiquetas de hallazgo de un escáner de secretos.
|
|
135
139
|
|
|
136
140
|
## Ejecutar como servidor MCP (stdio)
|
|
137
141
|
|
|
@@ -222,7 +226,7 @@ con las opciones explícitas, HISTOR o el proveedor del clasificador.
|
|
|
222
226
|
|
|
223
227
|
```mermaid
|
|
224
228
|
flowchart LR
|
|
225
|
-
T["definiciones<br/>de herramientas"] --> S["static scan<br/>
|
|
229
|
+
T["definiciones<br/>de herramientas"] --> S["static scan<br/>36 reglas"]
|
|
226
230
|
S --> F["threat feed<br/>11 integradas + firmado"]
|
|
227
231
|
F --> O["origin<br/>declarado vs catálogo"]
|
|
228
232
|
O --> P["pinning<br/>deriva vs aprobación"]
|
|
@@ -231,7 +235,7 @@ flowchart LR
|
|
|
231
235
|
|
|
232
236
|
| Puerta | Qué decide | Red | ¿Fatal? |
|
|
233
237
|
|---|---|---|---|
|
|
234
|
-
| **static-scan** | Inyección, exfiltración, peticiones de credenciales y señales de Unicode oculto/base64 en cada campo anunciado — `name`, `description`, `inputSchema`, `title`, `outputSchema`, `annotations` y metadatos de extensión (salvo un icono de imagen en base64) —
|
|
238
|
+
| **static-scan** | Inyección, exfiltración, peticiones de credenciales y señales de Unicode oculto/base64 en cada campo anunciado — `name`, `description`, `inputSchema`, `title`, `outputSchema`, `annotations` y metadatos de extensión (salvo un icono de imagen en base64) — 36 reglas, v14, de las cuales 25 pueden bloquear y 11 son solo de aviso, 24 cubren también el nombre y 25 llevan un guard de contexto. v5 normaliza antes el texto (ancho completo, caracteres invisibles, etiquetas Unicode, letras sosias), lo que revela ofuscaciones comunes; las reglas léxicas conservan sus límites lingüísticos | ninguna | no |
|
|
235
239
|
| **threat-feed** | Identidad de servidor o herramienta conocida como maliciosa: 11 registros integrados más un feed firmado opcional | solo la descarga del feed | sí, para un `critical` con alcance de servidor |
|
|
236
240
|
| **origin** | Si el operador declaró este servidor o llegó desde un catálogo remoto | ninguna | sí, con `allowUnknownServers: false` |
|
|
237
241
|
| **pinning** | Si las definiciones de herramientas siguen coincidiendo con lo que el usuario aprobó | ninguna | sí, con `pinToolDefs: true` |
|
|
@@ -317,7 +321,8 @@ comprobarlas: [Identidades ERC-8004](https://github.com/alexar76/aicom/blob/main
|
|
|
317
321
|
| [Analiza tus configuraciones](docs/scan.es.md) | `scan`, el archivo lock, la GitHub Action, los hooks de pre-commit, el plugin de Claude Code y HISTOR |
|
|
318
322
|
| [Guía de integración](docs/integration.es.md) | Cómo conectar WARDEN a tu propio host MCP, elecciones de política y qué registrar |
|
|
319
323
|
| [Estudio de campo: 1 108 servidores MCP públicos](docs/mcp-survey.es.md) | Qué decidió WARDEN sobre definiciones de herramienta reales de terceros — 50 servidores bloqueados, 4 sustentados, y las seis formas en que el resto se equivocó |
|
|
320
|
-
| [Comparación de escáneres](docs/scanner-comparison.es.md) | WARDEN, mcp-audit
|
|
324
|
+
| [Comparación de escáneres](docs/scanner-comparison.es.md) | WARDEN, mcp-audit, mcp-shield, truecopy y mcpsentry sobre los mismos servidores, sobre 14 933 paquetes de npm y PyPI y sobre el benchmark MCPTox, con cada juicio, el manifiesto y el banco de pruebas |
|
|
325
|
+
| [Guardián de flujos](docs/flow-guard.es.md) | La protección en ejecución del plugin de Claude Code: texto ajeno, datos privados, llamadas salientes; la medición en AgentDojo y sus límites |
|
|
321
326
|
| [Glama / Docker](docs/GLAMA.md) | MCP stdio, health check, Build steps / CMD |
|
|
322
327
|
| [Security](SECURITY.md) | Cómo informar de un bypass del cortafuegos |
|
|
323
328
|
| [Contributing](CONTRIBUTING.md) | Regla de cero dependencias, PRs de la tabla de reglas |
|
|
@@ -341,7 +346,7 @@ comprobarlas: [Identidades ERC-8004](https://github.com/alexar76/aicom/blob/main
|
|
|
341
346
|
## Desarrollo
|
|
342
347
|
|
|
343
348
|
```bash
|
|
344
|
-
npm install && npm run build && npm test #
|
|
349
|
+
npm install && npm run build && npm test # 532 pruebas
|
|
345
350
|
```
|
|
346
351
|
|
|
347
352
|
`test/packaging.test.ts` es lo que mantiene honesto el titular: falla si aparece una dependencia de
|
package/README-fr.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
|
|
9
9
|
<a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="version npm" /></a>
|
|
10
10
|
<img src="docs/badges/deps.svg" alt="Zéro dépendance d'exécution" />
|
|
11
|
-
<img src="docs/badges/tests.svg" alt="
|
|
11
|
+
<img src="docs/badges/tests.svg" alt="532 tests au vert" />
|
|
12
12
|
<img src="docs/badges/node.svg" alt="Node >= 20" />
|
|
13
13
|
<a href="LICENSE"><img src="docs/badges/license.svg" alt="Licence : MIT" /></a>
|
|
14
14
|
</p>
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
**Vérifiez tous les serveurs MCP de votre machine.** Pas de compte, pas de clé d’API, pas de modèle. Le seul trafic réseau va vers les serveurs de votre configuration.
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
npx -y @aimarket/warden@0.
|
|
32
|
+
npx -y @aimarket/warden@0.18.0 scan
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
```text
|
|
36
|
-
WARDEN scan 0.
|
|
36
|
+
WARDEN scan 0.18.0 · ruleset 11 sha256-RDXs+TaQoehA… · block at high
|
|
37
37
|
read .mcp.json (claude-code, 3 servers)
|
|
38
38
|
|
|
39
39
|
✓ allow notes claude-code 1 tool · score 0.90
|
|
@@ -44,9 +44,13 @@ WARDEN scan 0.16.0 · ruleset 11 sha256-RDXs+TaQoehA… · block at high
|
|
|
44
44
|
Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Face à
|
|
47
|
+
Face à quatre autres scanners open source sur les mêmes serveurs, chacun dans un conteneur gVisor sans réseau : sur la moitié réservée de MCPTox (un benchmark d’AAAI 2026 ; les règles de WARDEN ont été écrites à partir de l’autre moitié), WARDEN bloque 171 des 218 outils empoisonnés, les autres entre 8 et 41. Sur 986 serveurs publics, WARDEN en bloque 3 et sur 14 933 paquets npm et PyPI, 369 ; mcp-shield en bloque 343 et 5 354. [Méthode et tous les chiffres](docs/scanner-comparison.fr.md) · [guide de scan](docs/scan.fr.md).
|
|
48
48
|
<!-- /warden-try -->
|
|
49
49
|
|
|
50
|
+
**Garde de flux (source non publiée).** Vérifications renforcées après l’audit du 2026-10-18. Les anciennes mesures (replay 0/584 ; modèle détourné 42 → 0/929) ne mesurent pas ce code. Aucun nouveau benchmark. [Comportement et limites actuels](docs/flow-guard.fr.md).
|
|
51
|
+
|
|
52
|
+
Les chiffres corpus et MCPTox du scanner statique concernent aussi des rulesets antérieurs ; v14 a uniquement des tests locaux de régression, sans nouveau parcours du corpus.
|
|
53
|
+
|
|
50
54
|
> [Sécurité et migration 0.7.0](docs/security-hardening.fr.md): `vetLaunch`, durable pins, anti-rollback, ruleset v6, runtime revalidation.
|
|
51
55
|
|
|
52
56
|
**Un serveur MCP. Pare-feu des définitions d'outils annoncées. Bibliothèque incluse.**
|
|
@@ -86,14 +90,14 @@ placer devant votre propre hôte MCP sans adopter d'agent.
|
|
|
86
90
|
"mcpServers": {
|
|
87
91
|
"filesystem": {
|
|
88
92
|
"command": "npx",
|
|
89
|
-
"args": ["-y", "@aimarket/warden@0.
|
|
93
|
+
"args": ["-y", "@aimarket/warden@0.18.0", "wrap", "--id", "filesystem", "--",
|
|
90
94
|
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
```
|
|
95
99
|
|
|
96
|
-
Spécifiez toujours `--id` : sans cet identifiant, modifier les arguments crée une nouvelle identité et un premier contact. Un ID stable transforme un changement de commande ou de chemin en `SERVER_IDENTITY_DRIFT`. Le processus enfant hérite de l’environnement, exclu de l’identité. `npm install -g @aimarket/warden@0.
|
|
100
|
+
Spécifiez toujours `--id` : sans cet identifiant, modifier les arguments crée une nouvelle identité et un premier contact. Un ID stable transforme un changement de commande ou de chemin en `SERVER_IDENTITY_DRIFT`. Le processus enfant hérite de l’environnement, exclu de l’identité. `npm install -g @aimarket/warden@0.18.0` puis `warden-mcp` évitent les démarrages à froid répétés de `npx`.
|
|
97
101
|
|
|
98
102
|
Par défaut, **tout le serveur** est bloqué dès la gravité high, les définitions sont épinglées et les serveurs déclarés sont autorisés. Aucun mode partiel. La première vérification réussie crée une empreinte TOFU persistante. Tout changement ultérieur, même bénin, exige une approbation humaine. Avec `{"pinToolDefs":false}` explicitement, les changements sains sont notifiés après vérification. Une notification sans modification passe aussi après vérification.
|
|
99
103
|
|
|
@@ -103,7 +107,7 @@ warden-mcp pins approve --id filesystem
|
|
|
103
107
|
warden-mcp pins revoke --id filesystem
|
|
104
108
|
```
|
|
105
109
|
|
|
106
|
-
Les trois commandes pins exigent un TTY sur stdin. approve/revoke montrent les anciennes et nouvelles
|
|
110
|
+
Les trois commandes pins exigent un TTY sur stdin. approve/revoke montrent ce qui a changé champ par champ (mots ajoutés `{+…+}` et retirés `[-…-]` dans les descriptions ; valeurs du schéma `avant → après` ; un changement fait uniquement de chiffres est signalé, jamais ignoré : un chiffre peut être une limite), puis les définitions complètes anciennes et nouvelles, et demandent de saisir action et ID. `status_mcp_server` renvoie la même chose dans `changes` et `reviewText`. L’écriture compare le candidat observé et l’empreinte précédente. La révocation conserve un refus jusqu’à nouvelle approbation. Si la dérive d’identité a empêché le lancement, la nouvelle commande est présentée avec les **anciennes** définitions ; le prochain lancement vérifie les nouvelles. Le TTY impose une interaction, pas une authentification : un processus local peut créer un PTY ou modifier les fichiers.
|
|
107
111
|
|
|
108
112
|
Claude Desktop sur macOS : `~/Library/Logs/Claude/mcp-server-<nom>.log`. Cursor : [View → Output → MCP Logs](https://prod.cursor.com/help/customization/mcp), fichiers de session sous `~/Library/Application Support/Cursor/logs/` (noms variables suivant la version). Un refus produit une erreur JSON-RPC, jamais une liste vide. Codes de sortie : `2` pour options/politique invalides, `3` pour refus au lancement, sinon celui de l’enfant. L’erreur indique les règles et `pins status`.
|
|
109
113
|
|
|
@@ -118,12 +122,12 @@ Claude Desktop sur macOS : `~/Library/Logs/Claude/mcp-server-<nom>.log`. Cursor
|
|
|
118
122
|
## Analyser tous les serveurs que démarrent vos clients
|
|
119
123
|
|
|
120
124
|
```bash
|
|
121
|
-
npx -y @aimarket/warden@0.
|
|
125
|
+
npx -y @aimarket/warden@0.18.0 scan
|
|
122
126
|
```
|
|
123
127
|
|
|
124
|
-
Lit les configurations MCP de Claude Code, Claude Desktop, Cursor, VS Code et Windsurf, se connecte à chaque serveur qu’elles démarrent et vérifie les définitions d’outils avant qu’un modèle ne les voie. Affiche un tableau, du JSON, du SARIF ou du Markdown, et sort avec 1 quand un serveur est bloqué ; `--no-launch` ne démarre rien. Dans un dépôt, `warden.lock.json` transforme un changement de définitions en diff relisible, et la CI échoue sur un serveur nouveau ou modifié. Existe aussi en GitHub Action (`uses: alexar76/warden@v0.
|
|
128
|
+
Lit les configurations MCP de Claude Code, Claude Desktop, Cursor, VS Code et Windsurf, se connecte à chaque serveur qu’elles démarrent et vérifie les définitions d’outils avant qu’un modèle ne les voie. Affiche un tableau, du JSON, du SARIF ou du Markdown, et sort avec 1 quand un serveur est bloqué ; `--no-launch` ne démarre rien. Dans un dépôt, `warden.lock.json` transforme un changement de définitions en diff relisible, et la CI échoue sur un serveur nouveau ou modifié. Existe aussi en GitHub Action (`uses: alexar76/warden@v0.18.0`), en hooks pre-commit et en plugin Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` demande au journal public HISTOR si un serveur vous sert ce qu’il sert à tout le monde ; pour un serveur distant il envoie l’endpoint et un condensé, pour un serveur stdio lancé depuis npm ou PyPI le nom du paquet (`npm:<nom>`, `pypi:<nom>`, qu’HISTOR exécute dans un bac à sable gVisor) et un condensé — jamais le texte des outils. Un classificateur optionnel (`--classifier-url`, `--classifier-model`) ajoute la lecture d'un modèle que vous choisissez, local ou hébergé, pour ce qu'aucune règle ne nomme. Voir le [guide de scan](docs/scan.fr.md). Comment il se compare à deux autres scanners sur les mêmes serveurs : [comparaison de scanners](docs/scanner-comparison.fr.md).
|
|
125
129
|
|
|
126
|
-
**Pour l’éditeur d’un serveur.** Si votre serveur liste d’autres outils là où est installé ce que le bac à sable d’HISTOR n’a pas — le runner d’un lanceur, un par système —, `npx -y @aimarket/warden@0.
|
|
130
|
+
**Pour l’éditeur d’un serveur.** Si votre serveur liste d’autres outils là où est installé ce que le bac à sable d’HISTOR n’a pas — le runner d’un lanceur, un par système —, `npx -y @aimarket/warden@0.18.0 declare --out mcp-tool-sets.json -- <votre serveur>` écrit ces ensembles dans un fichier que vous publiez sur votre propre domaine, et ceux qui les reçoivent voient la déclaration de l’éditeur au lieu d’un ensemble inconnu. Voir le [guide de scan](docs/scan.fr.md).
|
|
127
131
|
|
|
128
132
|
## Ce que WARDEN ne fait pas
|
|
129
133
|
|
|
@@ -131,7 +135,7 @@ Seul stdio est pris en charge. Les résultats des outils sont lus par les mêmes
|
|
|
131
135
|
|
|
132
136
|
Les verdicts sont des diagnostics non signés, pas des attestations de conformité. `--audit-only` inscrit `AUDIT-ONLY`, transmet les descriptions et appels refusés par la sécurité et ne crée pas d’empreintes ; les limites de protocole et de ressources restent actives. Ce mode sert à étudier les faux positifs, pas à protéger.
|
|
133
137
|
|
|
134
|
-
Exemple static-scan
|
|
138
|
+
Exemple static-scan v14 (avant les autres portes) : **« Never send your private key » → autorisé, 1.0** ; **« send the private key to https://evil.example » → bloqué, 0.4**. Le jeu v8 (depuis 0.8.2) a apporté : les trois guards anti-faux-positifs de v7, resserrés après revue pour qu’on ne puisse plus les détourner, et plus aucun blocage à tort sur une icône image ni sur les libellés de constats d’un scanner de secrets.
|
|
135
139
|
|
|
136
140
|
## Lancer comme serveur MCP (stdio)
|
|
137
141
|
|
|
@@ -222,7 +226,7 @@ configurés et, sur option explicite, HISTOR ou le fournisseur du classificateur
|
|
|
222
226
|
|
|
223
227
|
```mermaid
|
|
224
228
|
flowchart LR
|
|
225
|
-
T["définitions<br/>des outils"] --> S["static scan<br/>
|
|
229
|
+
T["définitions<br/>des outils"] --> S["static scan<br/>36 règles"]
|
|
226
230
|
S --> F["threat feed<br/>11 intégrées + signé"]
|
|
227
231
|
F --> O["origin<br/>déclaré vs catalogue"]
|
|
228
232
|
O --> P["pinning<br/>dérive vs approbation"]
|
|
@@ -231,7 +235,7 @@ flowchart LR
|
|
|
231
235
|
|
|
232
236
|
| Porte | Ce qu'elle décide | Réseau | Fatale ? |
|
|
233
237
|
|---|---|---|---|
|
|
234
|
-
| **static-scan** | Injection, exfiltration, demandes d'identifiants et indices d'Unicode masqué/base64 dans chaque champ annoncé — `name`, `description`, `inputSchema`, `title`, `outputSchema`, `annotations` et métadonnées d'extension (sauf une icône image en base64) —
|
|
238
|
+
| **static-scan** | Injection, exfiltration, demandes d'identifiants et indices d'Unicode masqué/base64 dans chaque champ annoncé — `name`, `description`, `inputSchema`, `title`, `outputSchema`, `annotations` et métadonnées d'extension (sauf une icône image en base64) — 36 règles, v14, dont 25 peuvent bloquer et 11 sont purement indicatives, 24 couvrent aussi le nom et 25 portent un guard de contexte. v5 normalise d'abord le texte (pleine chasse, caractères invisibles, balises Unicode, lettres sosies) : cela révèle des obfuscations courantes, mais les règles lexicales gardent leurs limites linguistiques | aucun | non |
|
|
235
239
|
| **threat-feed** | Identité de serveur ou outil connu comme malveillant : 11 enregistrements intégrés plus un feed signé optionnel | seulement le téléchargement du feed | oui, pour un `critical` de portée serveur |
|
|
236
240
|
| **origin** | Si l'opérateur a déclaré ce serveur ou s'il provient d'un catalogue distant | aucun | oui, avec `allowUnknownServers: false` |
|
|
237
241
|
| **pinning** | Si les définitions d'outils correspondent encore à ce que l'utilisateur a approuvé | aucun | oui, avec `pinToolDefs: true` |
|
|
@@ -318,7 +322,8 @@ transactions et la façon de les vérifier :
|
|
|
318
322
|
| [Analyser vos configurations](docs/scan.fr.md) | `scan`, le fichier lock, la GitHub Action, les hooks pre-commit, le plugin Claude Code et HISTOR |
|
|
319
323
|
| [Guide d'intégration](docs/integration.fr.md) | Brancher WARDEN sur votre propre hôte MCP, choix de politique, et quoi consigner |
|
|
320
324
|
| [Étude de terrain : 1 108 serveurs MCP publics](docs/mcp-survey.fr.md) | Ce que WARDEN a décidé sur de vraies définitions d'outil tierces — 50 serveurs bloqués, 4 étayés, et les six façons dont le reste était faux |
|
|
321
|
-
| [Comparaison de scanners](docs/scanner-comparison.fr.md) | WARDEN, mcp-audit
|
|
325
|
+
| [Comparaison de scanners](docs/scanner-comparison.fr.md) | WARDEN, mcp-audit, mcp-shield, truecopy et mcpsentry sur les mêmes serveurs, sur 14 933 paquets npm et PyPI et sur le benchmark MCPTox, avec chaque jugement, le manifeste et le banc d’essai |
|
|
326
|
+
| [Garde de flux](docs/flow-guard.fr.md) | La protection à l’exécution du plugin Claude Code : texte extérieur, données privées, appels sortants ; la mesure sur AgentDojo et ses limites |
|
|
322
327
|
| [Glama / Docker](docs/GLAMA.md) | MCP stdio, health check, Build steps / CMD |
|
|
323
328
|
| [Security](SECURITY.md) | Signaler un contournement du pare-feu |
|
|
324
329
|
| [Contributing](CONTRIBUTING.md) | Règle zéro dépendance, PRs de table de règles |
|
|
@@ -342,7 +347,7 @@ transactions et la façon de les vérifier :
|
|
|
342
347
|
## Développement
|
|
343
348
|
|
|
344
349
|
```bash
|
|
345
|
-
npm install && npm run build && npm test #
|
|
350
|
+
npm install && npm run build && npm test # 532 tests
|
|
346
351
|
```
|
|
347
352
|
|
|
348
353
|
`test/packaging.test.ts` est ce qui tient l'accroche honnête : il échoue si une dépendance d'exécution
|
package/README-ru.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
|
|
9
9
|
<a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
|
|
10
10
|
<img src="docs/badges/deps.svg" alt="Zero runtime dependencies" />
|
|
11
|
-
<img src="docs/badges/tests.svg" alt="
|
|
11
|
+
<img src="docs/badges/tests.svg" alt="532 tests passing" />
|
|
12
12
|
<img src="docs/badges/node.svg" alt="Node >= 20" />
|
|
13
13
|
<a href="LICENSE"><img src="docs/badges/license.svg" alt="License: MIT" /></a>
|
|
14
14
|
</p>
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
**Проверьте все MCP-серверы на своей машине.** Без аккаунта, без API-ключа, без модели. Сетевой трафик идёт только к серверам из вашего конфига.
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
npx -y @aimarket/warden@0.
|
|
32
|
+
npx -y @aimarket/warden@0.18.0 scan
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
```text
|
|
36
|
-
WARDEN scan 0.
|
|
36
|
+
WARDEN scan 0.18.0 · ruleset 11 sha256-RDXs+TaQoehA… · block at high
|
|
37
37
|
read .mcp.json (claude-code, 3 servers)
|
|
38
38
|
|
|
39
39
|
✓ allow notes claude-code 1 tool · score 0.90
|
|
@@ -44,9 +44,13 @@ WARDEN scan 0.16.0 · ruleset 11 sha256-RDXs+TaQoehA… · block at high
|
|
|
44
44
|
Details: warden-mcp scan --json, or --markdown FILE. To review a changed server: warden-mcp scan --lock warden.lock.json --update-lock.
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Рядом с
|
|
47
|
+
Рядом с четырьмя другими открытыми сканерами на одних и тех же серверах, каждый в контейнере gVisor без сети: на отложенной половине MCPTox (бенчмарк AAAI 2026; правила WARDEN писались по другой половине) WARDEN блокирует 171 отравленный инструмент из 218, остальные — от 8 до 41. На 986 публичных серверах WARDEN блокирует 3, на 14 933 пакетах npm и PyPI — 369; mcp-shield — 343 и 5 354. [Методика и все цифры](docs/scanner-comparison.ru.md) · [руководство по scan](docs/scan.ru.md).
|
|
48
48
|
<!-- /warden-try -->
|
|
49
49
|
|
|
50
|
+
**Страж потоков (ещё не выпущен).** Проверки вызовов после внешнего текста усилены по аудиту 2026-10-18. Старые измерения (replay 0/584; модель с навязанным подчинением 42 → 0/929) относятся к коду до исправлений. Новых прогонов не делали. [Текущее поведение и ограничения](docs/flow-guard.ru.md).
|
|
51
|
+
|
|
52
|
+
Цифры корпуса и MCPTox для статического сканера тоже относятся к ранее измеренным ruleset; для v14 выполнены только локальные регрессионные тесты, без нового прогона корпуса.
|
|
53
|
+
|
|
50
54
|
> [Изменения безопасности 0.7.0 и миграция](docs/security-hardening.ru.md): `vetLaunch`, durable pins, anti-rollback, ruleset v6, runtime revalidation.
|
|
51
55
|
|
|
52
56
|
**Один MCP-сервер. Файрвол для объявленных определений инструментов. Библиотека в комплекте.**
|
|
@@ -86,7 +90,7 @@ MCP-сервер добавляет другие `node:` builtins (`fs`, `path`,
|
|
|
86
90
|
"mcpServers": {
|
|
87
91
|
"filesystem": {
|
|
88
92
|
"command": "npx",
|
|
89
|
-
"args": ["-y", "@aimarket/warden@0.
|
|
93
|
+
"args": ["-y", "@aimarket/warden@0.18.0", "wrap", "--id", "filesystem", "--",
|
|
90
94
|
"npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
|
|
91
95
|
}
|
|
92
96
|
}
|
|
@@ -95,7 +99,7 @@ MCP-сервер добавляет другие `node:` builtins (`fs`, `path`,
|
|
|
95
99
|
|
|
96
100
|
Для обязательного утверждения первого контакта добавьте к `wrap` флаг `--require-approval`. Определения не попадут модели до `warden-mcp pins approve --id filesystem` в терминале оператора. Любое изменение полей или идентичности запуска требует нового утверждения; автоматические и старые pins не подходят. Подробнее: [граница допуска, не зависящая от языка](docs/security-hardening-language-boundary.md).
|
|
97
101
|
|
|
98
|
-
Всегда задавайте `--id`: без него изменение аргументов создаёт новую идентичность и новый первый контакт. Со стабильным ID смена команды или пути даёт `SERVER_IDENTITY_DRIFT`. Дочерний процесс наследует окружение; оно не входит в идентичность. Чтобы избежать холодного старта `npx`, установите глобально: `npm install -g @aimarket/warden@0.
|
|
102
|
+
Всегда задавайте `--id`: без него изменение аргументов создаёт новую идентичность и новый первый контакт. Со стабильным ID смена команды или пути даёт `SERVER_IDENTITY_DRIFT`. Дочерний процесс наследует окружение; оно не входит в идентичность. Чтобы избежать холодного старта `npx`, установите глобально: `npm install -g @aimarket/warden@0.18.0`, затем команда `warden-mcp`.
|
|
99
103
|
|
|
100
104
|
По умолчанию блокируется **весь сервер** при находке high, определения закрепляются пинами, объявленные оператором серверы разрешены. Частичного режима нет. Первая успешная проверка создаёт постоянный TOFU-пин. Любые последующие изменения, даже безопасные, требуют ручного одобрения. При явной политике `{"pinToolDefs":false}` уведомления о безопасных изменениях проходят после проверки. Уведомление без изменения списка также проходит после проверки.
|
|
101
105
|
|
|
@@ -105,7 +109,7 @@ warden-mcp pins approve --id filesystem
|
|
|
105
109
|
warden-mcp pins revoke --id filesystem
|
|
106
110
|
```
|
|
107
111
|
|
|
108
|
-
Команды пинов запускаются в терминале: все три требуют TTY на stdin. approve/revoke
|
|
112
|
+
Команды пинов запускаются в терминале: все три требуют TTY на stdin. approve/revoke показывают, что изменилось, по полям (слова, добавленные `{+…+}` и удалённые `[-…-]` в описаниях; значения схемы `было → стало`; изменение только в цифрах помечено, но не пропускается: цифра может быть лимитом), затем полные старые и новые определения, и требуют ввести действие и ID. `status_mcp_server` возвращает то же в полях `changes` и `reviewText`. Перед записью повторно сверяются наблюдаемый снимок и предыдущий пин. Отзыв сохраняет запрет до нового одобрения. Если дрейф идентичности не дал запустить сервер, показываются новая команда и **старый** снимок инструментов; после одобрения новый список всё равно проверяется. TTY — защита от случайного неинтерактивного запуска, а не аутентификация: локальный процесс может создать PTY или изменить файлы состояния.
|
|
109
113
|
|
|
110
114
|
Логи Claude Desktop на macOS: `~/Library/Logs/Claude/mcp-server-<имя>.log`. В Cursor откройте [View → Output → MCP Logs](https://prod.cursor.com/help/customization/mcp); файлы сеанса на macOS находятся в `~/Library/Application Support/Cursor/logs/` (названия каналов и файлов зависят от версии). При блокировке возвращается JSON-RPC ошибка, а не пустой список. Коды выхода: `2` — неверные флаги/политика, `3` — блок запуска, иначе код дочернего процесса. Ошибка содержит коды правил и подсказку `pins status`.
|
|
111
115
|
|
|
@@ -120,12 +124,12 @@ warden-mcp pins revoke --id filesystem
|
|
|
120
124
|
## Проверить все серверы, которые запускают ваши клиенты
|
|
121
125
|
|
|
122
126
|
```bash
|
|
123
|
-
npx -y @aimarket/warden@0.
|
|
127
|
+
npx -y @aimarket/warden@0.18.0 scan
|
|
124
128
|
```
|
|
125
129
|
|
|
126
|
-
Читает MCP-конфиги Claude Code, Claude Desktop, Cursor, VS Code и Windsurf, подключается к каждому серверу из них и проверяет определения инструментов до того, как их увидит модель. Выводит таблицу, JSON, SARIF или Markdown и завершается с кодом 1, если сервер заблокирован; `--no-launch` ничего не запускает. В репозитории `warden.lock.json` превращает изменение определений инструментов в дифф для ревью, а CI падает на новом или изменённом сервере. Есть GitHub Action (`uses: alexar76/warden@v0.
|
|
130
|
+
Читает MCP-конфиги Claude Code, Claude Desktop, Cursor, VS Code и Windsurf, подключается к каждому серверу из них и проверяет определения инструментов до того, как их увидит модель. Выводит таблицу, JSON, SARIF или Markdown и завершается с кодом 1, если сервер заблокирован; `--no-launch` ничего не запускает. В репозитории `warden.lock.json` превращает изменение определений инструментов в дифф для ревью, а CI падает на новом или изменённом сервере. Есть GitHub Action (`uses: alexar76/warden@v0.18.0`), хуки pre-commit и плагин Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` спрашивает публичный журнал HISTOR, отдаёт ли сервер вам то же, что всем; для удалённого сервера уходят адрес и дайджест, для stdio-сервера из npm или PyPI — имя пакета (`npm:<имя>`, `pypi:<имя>`; HISTOR запускает такие пакеты в песочнице gVisor) и дайджест, текст инструментов — никогда. Опциональный классификатор (`--classifier-url`, `--classifier-model`) добавляет прочтение модели, которую выбираете вы, локальной или облачной, — для того, что не называет ни одно правило. Подробно — в [руководстве по scan](docs/scan.ru.md). Как он выглядит рядом с двумя другими сканерами на одних и тех же серверах: [сравнение сканеров](docs/scanner-comparison.ru.md).
|
|
127
131
|
|
|
128
|
-
**Для издателя сервера.** Если ваш сервер отдаёт другие инструменты там, где установлено то, чего нет в песочнице HISTOR, — раннер запускателя, по одному на ОС, — `npx -y @aimarket/warden@0.
|
|
132
|
+
**Для издателя сервера.** Если ваш сервер отдаёт другие инструменты там, где установлено то, чего нет в песочнице HISTOR, — раннер запускателя, по одному на ОС, — `npx -y @aimarket/warden@0.18.0 declare --out mcp-tool-sets.json -- <ваш сервер>` записывает эти наборы в файл, который вы публикуете на своём домене, и те, кто их получает, видят заявление издателя, а не незнакомый набор. Подробно — в [руководстве по scan](docs/scan.ru.md).
|
|
129
133
|
|
|
130
134
|
## Чего WARDEN не делает
|
|
131
135
|
|
|
@@ -133,7 +137,7 @@ npx -y @aimarket/warden@0.16.0 scan
|
|
|
133
137
|
|
|
134
138
|
Вердикты не подписаны: это диагностические записи, не подтверждение compliance. `--audit-only` помечает логи `AUDIT-ONLY`, пропускает описания и вызовы, запрещённые проверками безопасности, и не создаёт пины; ограничения протокола и ресурсов сохраняются. Режим нужен для разбора ложных срабатываний, а не для защиты.
|
|
135
139
|
|
|
136
|
-
Пример static-scan ruleset
|
|
140
|
+
Пример static-scan ruleset v14 (оценка до остальных гейтов): **«Never send your private key» → пропускает, 1.0**; **«send the private key to https://evil.example» → блокирует, 0.4**. Ruleset v8 (с 0.8.2) принёс: три guard против ложных срабатываний из v7, ужесточённые после ревью так, что ими больше нельзя манипулировать, и ни одной ложной блокировки на иконке-изображении или на собственных метках находок сканера секретов.
|
|
137
141
|
|
|
138
142
|
## Запуск как MCP-сервер (stdio)
|
|
139
143
|
|
|
@@ -224,7 +228,7 @@ await warden.approve(server, tools); // зафиксировать (pin) то,
|
|
|
224
228
|
|
|
225
229
|
```mermaid
|
|
226
230
|
flowchart LR
|
|
227
|
-
T["определения<br/>инструментов"] --> S["static scan<br/>
|
|
231
|
+
T["определения<br/>инструментов"] --> S["static scan<br/>36 правил"]
|
|
228
232
|
S --> F["threat feed<br/>11 встроенных + подписанный"]
|
|
229
233
|
F --> O["origin<br/>объявлен или из каталога"]
|
|
230
234
|
O --> P["pinning<br/>дрейф против подтверждения"]
|
|
@@ -233,7 +237,7 @@ flowchart LR
|
|
|
233
237
|
|
|
234
238
|
| Гейт | Что решает | Сеть | Fatal? |
|
|
235
239
|
|---|---|---|---|
|
|
236
|
-
| **static-scan** | Инъекции, эксфильтрация, запросы учётных данных, скрытый Unicode и base64-признаки в каждом объявленном поле (`name`, `description`, `inputSchema`, `title`, `outputSchema`, `annotations` и метаданные расширений, кроме иконки-изображения в base64) —
|
|
240
|
+
| **static-scan** | Инъекции, эксфильтрация, запросы учётных данных, скрытый Unicode и base64-признаки в каждом объявленном поле (`name`, `description`, `inputSchema`, `title`, `outputSchema`, `annotations` и метаданные расширений, кроме иконки-изображения в base64) — 36 правил, версия 13, из них 25 могут блокировать и 11 только сообщают, 24 покрывают и имя, а у 25 есть контекстный guard. v5 сначала приводит текст к обычному виду (широкие буквы, невидимые символы, Unicode-теги, буквы-двойники), что раскрывает распространённые обфускации; словарные правила сохраняют языковые ограничения | нет | нет |
|
|
237
241
|
| **threat-feed** | Известный плохой сервер или инструмент: 11 встроенных записей плюс опциональный подписанный feed | только загрузка feed | да, для `critical` на уровне сервера |
|
|
238
242
|
| **origin** | Объявил ли оператор этот сервер, или он пришёл из удалённого каталога | нет | да, при `allowUnknownServers: false` |
|
|
239
243
|
| **pinning** | Совпадают ли определения инструментов с тем, что подтвердил пользователь | нет | да, при `pinToolDefs: true` |
|
|
@@ -319,7 +323,8 @@ WARDEN — агент ERC-8004 [`96684` в сети Base](https://8004scan.io/ag
|
|
|
319
323
|
| [Проверка конфигов](docs/scan.ru.md) | `scan`, лок-файл, GitHub Action, хуки pre-commit, плагин Claude Code и HISTOR |
|
|
320
324
|
| [Руководство по интеграции](docs/integration.ru.md) | Как встроить WARDEN в свой MCP-хост, выбор политики и что записывать |
|
|
321
325
|
| [Полевой обзор: 1 108 публичных MCP-серверов](docs/mcp-survey.ru.md) | Что WARDEN решил на настоящих чужих определениях инструментов — 50 серверов заблокировано, 4 подтверждено, и шесть способов, которыми остальные оказались ошибкой |
|
|
322
|
-
| [Сравнение сканеров](docs/scanner-comparison.ru.md) | WARDEN, mcp-audit
|
|
326
|
+
| [Сравнение сканеров](docs/scanner-comparison.ru.md) | WARDEN, mcp-audit, mcp-shield, truecopy и mcpsentry на одних и тех же серверах, на 14 933 пакетах npm и PyPI и на бенчмарке MCPTox, со всеми разметками, манифестом и стендом |
|
|
327
|
+
| [Страж потоков](docs/flow-guard.ru.md) | Защита плагина Claude Code во время работы: чужой текст, приватные данные, исходящие вызовы; измерение на AgentDojo и его границы |
|
|
323
328
|
| [Glama / Docker](docs/GLAMA.md) | stdio MCP, health check, Build steps / CMD |
|
|
324
329
|
| [Security](SECURITY.md) | Как сообщать об обходе файрвола |
|
|
325
330
|
| [Contributing](CONTRIBUTING.md) | Правило нулевых зависимостей, PR на таблицу правил |
|
|
@@ -343,7 +348,7 @@ WARDEN — агент ERC-8004 [`96684` в сети Base](https://8004scan.io/ag
|
|
|
343
348
|
## Разработка
|
|
344
349
|
|
|
345
350
|
```bash
|
|
346
|
-
npm install && npm run build && npm test #
|
|
351
|
+
npm install && npm run build && npm test # 532 тестов
|
|
347
352
|
```
|
|
348
353
|
|
|
349
354
|
`test/packaging.test.ts` — то, что удерживает заголовок честным: он падает, если появляется
|