@cybedefend/vibedefend 1.4.7 → 1.6.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/README.md +77 -2
- package/dist/api/gateway-request.js +49 -0
- package/dist/api/gateway-request.js.map +1 -0
- package/dist/api/projects.js +67 -0
- package/dist/api/projects.js.map +1 -1
- package/dist/api/repository-link.js +157 -0
- package/dist/api/repository-link.js.map +1 -0
- package/dist/auth/auth-store.js +107 -25
- package/dist/auth/auth-store.js.map +1 -1
- package/dist/auth/auth.js +21 -0
- package/dist/auth/auth.js.map +1 -1
- package/dist/clients/cursor.js +5 -1
- package/dist/clients/cursor.js.map +1 -1
- package/dist/clients/vscode.js +38 -29
- package/dist/clients/vscode.js.map +1 -1
- package/dist/commands/mcp/allow.js +219 -0
- package/dist/commands/mcp/allow.js.map +1 -0
- package/dist/commands/mcp/connect.js +337 -0
- package/dist/commands/mcp/connect.js.map +1 -0
- package/dist/commands/mcp/index.js +170 -0
- package/dist/commands/mcp/index.js.map +1 -0
- package/dist/commands/mcp/proxy.js +264 -0
- package/dist/commands/mcp/proxy.js.map +1 -0
- package/dist/commands/mcp/scan.js +349 -0
- package/dist/commands/mcp/scan.js.map +1 -0
- package/dist/commands/mcp/sync.js +215 -0
- package/dist/commands/mcp/sync.js.map +1 -0
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/diagnostics.js +78 -12
- package/dist/diagnostics.js.map +1 -1
- package/dist/doctor.js +19 -0
- package/dist/doctor.js.map +1 -1
- package/dist/guards-evaluator/analysis-types.js +27 -0
- package/dist/guards-evaluator/analysis-types.js.map +1 -0
- package/dist/guards-evaluator/command-analysis.js +572 -0
- package/dist/guards-evaluator/command-analysis.js.map +1 -0
- package/dist/guards-evaluator/command-view.js +586 -0
- package/dist/guards-evaluator/command-view.js.map +1 -0
- package/dist/guards-evaluator/env.js +11 -0
- package/dist/guards-evaluator/env.js.map +1 -0
- package/dist/guards-evaluator/evaluate.js +91 -41
- package/dist/guards-evaluator/evaluate.js.map +1 -1
- package/dist/guards-evaluator/index.js +2 -1
- package/dist/guards-evaluator/index.js.map +1 -1
- package/dist/guards-evaluator/inline-code.js +259 -0
- package/dist/guards-evaluator/inline-code.js.map +1 -0
- package/dist/guards-evaluator/normalize.js +716 -0
- package/dist/guards-evaluator/normalize.js.map +1 -0
- package/dist/guards-evaluator/preprocess.js +13 -5
- package/dist/guards-evaluator/preprocess.js.map +1 -1
- package/dist/guards-evaluator/redact.js +19 -0
- package/dist/guards-evaluator/redact.js.map +1 -1
- package/dist/guards-evaluator/regex.js +25 -3
- package/dist/guards-evaluator/regex.js.map +1 -1
- package/dist/guards-evaluator/safe-commands.js +155 -0
- package/dist/guards-evaluator/safe-commands.js.map +1 -0
- package/dist/guards-evaluator/triage.js +315 -0
- package/dist/guards-evaluator/triage.js.map +1 -0
- package/dist/hook-runner.js +24873 -5068
- package/dist/hooks/install.js +38 -0
- package/dist/hooks/install.js.map +1 -1
- package/dist/hooks/runtime/config.js +38 -0
- package/dist/hooks/runtime/config.js.map +1 -1
- package/dist/hooks/runtime/emit.js +126 -53
- package/dist/hooks/runtime/emit.js.map +1 -1
- package/dist/hooks/runtime/fetch-rules.js +27 -7
- package/dist/hooks/runtime/fetch-rules.js.map +1 -1
- package/dist/hooks/runtime/gateway-http-error.js +34 -0
- package/dist/hooks/runtime/gateway-http-error.js.map +1 -0
- package/dist/hooks/runtime/guard-rules-cache.js +139 -17
- package/dist/hooks/runtime/guard-rules-cache.js.map +1 -1
- package/dist/hooks/runtime/guard-violations-buffer.js +321 -48
- package/dist/hooks/runtime/guard-violations-buffer.js.map +1 -1
- package/dist/hooks/runtime/judge-cache.js +6 -0
- package/dist/hooks/runtime/judge-cache.js.map +1 -1
- package/dist/hooks/runtime/judge-triage.js +193 -0
- package/dist/hooks/runtime/judge-triage.js.map +1 -0
- package/dist/hooks/runtime/judge.js +7 -1
- package/dist/hooks/runtime/judge.js.map +1 -1
- package/dist/hooks/runtime/pre-compact.js +21 -6
- package/dist/hooks/runtime/pre-compact.js.map +1 -1
- package/dist/hooks/runtime/resolve.js +108 -17
- package/dist/hooks/runtime/resolve.js.map +1 -1
- package/dist/hooks/runtime/retry-policy.js +57 -0
- package/dist/hooks/runtime/retry-policy.js.map +1 -0
- package/dist/hooks/runtime/review-sessions.js +74 -0
- package/dist/hooks/runtime/review-sessions.js.map +1 -0
- package/dist/hooks/runtime/script-resolve.js +695 -0
- package/dist/hooks/runtime/script-resolve.js.map +1 -0
- package/dist/hooks/runtime/session-activation.js +226 -0
- package/dist/hooks/runtime/session-activation.js.map +1 -0
- package/dist/hooks/runtime/session-review.js +174 -46
- package/dist/hooks/runtime/session-review.js.map +1 -1
- package/dist/hooks/runtime/session-start.js +35 -4
- package/dist/hooks/runtime/session-start.js.map +1 -1
- package/dist/hooks/runtime/session-writes.js +232 -0
- package/dist/hooks/runtime/session-writes.js.map +1 -0
- package/dist/hooks/runtime/sniff.js +26 -7
- package/dist/hooks/runtime/sniff.js.map +1 -1
- package/dist/hooks/runtime/target-resolve.js +336 -0
- package/dist/hooks/runtime/target-resolve.js.map +1 -0
- package/dist/hooks/runtime/unmapped-tools.js +93 -0
- package/dist/hooks/runtime/unmapped-tools.js.map +1 -0
- package/dist/hooks/runtime/usage-block.js +4 -0
- package/dist/hooks/runtime/usage-block.js.map +1 -1
- package/dist/hooks/runtime/user-prompt-submit.js +8 -2
- package/dist/hooks/runtime/user-prompt-submit.js.map +1 -1
- package/dist/hooks/runtime/wire-text.js +41 -0
- package/dist/hooks/runtime/wire-text.js.map +1 -0
- package/dist/hooks/runtime/work-dir.js +84 -0
- package/dist/hooks/runtime/work-dir.js.map +1 -0
- package/dist/index.js +45 -12
- package/dist/index.js.map +1 -1
- package/dist/install.js +174 -11
- package/dist/install.js.map +1 -1
- package/dist/link.js +74 -48
- package/dist/link.js.map +1 -1
- package/dist/login.js +99 -14
- package/dist/login.js.map +1 -1
- package/dist/mcp/auth/agent-sign-ins.js +174 -0
- package/dist/mcp/auth/agent-sign-ins.js.map +1 -0
- package/dist/mcp/auth/callback.js +200 -0
- package/dist/mcp/auth/callback.js.map +1 -0
- package/dist/mcp/auth/connect.js +392 -0
- package/dist/mcp/auth/connect.js.map +1 -0
- package/dist/mcp/auth/discovery.js +399 -0
- package/dist/mcp/auth/discovery.js.map +1 -0
- package/dist/mcp/auth/oauth.js +326 -0
- package/dist/mcp/auth/oauth.js.map +1 -0
- package/dist/mcp/auth/probe.js +128 -0
- package/dist/mcp/auth/probe.js.map +1 -0
- package/dist/mcp/auth/secrets.js +446 -0
- package/dist/mcp/auth/secrets.js.map +1 -0
- package/dist/mcp/auth/store.js +260 -0
- package/dist/mcp/auth/store.js.map +1 -0
- package/dist/mcp/auth/tokenSource.js +55 -0
- package/dist/mcp/auth/tokenSource.js.map +1 -0
- package/dist/mcp/config/atomicWrite.js +98 -0
- package/dist/mcp/config/atomicWrite.js.map +1 -0
- package/dist/mcp/config/clients.js +171 -0
- package/dist/mcp/config/clients.js.map +1 -0
- package/dist/mcp/config/cybedefend-servers.js +48 -0
- package/dist/mcp/config/cybedefend-servers.js.map +1 -0
- package/dist/mcp/config/discover.js +114 -0
- package/dist/mcp/config/discover.js.map +1 -0
- package/dist/mcp/config/hook.js +123 -0
- package/dist/mcp/config/hook.js.map +1 -0
- package/dist/mcp/config/index.js +11 -0
- package/dist/mcp/config/index.js.map +1 -0
- package/dist/mcp/config/install.js +132 -0
- package/dist/mcp/config/install.js.map +1 -0
- package/dist/mcp/config/installed.js +37 -0
- package/dist/mcp/config/installed.js.map +1 -0
- package/dist/mcp/config/jsonEdit.js +119 -0
- package/dist/mcp/config/jsonEdit.js.map +1 -0
- package/dist/mcp/config/lock.js +102 -0
- package/dist/mcp/config/lock.js.map +1 -0
- package/dist/mcp/config/proxyBinary.js +211 -0
- package/dist/mcp/config/proxyBinary.js.map +1 -0
- package/dist/mcp/config/rewrite.js +388 -0
- package/dist/mcp/config/rewrite.js.map +1 -0
- package/dist/mcp/config/types.js +34 -0
- package/dist/mcp/config/types.js.map +1 -0
- package/dist/mcp/proxy/audit.js +83 -0
- package/dist/mcp/proxy/audit.js.map +1 -0
- package/dist/mcp/proxy/authInterceptor.js +119 -0
- package/dist/mcp/proxy/authInterceptor.js.map +1 -0
- package/dist/mcp/proxy/expand.js +93 -0
- package/dist/mcp/proxy/expand.js.map +1 -0
- package/dist/mcp/proxy/inject.js +397 -0
- package/dist/mcp/proxy/inject.js.map +1 -0
- package/dist/mcp/proxy/intercept.js +37 -0
- package/dist/mcp/proxy/intercept.js.map +1 -0
- package/dist/mcp/proxy/jsonrpc.js +153 -0
- package/dist/mcp/proxy/jsonrpc.js.map +1 -0
- package/dist/mcp/proxy/log.js +109 -0
- package/dist/mcp/proxy/log.js.map +1 -0
- package/dist/mcp/proxy/paths.js +53 -0
- package/dist/mcp/proxy/paths.js.map +1 -0
- package/dist/mcp/proxy/proxy.js +510 -0
- package/dist/mcp/proxy/proxy.js.map +1 -0
- package/dist/mcp/proxy/spec.js +203 -0
- package/dist/mcp/proxy/spec.js.map +1 -0
- package/dist/mcp/proxy/sse.js +77 -0
- package/dist/mcp/proxy/sse.js.map +1 -0
- package/dist/mcp/proxy/upstream.js +2 -0
- package/dist/mcp/proxy/upstream.js.map +1 -0
- package/dist/mcp/proxy/upstreamHttp.js +499 -0
- package/dist/mcp/proxy/upstreamHttp.js.map +1 -0
- package/dist/mcp/proxy/upstreamStdio.js +188 -0
- package/dist/mcp/proxy/upstreamStdio.js.map +1 -0
- package/dist/mcp/proxy/upstreams.js +143 -0
- package/dist/mcp/proxy/upstreams.js.map +1 -0
- package/dist/mcp/proxy/verifyInterceptor.js +559 -0
- package/dist/mcp/proxy/verifyInterceptor.js.map +1 -0
- package/dist/mcp/proxy/windowsCommand.js +99 -0
- package/dist/mcp/proxy/windowsCommand.js.map +1 -0
- package/dist/mcp/scan/args.js +228 -0
- package/dist/mcp/scan/args.js.map +1 -0
- package/dist/mcp/scan/results.js +253 -0
- package/dist/mcp/scan/results.js.map +1 -0
- package/dist/mcp/scan/types.js +40 -0
- package/dist/mcp/scan/types.js.map +1 -0
- package/dist/mcp/verify/api.js +475 -0
- package/dist/mcp/verify/api.js.map +1 -0
- package/dist/mcp/verify/backend.js +143 -0
- package/dist/mcp/verify/backend.js.map +1 -0
- package/dist/mcp/verify/cache.js +182 -0
- package/dist/mcp/verify/cache.js.map +1 -0
- package/dist/mcp/verify/contract-errors.js +198 -0
- package/dist/mcp/verify/contract-errors.js.map +1 -0
- package/dist/mcp/verify/digest.js +91 -0
- package/dist/mcp/verify/digest.js.map +1 -0
- package/dist/mcp/verify/factory.js +56 -0
- package/dist/mcp/verify/factory.js.map +1 -0
- package/dist/mcp/verify/identity.js +173 -0
- package/dist/mcp/verify/identity.js.map +1 -0
- package/dist/mcp/verify/policy-store.js +63 -0
- package/dist/mcp/verify/policy-store.js.map +1 -0
- package/dist/mcp/verify/policy.js +158 -0
- package/dist/mcp/verify/policy.js.map +1 -0
- package/dist/mcp/verify/pool.js +27 -0
- package/dist/mcp/verify/pool.js.map +1 -0
- package/dist/mcp/verify/token-refresh.js +44 -0
- package/dist/mcp/verify/token-refresh.js.map +1 -0
- package/dist/mcp/verify/token.js +67 -0
- package/dist/mcp/verify/token.js.map +1 -0
- package/dist/mcp/verify/verifier.js +1009 -0
- package/dist/mcp/verify/verifier.js.map +1 -0
- package/dist/org-gate.js +1 -1
- package/dist/org-gate.js.map +1 -1
- package/dist/org.js +146 -0
- package/dist/org.js.map +1 -0
- package/dist/project-create.js +129 -0
- package/dist/project-create.js.map +1 -0
- package/dist/prompts.js +21 -0
- package/dist/prompts.js.map +1 -1
- package/dist/re2.wasm +0 -0
- package/dist/status.js +61 -0
- package/dist/status.js.map +1 -1
- package/dist/uninstall.js +49 -4
- package/dist/uninstall.js.map +1 -1
- package/dist/utils.js +62 -6
- package/dist/utils.js.map +1 -1
- package/package.json +10 -3
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where verification meets the forwarding loop.
|
|
3
|
+
*
|
|
4
|
+
* The loop's job is to move messages; deciding what a tool list means is this
|
|
5
|
+
* file's. It plugs into the `Interceptor` seam Phase 1 left, and touches
|
|
6
|
+
* exactly three things:
|
|
7
|
+
*
|
|
8
|
+
* - a `tools/list` RESPONSE, which it may replace;
|
|
9
|
+
* - a `tools/call` REQUEST for one of the proxy's own tools, which it
|
|
10
|
+
* answers itself and never forwards — the upstream has never heard of
|
|
11
|
+
* `vibedefend_alert` and would return an error the agent would relay as
|
|
12
|
+
* a bug of ours;
|
|
13
|
+
* - a `tools/call` REQUEST, which is where the judgement is BOUGHT — for
|
|
14
|
+
* the called tool only (`verifyOne`) — and where the SERVER'S ACTION is
|
|
15
|
+
* executed: on a BLOCKED server it is refused outright (hiding the list
|
|
16
|
+
* is not locking the door — an agent that remembers a tool name can
|
|
17
|
+
* still call it); a tool the server blocks is refused the same way; a
|
|
18
|
+
* tool the server says to ASK about has the user asked, through MCP
|
|
19
|
+
* elicitation, whether to send the call anyway — once per server and
|
|
20
|
+
* session on a yes, every time on a no; a tool the server only WARNS
|
|
21
|
+
* about goes through, its result framed. A client that cannot be asked
|
|
22
|
+
* (no `elicitation` capability) gets the previous behaviour: the call
|
|
23
|
+
* goes through, `vibedefend_alert` was in the list. Never fail-open on a
|
|
24
|
+
* question that WAS asked and got no answer;
|
|
25
|
+
* - `notifications/tools/list_changed`, which it notes and lets through so
|
|
26
|
+
* the client asks again;
|
|
27
|
+
* - `notifications/cancelled` from the agent, for a call still waiting on
|
|
28
|
+
* the user: the call is dropped, unanswered, and the notification is not
|
|
29
|
+
* forwarded — the upstream never saw the call. Any other cancellation
|
|
30
|
+
* passes through.
|
|
31
|
+
*
|
|
32
|
+
* Everything else passes untouched, which is the whole point of the seam.
|
|
33
|
+
*/
|
|
34
|
+
import { applyToToolsList, CONFIRMATION_SCHEMA, confirmationPrompt, isSyntheticTool, prefixResult, refusedCallResponse, replaceResult, syntheticCallResponse, } from './inject.js';
|
|
35
|
+
import { scanArguments } from '../scan/args.js';
|
|
36
|
+
import { scanResult } from '../scan/results.js';
|
|
37
|
+
import { toolDigest } from '../verify/digest.js';
|
|
38
|
+
import { idKey, isRequest, isResponse, methodOf } from './jsonrpc.js';
|
|
39
|
+
/**
|
|
40
|
+
* How long a question may stay on screen. A user who is away is not a user
|
|
41
|
+
* who said yes: past this, the call is refused and the agent is told why.
|
|
42
|
+
*/
|
|
43
|
+
export const CONFIRMATION_TIMEOUT_MS = 5 * 60 * 1000;
|
|
44
|
+
/**
|
|
45
|
+
* A call's seat in the queue for the user, and the way to pull it out.
|
|
46
|
+
*
|
|
47
|
+
* `race` settles with the user's answer or, if the agent sends
|
|
48
|
+
* `notifications/cancelled` for the call first, with a no — the call is
|
|
49
|
+
* dropped either way, but the caller can tell which, and only the former is
|
|
50
|
+
* answered.
|
|
51
|
+
*/
|
|
52
|
+
class Cancellation {
|
|
53
|
+
tool;
|
|
54
|
+
cancelled = false;
|
|
55
|
+
signal;
|
|
56
|
+
settle = () => undefined;
|
|
57
|
+
constructor(tool) {
|
|
58
|
+
this.tool = tool;
|
|
59
|
+
this.signal = new Promise((resolve) => {
|
|
60
|
+
this.settle = resolve;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
cancel() {
|
|
64
|
+
this.cancelled = true;
|
|
65
|
+
this.settle({ proceed: false, remember: false });
|
|
66
|
+
}
|
|
67
|
+
race(answer) {
|
|
68
|
+
return Promise.race([answer, this.signal]);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The last finding, so a call to a synthetic tool can answer with the detail
|
|
73
|
+
* that produced it rather than re-running a verification.
|
|
74
|
+
*/
|
|
75
|
+
const NO_FINDING = {
|
|
76
|
+
serverName: 'this server',
|
|
77
|
+
kind: 'no finding is on record',
|
|
78
|
+
tools: [],
|
|
79
|
+
};
|
|
80
|
+
export function createVerifyInterceptor(options) {
|
|
81
|
+
const { verifier, logger } = options;
|
|
82
|
+
/** Ids of the `tools/list` requests in flight, so the answers can be matched. */
|
|
83
|
+
const pendingLists = new Set();
|
|
84
|
+
/** Calls in flight, so a result can be scanned knowing which tool it is from. */
|
|
85
|
+
const pendingCalls = new Map();
|
|
86
|
+
/** The last list, for the schema a call's arguments are judged against. */
|
|
87
|
+
let knownTools = new Map();
|
|
88
|
+
let lastFinding = NO_FINDING;
|
|
89
|
+
/** The last verification, for the gate a `tools/call` goes through. */
|
|
90
|
+
let lastOutcome;
|
|
91
|
+
/** The user said yes for this server, for the rest of the session. */
|
|
92
|
+
let confirmed = false;
|
|
93
|
+
/** A question already on screen: calls that arrive meanwhile wait for its answer. */
|
|
94
|
+
let openQuestion;
|
|
95
|
+
/**
|
|
96
|
+
* Calls waiting on the user, by request id, so a `notifications/cancelled`
|
|
97
|
+
* from the agent can settle the one it names. A client that gave up on the
|
|
98
|
+
* call has told its model the call failed; a yes that arrives afterwards
|
|
99
|
+
* must not send it anyway.
|
|
100
|
+
*/
|
|
101
|
+
const pendingConfirmations = new Map();
|
|
102
|
+
let warnedCannotAsk = false;
|
|
103
|
+
return {
|
|
104
|
+
name: 'verify',
|
|
105
|
+
async fromAgent(message, context) {
|
|
106
|
+
const method = methodOf(message);
|
|
107
|
+
if (method === 'notifications/cancelled') {
|
|
108
|
+
const requestId = typeof message.params === 'object' && message.params !== null
|
|
109
|
+
? message.params.requestId
|
|
110
|
+
: undefined;
|
|
111
|
+
const key = idKey(requestId);
|
|
112
|
+
const waiting = key ? pendingConfirmations.get(key) : undefined;
|
|
113
|
+
if (waiting) {
|
|
114
|
+
// The call is still here, waiting on the user: it never reached
|
|
115
|
+
// the upstream, so the upstream has nothing to cancel and must not
|
|
116
|
+
// hear of an id it never saw. Settle the call as declined instead.
|
|
117
|
+
logger.info('verify: the agent cancelled a tools/call while the user was being asked', {
|
|
118
|
+
tool: waiting.tool,
|
|
119
|
+
});
|
|
120
|
+
waiting.cancel();
|
|
121
|
+
return { action: 'drop', reason: 'the cancelled call was never forwarded' };
|
|
122
|
+
}
|
|
123
|
+
return { action: 'forward' };
|
|
124
|
+
}
|
|
125
|
+
if (isRequest(message) && method === 'tools/list') {
|
|
126
|
+
const key = idKey(message.id);
|
|
127
|
+
if (key)
|
|
128
|
+
pendingLists.add(key);
|
|
129
|
+
return { action: 'forward' };
|
|
130
|
+
}
|
|
131
|
+
if (isRequest(message) && method === 'tools/call') {
|
|
132
|
+
const params = typeof message.params === 'object' && message.params !== null
|
|
133
|
+
? message.params
|
|
134
|
+
: {};
|
|
135
|
+
const name = params.name;
|
|
136
|
+
if (isSyntheticTool(name)) {
|
|
137
|
+
// Answered here, never forwarded: it is our tool, not theirs.
|
|
138
|
+
return {
|
|
139
|
+
action: 'respond',
|
|
140
|
+
message: syntheticCallResponse(message.id, String(name), lastFinding),
|
|
141
|
+
reason: 'a VibeDefend tool is answered by VibeDefend',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const toolName = typeof name === 'string' ? name : '(unnamed)';
|
|
145
|
+
// The SERVER-level gate, from the last list: a blocked server takes
|
|
146
|
+
// every call with it, whatever the individual tool's record says.
|
|
147
|
+
if (lastOutcome?.decision.action === 'block') {
|
|
148
|
+
logger.info('verify: refused a tools/call to a blocked server', { tool: toolName });
|
|
149
|
+
return {
|
|
150
|
+
action: 'respond',
|
|
151
|
+
message: refusedCallResponse(message.id, options.serverName, toolName, lastFinding, 'blocked'),
|
|
152
|
+
reason: 'the server is blocked',
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const definition = knownTools.get(toolName);
|
|
156
|
+
const findings = scanArguments(params.arguments, {
|
|
157
|
+
spec: options.spec,
|
|
158
|
+
inputSchema: definition?.inputSchema,
|
|
159
|
+
description: definition?.description,
|
|
160
|
+
});
|
|
161
|
+
if (findings.length > 0) {
|
|
162
|
+
// Reported, never blocked: the plan's default here is `warn`, and a
|
|
163
|
+
// proxy that refused a call because a value looked like a token
|
|
164
|
+
// would break the tools people use to manage tokens.
|
|
165
|
+
logger.warn('scan: something in the arguments of a tools/call', {
|
|
166
|
+
tool: toolName,
|
|
167
|
+
findings: findings.map((finding) => finding.rule),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// The judgement, bought here and for this tool only.
|
|
171
|
+
let verdictFinding;
|
|
172
|
+
let policy = verifier.policy();
|
|
173
|
+
if (definition) {
|
|
174
|
+
const outcome = await verifier.verifyOne(definition);
|
|
175
|
+
policy = outcome.policy;
|
|
176
|
+
options.onOutcome?.({
|
|
177
|
+
action: outcome.decision.action,
|
|
178
|
+
verdict: outcome.verdict,
|
|
179
|
+
fromCache: outcome.fromCache,
|
|
180
|
+
tool: toolName,
|
|
181
|
+
});
|
|
182
|
+
if (outcome.decision.action !== 'pass') {
|
|
183
|
+
lastFinding = outcome.finding;
|
|
184
|
+
logger.info('verify: decided for a call', {
|
|
185
|
+
tool: toolName,
|
|
186
|
+
action: outcome.decision.action,
|
|
187
|
+
rationale: outcome.decision.rationale,
|
|
188
|
+
verdict: outcome.verdict,
|
|
189
|
+
fromCache: outcome.fromCache,
|
|
190
|
+
});
|
|
191
|
+
if (outcome.decision.action === 'block') {
|
|
192
|
+
// Answered here, never forwarded: the call would have reached
|
|
193
|
+
// a tool the verdict says must not run.
|
|
194
|
+
return {
|
|
195
|
+
action: 'respond',
|
|
196
|
+
message: refusedCallResponse(message.id, options.serverName, toolName, outcome.finding, 'blocked'),
|
|
197
|
+
reason: 'the called tool is refused by its verdict',
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// The TOOL-level gate: this tool's own verdict, bought just now or
|
|
201
|
+
// served from the dictionary. The user decides, once per server
|
|
202
|
+
// and session on a yes.
|
|
203
|
+
if (needsConfirmation(outcome)) {
|
|
204
|
+
const refused = await confirmOrRefuse(message, toolName, outcome.finding, context.agent);
|
|
205
|
+
if (refused)
|
|
206
|
+
return refused;
|
|
207
|
+
}
|
|
208
|
+
verdictFinding = verdictFindingOf(outcome);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (!lastOutcome) {
|
|
212
|
+
// No list yet this session: nothing has been verified, so there is
|
|
213
|
+
// no server verdict to gate on and no definition to judge. The call
|
|
214
|
+
// goes through like everything else this seam does not understand,
|
|
215
|
+
// and the first `tools/list` sets the gate for the ones after it.
|
|
216
|
+
logger.info('verify: a tools/call before any tools/list, forwarding without a verdict', {
|
|
217
|
+
tool: toolName,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
else if (needsConfirmation(lastOutcome)) {
|
|
221
|
+
// A name the last list did not carry — added after a
|
|
222
|
+
// `list_changed` the client did not follow up on, or one the agent
|
|
223
|
+
// remembered. There is no definition to judge, but the SERVER's
|
|
224
|
+
// verdict still stands, and a suspicious server is not vouched for
|
|
225
|
+
// by the tool being new. The user decides, as for a listed tool.
|
|
226
|
+
const refused = await confirmOrRefuse(message, toolName, lastFinding, context.agent);
|
|
227
|
+
if (refused)
|
|
228
|
+
return refused;
|
|
229
|
+
}
|
|
230
|
+
const key = idKey(message.id);
|
|
231
|
+
if (key) {
|
|
232
|
+
pendingCalls.set(key, {
|
|
233
|
+
tool: toolName,
|
|
234
|
+
digest: definition ? safeDigest(definition) : undefined,
|
|
235
|
+
argumentBytes: byteLength(params.arguments),
|
|
236
|
+
findings,
|
|
237
|
+
verdictFinding,
|
|
238
|
+
withholdOnFinding: policy.mode === 'block',
|
|
239
|
+
startedAt: Date.now(),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return { action: 'forward' };
|
|
244
|
+
},
|
|
245
|
+
async fromUpstream(message, context) {
|
|
246
|
+
if (methodOf(message) === 'notifications/tools/list_changed') {
|
|
247
|
+
// Noted, and forwarded: the client is the one that decides to ask
|
|
248
|
+
// again, and swallowing this would leave it with a stale list.
|
|
249
|
+
verifier.noteListChanged();
|
|
250
|
+
logger.info('verify: the upstream announced its tool list changed');
|
|
251
|
+
return { action: 'forward' };
|
|
252
|
+
}
|
|
253
|
+
if (!isResponse(message))
|
|
254
|
+
return { action: 'forward' };
|
|
255
|
+
const key = idKey(message.id);
|
|
256
|
+
if (!key)
|
|
257
|
+
return { action: 'forward' };
|
|
258
|
+
const call = pendingCalls.get(key);
|
|
259
|
+
if (call) {
|
|
260
|
+
pendingCalls.delete(key);
|
|
261
|
+
return finishCall(call, message);
|
|
262
|
+
}
|
|
263
|
+
if (!pendingLists.has(key))
|
|
264
|
+
return { action: 'forward' };
|
|
265
|
+
pendingLists.delete(key);
|
|
266
|
+
const result = message.result;
|
|
267
|
+
if (typeof result !== 'object' || result === null)
|
|
268
|
+
return { action: 'forward' };
|
|
269
|
+
const tools = result.tools;
|
|
270
|
+
if (!Array.isArray(tools))
|
|
271
|
+
return { action: 'forward' };
|
|
272
|
+
knownTools = new Map(tools
|
|
273
|
+
.filter((tool) => typeof tool?.name === 'string')
|
|
274
|
+
.map((tool) => [tool.name, tool]));
|
|
275
|
+
const outcome = await verifier.verify(tools);
|
|
276
|
+
options.onOutcome?.({
|
|
277
|
+
action: outcome.decision.action,
|
|
278
|
+
verdict: outcome.verdict,
|
|
279
|
+
fromCache: outcome.fromCache,
|
|
280
|
+
});
|
|
281
|
+
lastFinding = outcome.finding;
|
|
282
|
+
lastOutcome = outcome;
|
|
283
|
+
logger.info('verify: decided', {
|
|
284
|
+
action: outcome.decision.action,
|
|
285
|
+
rationale: outcome.decision.rationale,
|
|
286
|
+
verdict: outcome.verdict,
|
|
287
|
+
fromCache: outcome.fromCache,
|
|
288
|
+
tools: tools.length,
|
|
289
|
+
});
|
|
290
|
+
if (outcome.decision.action === 'pass')
|
|
291
|
+
return { action: 'forward' };
|
|
292
|
+
// The alert must not promise a prompt that will not come: none comes
|
|
293
|
+
// for an agent that cannot be asked, nor for a finding nobody is asked
|
|
294
|
+
// about (a contract error).
|
|
295
|
+
const canAsk = Boolean(context.agent?.supports('elicitation'));
|
|
296
|
+
const willAsk = needsConfirmation(outcome) && canAsk;
|
|
297
|
+
// Each flagged tool's own verdict, so the notice that replaces its
|
|
298
|
+
// description names ITS finding — see `withheldTool`.
|
|
299
|
+
const flagged = (outcome.tools ?? [])
|
|
300
|
+
.filter((tool) => tool.verdict === 'malicious' || tool.verdict === 'suspicious')
|
|
301
|
+
.map((tool) => ({ name: tool.name, verdict: tool.verdict, reason: tool.reason }));
|
|
302
|
+
// A server nobody is asked about (malicious, under `warn`) can still
|
|
303
|
+
// carry a suspicious tool — and a call to THAT one is put to the user.
|
|
304
|
+
const willAskForSuspicious = !willAsk && canAsk && flagged.some((tool) => tool.verdict === 'suspicious');
|
|
305
|
+
return {
|
|
306
|
+
action: 'replace',
|
|
307
|
+
message: {
|
|
308
|
+
...message,
|
|
309
|
+
result: applyToToolsList(result, outcome.decision.action, outcome.finding, {
|
|
310
|
+
willAsk,
|
|
311
|
+
willAskForSuspicious,
|
|
312
|
+
flagged,
|
|
313
|
+
}),
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* The confirmation step of a `tools/call`: the decision that ends the call
|
|
320
|
+
* (refused, or dropped after a cancellation), or nothing when it may go on.
|
|
321
|
+
*/
|
|
322
|
+
async function confirmOrRefuse(message, toolName, finding, agent) {
|
|
323
|
+
if (confirmed)
|
|
324
|
+
return undefined;
|
|
325
|
+
const { answer, cancelled } = await askAbout(message.id, toolName, finding, agent);
|
|
326
|
+
if (cancelled) {
|
|
327
|
+
// No response, on purpose: the spec has the receiver of a cancellation
|
|
328
|
+
// "not send a response for the cancelled request", and the sender
|
|
329
|
+
// ignore one that arrives anyway. A late refusal text would land in
|
|
330
|
+
// the agent's context as a fresh tool error for a call it already
|
|
331
|
+
// wrote off.
|
|
332
|
+
return { action: 'drop', reason: 'the agent cancelled the call before the user answered' };
|
|
333
|
+
}
|
|
334
|
+
if (answer.proceed)
|
|
335
|
+
return undefined;
|
|
336
|
+
if (answer.answered === false) {
|
|
337
|
+
logger.info('verify: no answer to the confirmation, the tools/call is not sent', { tool: toolName });
|
|
338
|
+
return {
|
|
339
|
+
action: 'respond',
|
|
340
|
+
message: refusedCallResponse(message.id, options.serverName, toolName, finding, 'unanswered'),
|
|
341
|
+
reason: 'the confirmation got no answer',
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
logger.info('verify: the user declined a tools/call to a suspicious tool', { tool: toolName });
|
|
345
|
+
return {
|
|
346
|
+
action: 'respond',
|
|
347
|
+
message: refusedCallResponse(message.id, options.serverName, toolName, finding, 'declined'),
|
|
348
|
+
reason: 'the user declined to send the call',
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
async function askAbout(requestId, toolName, finding, agent) {
|
|
352
|
+
const cancellation = new Cancellation(toolName);
|
|
353
|
+
const key = idKey(requestId);
|
|
354
|
+
if (key)
|
|
355
|
+
pendingConfirmations.set(key, cancellation);
|
|
356
|
+
try {
|
|
357
|
+
const answer = await confirmWithUser(toolName, finding, agent, cancellation);
|
|
358
|
+
return { answer, cancelled: cancellation.cancelled };
|
|
359
|
+
}
|
|
360
|
+
finally {
|
|
361
|
+
if (key)
|
|
362
|
+
pendingConfirmations.delete(key);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Puts the question to the user, once at a time.
|
|
367
|
+
*
|
|
368
|
+
* Two calls arriving while the prompt is up must not produce two prompts —
|
|
369
|
+
* the second would be answered by reflex — so the second WAITS on the open
|
|
370
|
+
* one. What the answer then covers depends on what the user said:
|
|
371
|
+
*
|
|
372
|
+
* - a yes with `remember` covers the session, so every waiter goes through;
|
|
373
|
+
* - a yes WITHOUT `remember` covers only the call the prompt named. The
|
|
374
|
+
* user vouched for `read_file`, not for the `exfiltrate_env` that queued
|
|
375
|
+
* behind it. A waiter re-asks, in turn, once the prompt closes — one
|
|
376
|
+
* open question at a time, each naming its own tool;
|
|
377
|
+
* - a no covers every call that waited on it. "Not this one" said while
|
|
378
|
+
* N calls were queued is N refusals, not one refusal and N-1 nudges, and
|
|
379
|
+
* the next call after the prompt closes asks again — a no is never
|
|
380
|
+
* remembered.
|
|
381
|
+
*/
|
|
382
|
+
async function confirmWithUser(toolName, finding, agent, cancellation) {
|
|
383
|
+
if (!agent || !agent.supports('elicitation')) {
|
|
384
|
+
if (!warnedCannotAsk) {
|
|
385
|
+
warnedCannotAsk = true;
|
|
386
|
+
logger.warn('verify: the agent cannot be asked (no elicitation capability), forwarding calls to a suspicious server');
|
|
387
|
+
}
|
|
388
|
+
return { proceed: true, remember: false };
|
|
389
|
+
}
|
|
390
|
+
for (;;) {
|
|
391
|
+
if (confirmed)
|
|
392
|
+
return { proceed: true, remember: true };
|
|
393
|
+
if (openQuestion) {
|
|
394
|
+
// Somebody else's prompt. Its answer is ours only if it was a no, or
|
|
395
|
+
// a yes for the whole session.
|
|
396
|
+
const shared = await cancellation.race(openQuestion);
|
|
397
|
+
if (!shared.proceed || shared.remember)
|
|
398
|
+
return shared;
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
openQuestion = ask(agent, toolName, finding)
|
|
402
|
+
.then((answer) => {
|
|
403
|
+
if (answer.proceed && answer.remember)
|
|
404
|
+
confirmed = true;
|
|
405
|
+
return answer;
|
|
406
|
+
})
|
|
407
|
+
.finally(() => {
|
|
408
|
+
openQuestion = undefined;
|
|
409
|
+
});
|
|
410
|
+
const answer = await cancellation.race(openQuestion);
|
|
411
|
+
if (cancellation.cancelled)
|
|
412
|
+
return answer;
|
|
413
|
+
logger.info('verify: the user answered the confirmation', {
|
|
414
|
+
tool: toolName,
|
|
415
|
+
proceed: answer.proceed,
|
|
416
|
+
remember: answer.remember,
|
|
417
|
+
});
|
|
418
|
+
return answer;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
async function ask(agent, toolName, finding) {
|
|
422
|
+
let response;
|
|
423
|
+
try {
|
|
424
|
+
response = await agent.request('elicitation/create', {
|
|
425
|
+
message: confirmationPrompt(options.serverName, toolName, finding),
|
|
426
|
+
requestedSchema: CONFIRMATION_SCHEMA,
|
|
427
|
+
}, CONFIRMATION_TIMEOUT_MS);
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
// A question that got no answer is a no. The alternative — forwarding
|
|
431
|
+
// because the prompt broke — would make a crashed dialog the way past
|
|
432
|
+
// the gate.
|
|
433
|
+
logger.warn('verify: the confirmation prompt failed, refusing the call', {
|
|
434
|
+
error: error instanceof Error ? error.message : String(error),
|
|
435
|
+
});
|
|
436
|
+
return { proceed: false, remember: false, answered: false };
|
|
437
|
+
}
|
|
438
|
+
const result = typeof response.result === 'object' && response.result !== null
|
|
439
|
+
? response.result
|
|
440
|
+
: undefined;
|
|
441
|
+
if (!result || result.action !== 'accept')
|
|
442
|
+
return { proceed: false, remember: false };
|
|
443
|
+
const content = typeof result.content === 'object' && result.content !== null
|
|
444
|
+
? result.content
|
|
445
|
+
: {};
|
|
446
|
+
return { proceed: true, remember: content.remember !== false };
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Scans a result, frames it if there is something to say, and writes the
|
|
450
|
+
* audit line either way.
|
|
451
|
+
*/
|
|
452
|
+
function finishCall(call, message) {
|
|
453
|
+
const resultFindings = message.result === undefined ? [] : scanResult(message.result);
|
|
454
|
+
const findings = [...call.findings, ...resultFindings];
|
|
455
|
+
const resultBytes = byteLength(message.result);
|
|
456
|
+
options.audit?.record({
|
|
457
|
+
serverId: options.serverId,
|
|
458
|
+
serverName: options.serverName,
|
|
459
|
+
tool: call.tool,
|
|
460
|
+
digest: call.digest,
|
|
461
|
+
// Rules only. The arguments and the result are never written down: a
|
|
462
|
+
// file that quoted them would be a second copy of everything the user
|
|
463
|
+
// has done, sitting in their home directory.
|
|
464
|
+
findings: findings.length > 0 ? findings.map((finding) => finding.rule) : undefined,
|
|
465
|
+
argumentBytes: call.argumentBytes,
|
|
466
|
+
resultBytes,
|
|
467
|
+
isError: Boolean(message.result?.isError),
|
|
468
|
+
durationMs: Date.now() - call.startedAt,
|
|
469
|
+
});
|
|
470
|
+
if (resultFindings.length === 0 && !call.verdictFinding)
|
|
471
|
+
return { action: 'forward' };
|
|
472
|
+
if (resultFindings.length > 0) {
|
|
473
|
+
logger.warn('scan: something in the result of a tools/call', {
|
|
474
|
+
tool: call.tool,
|
|
475
|
+
findings: resultFindings.map((finding) => finding.rule),
|
|
476
|
+
});
|
|
477
|
+
lastFinding = {
|
|
478
|
+
serverName: options.serverName,
|
|
479
|
+
kind: 'a tool result tried to give you instructions',
|
|
480
|
+
tools: [call.tool],
|
|
481
|
+
reason: resultFindings[0]?.detail,
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
// The verdict frames, it never withholds: a call the server blocks was
|
|
485
|
+
// answered before it left, so a verdict here is one the server let
|
|
486
|
+
// through. Only a RESULT finding — an injection in the text — is
|
|
487
|
+
// withheld, and only under the organization's `block` policy.
|
|
488
|
+
const framed = [...(call.verdictFinding ? [call.verdictFinding] : []), ...resultFindings];
|
|
489
|
+
return {
|
|
490
|
+
action: 'replace',
|
|
491
|
+
message: {
|
|
492
|
+
...message,
|
|
493
|
+
result: call.withholdOnFinding && resultFindings.length > 0
|
|
494
|
+
? replaceResult(options.serverName, call.tool, resultFindings)
|
|
495
|
+
: prefixResult(message.result, options.serverName, call.tool, framed),
|
|
496
|
+
},
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Whether a verification is one the user must be asked about.
|
|
502
|
+
*
|
|
503
|
+
* A block is enforced without a question. `alert` is the path for a
|
|
504
|
+
* SUSPICIOUS verdict or a list that changed mid-session — the two findings
|
|
505
|
+
* where the user's judgement is the missing piece. A contract error alerts
|
|
506
|
+
* too, but it is about OUR machinery, and asking the user to vouch for a
|
|
507
|
+
* server because our backend disagrees with our client would be asking the
|
|
508
|
+
* wrong person the wrong question.
|
|
509
|
+
*/
|
|
510
|
+
function needsConfirmation(outcome) {
|
|
511
|
+
return (outcome.decision.action === 'alert' &&
|
|
512
|
+
(outcome.verdict === 'suspicious' || outcome.decision.rationale === 'changed-mid-session'));
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* The word put on a result, when the tool's own verdict deserves one.
|
|
516
|
+
*
|
|
517
|
+
* Only a verdict ABOUT THE TOOL — suspicious, malicious, refused by the user,
|
|
518
|
+
* a list that changed under the session — earns the frame. A contract error
|
|
519
|
+
* is about our backend and our client disagreeing: the list-level alert
|
|
520
|
+
* already says so, and a "- ok (tool-verdict)" banner on every result of a
|
|
521
|
+
* clean tool would say nothing at all.
|
|
522
|
+
*/
|
|
523
|
+
function verdictFindingOf(outcome) {
|
|
524
|
+
const { verdict, decision, finding } = outcome;
|
|
525
|
+
const aboutTheTool = verdict === 'suspicious' ||
|
|
526
|
+
verdict === 'malicious' ||
|
|
527
|
+
decision.rationale === 'denied-by-user' ||
|
|
528
|
+
decision.rationale === 'changed-mid-session';
|
|
529
|
+
if (!aboutTheTool)
|
|
530
|
+
return undefined;
|
|
531
|
+
return {
|
|
532
|
+
kind: 'tool-verdict',
|
|
533
|
+
rule: 'tool-verdict',
|
|
534
|
+
where: 'tool',
|
|
535
|
+
detail: finding.reason ? `${finding.kind}: ${finding.reason}` : finding.kind,
|
|
536
|
+
severity: 'high',
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
/** A digest, or nothing: an un-hashable schema is not a reason to fail a call. */
|
|
540
|
+
function safeDigest(tool) {
|
|
541
|
+
try {
|
|
542
|
+
return toolDigest(tool);
|
|
543
|
+
}
|
|
544
|
+
catch {
|
|
545
|
+
return undefined;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/** How big a value is on the wire. Sizes are audited; contents never are. */
|
|
549
|
+
function byteLength(value) {
|
|
550
|
+
if (value === undefined)
|
|
551
|
+
return 0;
|
|
552
|
+
try {
|
|
553
|
+
return Buffer.byteLength(JSON.stringify(value) ?? '', 'utf8');
|
|
554
|
+
}
|
|
555
|
+
catch {
|
|
556
|
+
return 0;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
//# sourceMappingURL=verifyInterceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyInterceptor.js","sourceRoot":"","sources":["../../../src/mcp/proxy/verifyInterceptor.ts"],"names":[],"mappings":"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"}
|