@claude-flow/security 3.0.0-alpha.8 → 3.0.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/dist/CVE-REMEDIATION.d.ts +17 -6
- package/dist/CVE-REMEDIATION.d.ts.map +1 -1
- package/dist/CVE-REMEDIATION.js +328 -12
- package/dist/CVE-REMEDIATION.js.map +1 -1
- package/dist/authorization/propagator.d.ts +148 -0
- package/dist/authorization/propagator.d.ts.map +1 -0
- package/dist/authorization/propagator.js +182 -0
- package/dist/authorization/propagator.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -1
- package/dist/keychain-adapter.d.ts +48 -0
- package/dist/keychain-adapter.d.ts.map +1 -0
- package/dist/keychain-adapter.js +0 -0
- package/dist/keychain-adapter.js.map +1 -0
- package/dist/mcp-caller-identity.d.ts +101 -0
- package/dist/mcp-caller-identity.d.ts.map +1 -0
- package/dist/mcp-caller-identity.js +0 -0
- package/dist/mcp-caller-identity.js.map +1 -0
- package/dist/mcp-composition-inspector.d.ts +133 -0
- package/dist/mcp-composition-inspector.d.ts.map +1 -0
- package/dist/mcp-composition-inspector.js +254 -0
- package/dist/mcp-composition-inspector.js.map +1 -0
- package/dist/oauth/browser.d.ts +31 -0
- package/dist/oauth/browser.d.ts.map +1 -0
- package/dist/oauth/browser.js +55 -0
- package/dist/oauth/browser.js.map +1 -0
- package/dist/oauth/callback-server.d.ts +37 -0
- package/dist/oauth/callback-server.d.ts.map +1 -0
- package/dist/oauth/callback-server.js +86 -0
- package/dist/oauth/callback-server.js.map +1 -0
- package/dist/oauth/client.d.ts +57 -0
- package/dist/oauth/client.d.ts.map +1 -0
- package/dist/oauth/client.js +120 -0
- package/dist/oauth/client.js.map +1 -0
- package/dist/oauth/pkce.d.ts +25 -0
- package/dist/oauth/pkce.d.ts.map +1 -0
- package/dist/oauth/pkce.js +36 -0
- package/dist/oauth/pkce.js.map +1 -0
- package/dist/path-validator.d.ts +23 -0
- package/dist/path-validator.d.ts.map +1 -1
- package/dist/path-validator.js +128 -5
- package/dist/path-validator.js.map +1 -1
- package/dist/plugins/integrity-verifier.d.ts +125 -0
- package/dist/plugins/integrity-verifier.d.ts.map +1 -0
- package/dist/plugins/integrity-verifier.js +186 -0
- package/dist/plugins/integrity-verifier.js.map +1 -0
- package/dist/policy/canonical.d.ts +5 -0
- package/dist/policy/canonical.d.ts.map +1 -0
- package/dist/policy/canonical.js +30 -0
- package/dist/policy/canonical.js.map +1 -0
- package/dist/policy/engine.d.ts +34 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +285 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/envelope.d.ts +9 -0
- package/dist/policy/envelope.d.ts.map +1 -0
- package/dist/policy/envelope.js +90 -0
- package/dist/policy/envelope.js.map +1 -0
- package/dist/policy/evaluator.d.ts +4 -0
- package/dist/policy/evaluator.d.ts.map +1 -0
- package/dist/policy/evaluator.js +119 -0
- package/dist/policy/evaluator.js.map +1 -0
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +7 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/product-plane.d.ts +238 -0
- package/dist/policy/product-plane.d.ts.map +1 -0
- package/dist/policy/product-plane.js +1022 -0
- package/dist/policy/product-plane.js.map +1 -0
- package/dist/policy/types.d.ts +169 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +2 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/safe-git.d.ts +22 -0
- package/dist/safe-git.d.ts.map +1 -0
- package/dist/safe-git.js +63 -0
- package/dist/safe-git.js.map +1 -0
- package/dist/tool-output-guardrail.d.ts +126 -0
- package/dist/tool-output-guardrail.d.ts.map +1 -0
- package/dist/tool-output-guardrail.js +257 -0
- package/dist/tool-output-guardrail.js.map +1 -0
- package/package.json +17 -5
- package/__tests__/acceptance/security-compliance.test.ts +0 -674
- package/__tests__/credential-generator.test.ts +0 -310
- package/__tests__/fixtures/configurations.ts +0 -425
- package/__tests__/fixtures/index.ts +0 -21
- package/__tests__/helpers/create-mock.ts +0 -469
- package/__tests__/helpers/index.ts +0 -32
- package/__tests__/input-validator.test.ts +0 -382
- package/__tests__/integration/security-flow.test.ts +0 -606
- package/__tests__/password-hasher.test.ts +0 -239
- package/__tests__/path-validator.test.ts +0 -302
- package/__tests__/safe-executor.test.ts +0 -292
- package/__tests__/token-generator.test.ts +0 -371
- package/__tests__/unit/credential-generator.test.ts +0 -182
- package/__tests__/unit/password-hasher.test.ts +0 -359
- package/__tests__/unit/path-validator.test.ts +0 -509
- package/__tests__/unit/safe-executor.test.ts +0 -667
- package/__tests__/unit/token-generator.test.ts +0 -310
- package/ruvector.db +0 -0
- package/src/CVE-REMEDIATION.ts +0 -251
- package/src/application/index.ts +0 -10
- package/src/application/services/security-application-service.ts +0 -193
- package/src/credential-generator.ts +0 -368
- package/src/domain/entities/security-context.ts +0 -173
- package/src/domain/index.ts +0 -17
- package/src/domain/services/security-domain-service.ts +0 -296
- package/src/index.ts +0 -271
- package/src/input-validator.ts +0 -466
- package/src/password-hasher.ts +0 -277
- package/src/path-validator.ts +0 -525
- package/src/safe-executor.ts +0 -546
- package/src/token-generator.ts +0 -463
- package/tmp.json +0 -0
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
- package/vitest.config.ts +0 -20
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentAuthorizationPropagator — action-layer security for agent delegation.
|
|
3
|
+
*
|
|
4
|
+
* Implements P1 of ADR-144 (ruvnet/ruflo#2248): scope-envelope on SendMessage
|
|
5
|
+
* + per-action authorization checks. P2-P5 wire this into the comms layer,
|
|
6
|
+
* MCP dispatcher, MCP auth validator, and provenance log respectively.
|
|
7
|
+
*
|
|
8
|
+
* Threat model
|
|
9
|
+
* ------------
|
|
10
|
+
* When agent A delegates a task to agent B via SendMessage, B can today
|
|
11
|
+
* escalate the granted scope by calling tools A was never authorized to
|
|
12
|
+
* invoke. RBAC/ABAC on agent roles do not solve this — roles don't compose
|
|
13
|
+
* under dynamic LLM delegation (arXiv:2605.05440, Grade A formal analysis).
|
|
14
|
+
*
|
|
15
|
+
* The fix is scope-based propagation: every SendMessage carries an
|
|
16
|
+
* `AuthScope` that is *monotonically reducing* — each hop can drop tools or
|
|
17
|
+
* servers from the granted set but never add them. This is the same shape
|
|
18
|
+
* as OAuth scope reduction; adding back a tool requires talking to the
|
|
19
|
+
* original principal out-of-band.
|
|
20
|
+
*
|
|
21
|
+
* Scope
|
|
22
|
+
* -----
|
|
23
|
+
* - P1 (this file): the component, the envelope, the type-level invariants.
|
|
24
|
+
* No call sites yet — adding the wrapping/enforcement in P2-P4.
|
|
25
|
+
* - All operations synchronous, pure, allocation-light. Targets < 1 ms p99
|
|
26
|
+
* for `wrapOutbound` + `checkToolCall` so it can sit on every SendMessage.
|
|
27
|
+
*
|
|
28
|
+
* Backwards compatibility
|
|
29
|
+
* -----------------------
|
|
30
|
+
* `scope` on the envelope is optional in v1. Agents without scope set
|
|
31
|
+
* operate in legacy permissive mode (all tools allowed, depth unlimited,
|
|
32
|
+
* server auth unchecked). `CLAUDE_FLOW_STRICT_AUTH=true` enables enforcement.
|
|
33
|
+
*
|
|
34
|
+
* Reference: ADR-144, arXiv:2605.05440 (Authorization Propagation),
|
|
35
|
+
* arXiv:2605.28914 (AIRGuard), arXiv:2605.22333 (MCP auth survey).
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Wrap-failure reasons surfaced to callers as a typed error. We use a
|
|
39
|
+
* discriminated union rather than throwing so the comms layer (P2) can
|
|
40
|
+
* decide whether to drop the SendMessage or surface to the user.
|
|
41
|
+
*/
|
|
42
|
+
export class AuthorizationPropagationError extends Error {
|
|
43
|
+
code;
|
|
44
|
+
constructor(code, message) {
|
|
45
|
+
super(message);
|
|
46
|
+
this.code = code;
|
|
47
|
+
this.name = 'AuthorizationPropagationError';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Construct a default permissive scope. Used in legacy mode when no scope
|
|
52
|
+
* was attached upstream. Callers SHOULD migrate to explicit scopes; this is
|
|
53
|
+
* here so the propagator never has to special-case "no scope".
|
|
54
|
+
*/
|
|
55
|
+
export function makeLegacyPermissiveScope(principalId = 'legacy') {
|
|
56
|
+
return {
|
|
57
|
+
principalId,
|
|
58
|
+
grantedTools: ['*'], // sentinel — see `checkToolCall`
|
|
59
|
+
grantedServers: ['*'],
|
|
60
|
+
delegationDepth: Number.MAX_SAFE_INTEGER,
|
|
61
|
+
expiresAt: Number.MAX_SAFE_INTEGER,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* `AgentAuthorizationPropagator` — the load-bearing component for ADR-144.
|
|
66
|
+
*
|
|
67
|
+
* Construction is intentionally cheap (no I/O, no async). Callers can build
|
|
68
|
+
* a fresh instance per task without overhead, or share one — it holds no
|
|
69
|
+
* mutable state beyond the optional provenance buffer.
|
|
70
|
+
*/
|
|
71
|
+
export class AgentAuthorizationPropagator {
|
|
72
|
+
opts;
|
|
73
|
+
/**
|
|
74
|
+
* In-memory provenance buffer. P5 will flush this to the structured
|
|
75
|
+
* telemetry sink (ADR-146 GuardrailEvent shape). For P1 we just retain
|
|
76
|
+
* the last N events for inspection/tests.
|
|
77
|
+
*/
|
|
78
|
+
provenance = [];
|
|
79
|
+
constructor(opts = {}) {
|
|
80
|
+
this.opts = opts;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Attach a reduced scope to an outbound SendMessage.
|
|
84
|
+
*
|
|
85
|
+
* Invariants enforced (throws `AuthorizationPropagationError` on violation):
|
|
86
|
+
* - newly granted tools MUST be a subset of `currentScope.grantedTools`
|
|
87
|
+
* - newly granted servers MUST be a subset of `currentScope.grantedServers`
|
|
88
|
+
* - delegationDepth MUST decrement by ≥ 1 (must remain ≥ 0)
|
|
89
|
+
* - principalId is propagated unchanged
|
|
90
|
+
* - expiresAt cannot be extended; copied from the holder
|
|
91
|
+
*/
|
|
92
|
+
wrapOutbound(payload, currentScope, requested = {}) {
|
|
93
|
+
if (currentScope.delegationDepth <= 0) {
|
|
94
|
+
throw new AuthorizationPropagationError('depth-underflow', `cannot delegate further — delegationDepth=${currentScope.delegationDepth}`);
|
|
95
|
+
}
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
if (currentScope.expiresAt <= now) {
|
|
98
|
+
throw new AuthorizationPropagationError('scope-expired', `scope expired at ${new Date(currentScope.expiresAt).toISOString()}`);
|
|
99
|
+
}
|
|
100
|
+
const reducedTools = subsetOrThrow(currentScope.grantedTools, requested.tools ?? currentScope.grantedTools, 'tools');
|
|
101
|
+
const reducedServers = subsetOrThrow(currentScope.grantedServers, requested.servers ?? currentScope.grantedServers, 'servers');
|
|
102
|
+
const reducedScope = {
|
|
103
|
+
principalId: currentScope.principalId,
|
|
104
|
+
grantedTools: reducedTools,
|
|
105
|
+
grantedServers: reducedServers,
|
|
106
|
+
delegationDepth: currentScope.delegationDepth - 1,
|
|
107
|
+
expiresAt: currentScope.expiresAt,
|
|
108
|
+
scopeId: currentScope.scopeId,
|
|
109
|
+
};
|
|
110
|
+
return { scope: reducedScope, payload };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Validate a single tool call against a scope. Pure; never throws. Use the
|
|
114
|
+
* result's `allowed` to make the dispatch decision.
|
|
115
|
+
*/
|
|
116
|
+
checkToolCall(toolId, scope, opts = {}) {
|
|
117
|
+
const now = opts.now ?? Date.now();
|
|
118
|
+
if (scope.expiresAt <= now)
|
|
119
|
+
return { allowed: false, reason: 'scope-expired' };
|
|
120
|
+
if (!matchesScopeList(scope.grantedTools, toolId)) {
|
|
121
|
+
return { allowed: false, reason: 'tool-not-in-scope' };
|
|
122
|
+
}
|
|
123
|
+
if (opts.serverId && !matchesScopeList(scope.grantedServers, opts.serverId)) {
|
|
124
|
+
return { allowed: false, reason: 'server-not-in-scope' };
|
|
125
|
+
}
|
|
126
|
+
return { allowed: true };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Verify an MCP server presented a valid credential before its response is
|
|
130
|
+
* consumed. P1 ships a permissive default (any non-empty credential is
|
|
131
|
+
* accepted) so the API is stable; P4 wires this to a real validator.
|
|
132
|
+
*
|
|
133
|
+
* Returns `false` on missing/empty credential; callers MUST treat `false`
|
|
134
|
+
* as a hard reject (same rule as ADR-131 reject findings).
|
|
135
|
+
*/
|
|
136
|
+
verifyServerAuth(serverId, credential) {
|
|
137
|
+
if (!serverId || typeof serverId !== 'string')
|
|
138
|
+
return false;
|
|
139
|
+
if (credential == null)
|
|
140
|
+
return false;
|
|
141
|
+
if (typeof credential === 'string' && credential.trim().length === 0)
|
|
142
|
+
return false;
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Record an action in the provenance buffer. P5 will route to telemetry;
|
|
147
|
+
* P1 keeps the last N events for test inspection and post-incident audit.
|
|
148
|
+
*/
|
|
149
|
+
recordAction(agentId, toolId, scope, outcome, reason) {
|
|
150
|
+
const max = this.opts.provenanceBufferMax ?? 1024;
|
|
151
|
+
this.provenance.push({ agentId, toolId, scope, outcome, reason, ts: Date.now() });
|
|
152
|
+
if (this.provenance.length > max)
|
|
153
|
+
this.provenance.splice(0, this.provenance.length - max);
|
|
154
|
+
}
|
|
155
|
+
/** Read-only view of recorded provenance for tests + audit CLI (P5). */
|
|
156
|
+
getProvenance() {
|
|
157
|
+
return this.provenance.slice();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// ─── helpers ────────────────────────────────────────────────────────────
|
|
161
|
+
function subsetOrThrow(parent, requested, kind) {
|
|
162
|
+
if (parent.includes('*'))
|
|
163
|
+
return Array.from(new Set(requested));
|
|
164
|
+
for (const item of requested) {
|
|
165
|
+
if (!parent.includes(item) && item !== '*') {
|
|
166
|
+
throw new AuthorizationPropagationError('scope-cannot-grow', `cannot grant ${kind} '${item}' — not in parent scope`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// De-duplicate; preserve requested order
|
|
170
|
+
const seen = new Set();
|
|
171
|
+
const out = [];
|
|
172
|
+
for (const r of requested)
|
|
173
|
+
if (!seen.has(r))
|
|
174
|
+
(seen.add(r), out.push(r));
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
function matchesScopeList(list, item) {
|
|
178
|
+
if (list.includes('*'))
|
|
179
|
+
return true;
|
|
180
|
+
return list.includes(item);
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=propagator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propagator.js","sourceRoot":"","sources":["../../src/authorization/propagator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,17 @@ export { SafeExecutor, SafeExecutorError, createDevelopmentExecutor, createReadO
|
|
|
19
19
|
export { PathValidator, PathValidatorError, createProjectPathValidator, createFullProjectPathValidator, type PathValidatorConfig, type PathValidationResult, } from './path-validator.js';
|
|
20
20
|
export { InputValidator, sanitizeString, sanitizeHtml, sanitizePath, SafeStringSchema, IdentifierSchema, FilenameSchema, EmailSchema, PasswordSchema, UUIDSchema, HttpsUrlSchema, UrlSchema, SemverSchema, PortSchema, IPv4Schema, IPSchema, UserRoleSchema, PermissionSchema, LoginRequestSchema, CreateUserSchema, CreateApiKeySchema, AgentTypeSchema, SpawnAgentSchema, TaskInputSchema, CommandArgumentSchema, PathSchema, SecurityConfigSchema, ExecutorConfigSchema, PATTERNS, LIMITS, z, } from './input-validator.js';
|
|
21
21
|
export { TokenGenerator, TokenGeneratorError, createTokenGenerator, getDefaultGenerator, quickGenerate, type TokenConfig, type Token, type SignedToken, type VerificationCode, } from './token-generator.js';
|
|
22
|
+
export { ToolOutputGuardrail, createToolOutputGuardrail, isToolOutputSafe, type GuardrailConfig, type GuardrailResult, type GuardrailAction, type InjectionFinding, type InjectionSeverity, type InjectionCategory, } from './tool-output-guardrail.js';
|
|
23
|
+
export { AgentAuthorizationPropagator, AuthorizationPropagationError, makeLegacyPermissiveScope, type AuthScope, type SendMessageEnvelope, type ToolCallDecision, } from './authorization/propagator.js';
|
|
24
|
+
export { generateCallerIdentityKey, loadCallerIdentityKey, issueInvocationToken, verifyInvocationToken, isMcpCallerAuthEnabled, publicKeyFromHex, encodeTokenEnvelope, decodeTokenEnvelope, type CallerIdentityKey, type InvocationToken, type TokenVerificationResult, } from './mcp-caller-identity.js';
|
|
25
|
+
export * from './policy/index.js';
|
|
26
|
+
export { CLIENT_ID as OAUTH_CLIENT_ID, SCOPE as OAUTH_SCOPE, OOB_REDIRECT_URI, OAuthError, authorizeUrl, exchangeCode, refreshToken, exchangeManualCode, type TokenResponse as OAuthTokenResponse, } from './oauth/client.js';
|
|
27
|
+
export { generate as generatePkce, challengeFromVerifier, type PkceRequest } from './oauth/pkce.js';
|
|
28
|
+
export { CallbackServer, CallbackTimeoutError, type CallbackResult } from './oauth/callback-server.js';
|
|
29
|
+
export { openBrowser } from './oauth/browser.js';
|
|
30
|
+
export { createKeychainAdapter, SessionOnlyKeychainAdapter, type KeychainAdapter, } from './keychain-adapter.js';
|
|
31
|
+
export { PluginIntegrityVerifier, canonicalize, hashManifest, fingerprint, findAnchor, type PluginManifest, type SignedPluginManifest, type TrustAnchor, type TrustAnchors, type VerificationStatus, type VerificationResult, type VerifierConfig, } from './plugins/integrity-verifier.js';
|
|
32
|
+
export { inspectToolComposition, evaluateToolComposition, isCompositionBlockEnabled, fnv1a64, simhash64, hammingDistance64, type McpToolDescriptor, type CompositionInspectorOptions, type CompositionFinding, type CompositionInspectionStats, type CompositionInspectionResult, type CompositionGuardResult, } from './mcp-composition-inspector.js';
|
|
22
33
|
import { PasswordHasher } from './password-hasher.js';
|
|
23
34
|
import { CredentialGenerator } from './credential-generator.js';
|
|
24
35
|
import { SafeExecutor } from './safe-executor.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,GAC9B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,8BAA8B,EAC9B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,cAAc,EACd,cAAc,EACd,YAAY,EACZ,YAAY,EAEZ,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,cAAc,EACd,UAAU,EACV,cAAc,EACd,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,QAAQ,EAER,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAElB,eAAe,EACf,gBAAgB,EAChB,eAAe,EAEf,qBAAqB,EACrB,UAAU,EAEV,oBAAoB,EACpB,oBAAoB,EAEpB,QAAQ,EACR,MAAM,EACN,CAAC,GACF,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,42 @@ SecurityConfigSchema, ExecutorConfigSchema,
|
|
|
37
37
|
PATTERNS, LIMITS, z, } from './input-validator.js';
|
|
38
38
|
// Token Generation
|
|
39
39
|
export { TokenGenerator, TokenGeneratorError, createTokenGenerator, getDefaultGenerator, quickGenerate, } from './token-generator.js';
|
|
40
|
+
// Tool-Output Guardrail (ADR-131 — closes OWASP ASI01 gap; ruvnet/ruflo#2149)
|
|
41
|
+
export { ToolOutputGuardrail, createToolOutputGuardrail, isToolOutputSafe, } from './tool-output-guardrail.js';
|
|
42
|
+
// Agent Authorization Propagation (ADR-144 P1 — ruvnet/ruflo#2248)
|
|
43
|
+
// Action-layer: SendMessage envelope + per-action scope check + MCP server
|
|
44
|
+
// identity probe. Wraps the comms layer in P2; wraps the dispatcher in P3.
|
|
45
|
+
export { AgentAuthorizationPropagator, AuthorizationPropagationError, makeLegacyPermissiveScope, } from './authorization/propagator.js';
|
|
46
|
+
// MCP Caller-Identity Binding (ADR-377 Phase 3 — ruvnet/ruflo#2516, #2873)
|
|
47
|
+
// Per-invocation Ed25519-signed capability tokens. Off by default
|
|
48
|
+
// (CLAUDE_FLOW_MCP_CALLER_AUTH) pending a follow-on ADR for key
|
|
49
|
+
// distribution; see mcp-caller-identity.ts's file header for scope notes.
|
|
50
|
+
export { generateCallerIdentityKey, loadCallerIdentityKey, issueInvocationToken, verifyInvocationToken, isMcpCallerAuthEnabled, publicKeyFromHex, encodeTokenEnvelope, decodeTokenEnvelope, } from './mcp-caller-identity.js';
|
|
51
|
+
// Agentic Policy Engine (ADR-324)
|
|
52
|
+
// Deterministic policy evaluation, monotonic capability envelopes, approvals,
|
|
53
|
+
// budgets, and tamper-evident decision receipts. Legacy mode preserves the
|
|
54
|
+
// behavior of pre-ADR-324 installations until enforcement is explicitly enabled.
|
|
55
|
+
export * from './policy/index.js';
|
|
56
|
+
// OAuth 2.0 + PKCE + OS Keychain (ADR-306)
|
|
57
|
+
// A TypeScript port of meta-proxy's proven oauth/{client,pkce,browser,
|
|
58
|
+
// callback_server}.rs — see src/oauth/client.ts for why this targets the
|
|
59
|
+
// live auth.cognitum.one surface rather than ADR-308's unconfirmed spec.
|
|
60
|
+
export { CLIENT_ID as OAUTH_CLIENT_ID, SCOPE as OAUTH_SCOPE, OOB_REDIRECT_URI, OAuthError, authorizeUrl, exchangeCode, refreshToken, exchangeManualCode, } from './oauth/client.js';
|
|
61
|
+
export { generate as generatePkce, challengeFromVerifier } from './oauth/pkce.js';
|
|
62
|
+
export { CallbackServer, CallbackTimeoutError } from './oauth/callback-server.js';
|
|
63
|
+
export { openBrowser } from './oauth/browser.js';
|
|
64
|
+
// OS Keychain Adapter (ADR-306)
|
|
65
|
+
export { createKeychainAdapter, SessionOnlyKeychainAdapter, } from './keychain-adapter.js';
|
|
66
|
+
// Plugin Integrity Verifier (ADR-145 P1 — ruvnet/ruflo#2254)
|
|
67
|
+
// Install-layer: Ed25519 signature verification + trust-anchor allowlist.
|
|
68
|
+
// Stage-2 semantic-intent scan (SCH defence) lands in P2.
|
|
69
|
+
export { PluginIntegrityVerifier, canonicalize, hashManifest, fingerprint, findAnchor, } from './plugins/integrity-verifier.js';
|
|
70
|
+
// MCP Tool Composition Inspector (ADR-320 — ruvnet/ruflo dream-cycle,
|
|
71
|
+
// arXiv:2606.27027 "ShareLock"). SimHash-based cross-tool instruction
|
|
72
|
+
// fragment detector — the v2 successor to the CLI-only v1 in
|
|
73
|
+
// @claude-flow/cli/src/security/mcp-composition-inspector.ts (#2783),
|
|
74
|
+
// whose own header deferred exactly this ("Future v2: SimHash + LSH").
|
|
75
|
+
export { inspectToolComposition, evaluateToolComposition, isCompositionBlockEnabled, fnv1a64, simhash64, hammingDistance64, } from './mcp-composition-inspector.js';
|
|
40
76
|
// ============================================================================
|
|
41
77
|
// Convenience Factory Functions
|
|
42
78
|
// ============================================================================
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform OS keychain adapter (ADR-306) — macOS Keychain, Windows
|
|
3
|
+
* Credential Manager (DPAPI), Linux Secret Service (libsecret), backed by
|
|
4
|
+
* `@napi-rs/keyring` (prebuilt N-API binaries per platform, wraps the Rust
|
|
5
|
+
* `keyring-rs` crate — no node-gyp compile step, same "optional native
|
|
6
|
+
* binding" shape this monorepo already tolerates for `ruvector`).
|
|
7
|
+
*
|
|
8
|
+
* `keytar` was considered and rejected: archived by the Electron team,
|
|
9
|
+
* compiles from source via node-gyp at install time.
|
|
10
|
+
*
|
|
11
|
+
* ADR-306's refresh-token storage rule: OS keychain only, never plain-text
|
|
12
|
+
* config. When no keychain backend is reachable (typical headless Linux —
|
|
13
|
+
* the binding can be present but no D-Bus Secret Service running), the CLI
|
|
14
|
+
* falls back to session-only tokens (never persisted) rather than writing
|
|
15
|
+
* the secret to disk unencrypted — a deliberate usability cost, not a bug.
|
|
16
|
+
* `SessionOnlyKeychainAdapter` is that fallback, made explicit rather than
|
|
17
|
+
* silently degrading.
|
|
18
|
+
*
|
|
19
|
+
* @module v3/security/keychain-adapter
|
|
20
|
+
*/
|
|
21
|
+
export interface KeychainAdapter {
|
|
22
|
+
/**
|
|
23
|
+
* A real write+read+delete canary probe against a throwaway entry — not
|
|
24
|
+
* just "did the native module load". A headless box can have the binding
|
|
25
|
+
* present but no reachable Secret Service, which only a real round-trip
|
|
26
|
+
* reveals.
|
|
27
|
+
*/
|
|
28
|
+
isAvailable(): Promise<boolean>;
|
|
29
|
+
setSecret(service: string, account: string, secret: string): Promise<void>;
|
|
30
|
+
getSecret(service: string, account: string): Promise<string | null>;
|
|
31
|
+
deleteSecret(service: string, account: string): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
/** In-memory-only fallback — the ADR-306-mandated degrade path, not an error state. */
|
|
34
|
+
export declare class SessionOnlyKeychainAdapter implements KeychainAdapter {
|
|
35
|
+
private readonly store;
|
|
36
|
+
private key;
|
|
37
|
+
isAvailable(): Promise<boolean>;
|
|
38
|
+
setSecret(service: string, account: string, secret: string): Promise<void>;
|
|
39
|
+
getSecret(service: string, account: string): Promise<string | null>;
|
|
40
|
+
deleteSecret(service: string, account: string): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Selects a real OS keychain when reachable, falling back to
|
|
44
|
+
* `SessionOnlyKeychainAdapter` otherwise. Always resolves — never throws —
|
|
45
|
+
* so callers can treat "no keychain" as a normal, expected outcome.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createKeychainAdapter(): Promise<KeychainAdapter>;
|
|
48
|
+
//# sourceMappingURL=keychain-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain-adapter.d.ts","sourceRoot":"","sources":["../src/keychain-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAKD,uFAAuF;AACvF,qBAAa,0BAA2B,YAAW,eAAe;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD,OAAO,CAAC,GAAG;IAIL,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1E,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAInE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGpE;AAiED;;;;GAIG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,eAAe,CAAC,CAItE"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain-adapter.js","sourceRoot":"","sources":["../src/keychain-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* McpCallerIdentity — ADR-377 Phase 3 (ruvnet/ruflo#2516, #2873).
|
|
3
|
+
*
|
|
4
|
+
* Per-invocation, Ed25519-signed capability tokens binding an MCP tool call
|
|
5
|
+
* to a specific caller. Closes the gap identified in arXiv:2603.07473
|
|
6
|
+
* (Caller Identity Confusion in MCP): authorization state today persists
|
|
7
|
+
* across callers with no re-verification, and `AgentAuthorizationPropagator`
|
|
8
|
+
* (ADR-144)'s `checkToolCall` validates a *scope* but not that the caller
|
|
9
|
+
* presenting it is who they claim to be for *this* call.
|
|
10
|
+
*
|
|
11
|
+
* Signing implementation follows the same pattern already used in this repo
|
|
12
|
+
* for Ed25519 signing (`@claude-flow/browser`'s `witness-signer.ts`): native
|
|
13
|
+
* `node:crypto`, zero new dependencies, sign+verify both supported (unlike
|
|
14
|
+
* `@claude-flow/security`'s own `plugins/integrity-verifier.ts`, which uses
|
|
15
|
+
* `@noble/ed25519` for verify-only). Reimplemented here rather than imported
|
|
16
|
+
* from `@claude-flow/browser` because a security-primitives module
|
|
17
|
+
* depending on the browser package would be a backwards layering
|
|
18
|
+
* dependency; the pattern is ~15 lines and not worth a cross-package import
|
|
19
|
+
* for that.
|
|
20
|
+
*
|
|
21
|
+
* Scope and honest limitations (per the ADR's own text)
|
|
22
|
+
* --------------------------------------------------------
|
|
23
|
+
* This module implements token issuance/verification only. It does NOT
|
|
24
|
+
* wire itself into any MCP tool dispatcher — this repo currently has at
|
|
25
|
+
* least two distinct `ToolRegistry` implementations
|
|
26
|
+
* (`v3/mcp/tool-registry.ts`, `v3/@claude-flow/mcp/src/tool-registry.ts`)
|
|
27
|
+
* plus a third under `@claude-flow/shared`, and it was not safe to guess
|
|
28
|
+
* which one is authoritative without risking silently wiring the wrong
|
|
29
|
+
* dispatch path. `AgentAuthorizationPropagator.checkToolCall` (ADR-144) is
|
|
30
|
+
* the natural composition point — call `verifyInvocationToken` first and
|
|
31
|
+
* only proceed to `checkToolCall` if it passes — but that composition is
|
|
32
|
+
* left to the caller rather than baked into `checkToolCall` itself, to
|
|
33
|
+
* avoid changing ADR-144's already-shipped, already-tested behavior.
|
|
34
|
+
*
|
|
35
|
+
* Key distribution (how callers obtain a private key to sign with in the
|
|
36
|
+
* first place) is explicitly out of scope — the ADR calls for "a follow-on
|
|
37
|
+
* ADR for key distribution" before this ships enabled by default, which is
|
|
38
|
+
* why `CLAUDE_FLOW_MCP_CALLER_AUTH` defaults to disabled.
|
|
39
|
+
*/
|
|
40
|
+
import type { KeyObject } from 'node:crypto';
|
|
41
|
+
export interface CallerIdentityKey {
|
|
42
|
+
privateKey: KeyObject;
|
|
43
|
+
publicKey: KeyObject;
|
|
44
|
+
publicKeyHex: string;
|
|
45
|
+
}
|
|
46
|
+
export interface InvocationToken {
|
|
47
|
+
/** Agent/principal id of the caller this token was issued to. */
|
|
48
|
+
callerId: string;
|
|
49
|
+
/** Tool this token authorizes — a token issued for one tool cannot be
|
|
50
|
+
* replayed against another. */
|
|
51
|
+
toolName: string;
|
|
52
|
+
/** Unix ms the token was issued. */
|
|
53
|
+
issuedAt: number;
|
|
54
|
+
/** Unix ms after which the token is no longer valid. */
|
|
55
|
+
expiresAt: number;
|
|
56
|
+
/** Random per-token value; prevents replay of an otherwise-identical
|
|
57
|
+
* token issued in the same millisecond. */
|
|
58
|
+
nonce: string;
|
|
59
|
+
/** Hex-encoded Ed25519 signature over the canonicalized fields above. */
|
|
60
|
+
signature: string;
|
|
61
|
+
}
|
|
62
|
+
export interface TokenVerificationResult {
|
|
63
|
+
valid: boolean;
|
|
64
|
+
reason?: 'expired' | 'bad-signature' | 'tool-mismatch';
|
|
65
|
+
}
|
|
66
|
+
/** Generate a fresh Ed25519 keypair. */
|
|
67
|
+
export declare function generateCallerIdentityKey(): CallerIdentityKey;
|
|
68
|
+
/** Load a caller-identity key from a PEM-encoded private key string. */
|
|
69
|
+
export declare function loadCallerIdentityKey(privateKeyPem: string): CallerIdentityKey;
|
|
70
|
+
/**
|
|
71
|
+
* Issue a fresh, signed `InvocationToken` for `callerId` to call `toolName`.
|
|
72
|
+
* Callers must present a *new* token per invocation — tokens are
|
|
73
|
+
* single-tool-bound and short-lived (`ttlMs`, default 30s) by design; there
|
|
74
|
+
* is no renewal API on purpose.
|
|
75
|
+
*/
|
|
76
|
+
export declare function issueInvocationToken(callerId: string, toolName: string, key: CallerIdentityKey, opts?: {
|
|
77
|
+
ttlMs?: number;
|
|
78
|
+
now?: number;
|
|
79
|
+
}): InvocationToken;
|
|
80
|
+
/**
|
|
81
|
+
* Verify an `InvocationToken` against the issuing caller's public key and
|
|
82
|
+
* (if provided) the tool the caller is about to invoke. Never throws.
|
|
83
|
+
*/
|
|
84
|
+
export declare function verifyInvocationToken(token: InvocationToken, publicKey: KeyObject, opts?: {
|
|
85
|
+
toolName?: string;
|
|
86
|
+
now?: number;
|
|
87
|
+
}): TokenVerificationResult;
|
|
88
|
+
/** Off by default — see the file header re: key distribution being out of scope pending a follow-on ADR. Only the literal `'true'` enables enforcement. */
|
|
89
|
+
export declare function isMcpCallerAuthEnabled(): boolean;
|
|
90
|
+
/** Inverse of `extractPublicKeyHex`: rebuild a `KeyObject` from the raw hex it produced. */
|
|
91
|
+
export declare function publicKeyFromHex(hex: string): KeyObject;
|
|
92
|
+
/**
|
|
93
|
+
* Pack an `InvocationToken` into one env-var-safe string (JSON + base64url).
|
|
94
|
+
* The issuer's public key travels in its own env var (set alongside this
|
|
95
|
+
* one, hex is already env-var-safe) rather than being folded in here — kept
|
|
96
|
+
* separate to mirror how the two values are set independently at spawn time.
|
|
97
|
+
*/
|
|
98
|
+
export declare function encodeTokenEnvelope(token: InvocationToken): string;
|
|
99
|
+
/** Inverse of `encodeTokenEnvelope`. Never throws — returns `undefined` on any malformed input. */
|
|
100
|
+
export declare function decodeTokenEnvelope(encoded: string): InvocationToken | undefined;
|
|
101
|
+
//# sourceMappingURL=mcp-caller-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-caller-identity.d.ts","sourceRoot":"","sources":["../src/mcp-caller-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB;mCAC+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB;+CAC2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,GAAG,eAAe,GAAG,eAAe,CAAC;CACxD;AAeD,wCAAwC;AACxC,wBAAgB,yBAAyB,IAAI,iBAAiB,CAG7D;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB,CAI9E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,iBAAiB,EACtB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,eAAe,CAWjB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,SAAS,EACpB,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,uBAAuB,CAgBzB;AAQD,2JAA2J;AAC3J,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAoBD,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAMvD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAElE;AAED,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAmBhF"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-caller-identity.js","sourceRoot":"","sources":["../src/mcp-caller-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Composition Inspector — ADR-320 (this ADR; ruvnet/ruflo dream-cycle
|
|
3
|
+
* proposal, arXiv:2606.27027 "ShareLock").
|
|
4
|
+
*
|
|
5
|
+
* The attack: an adversary registers N seemingly-benign MCP tools whose
|
|
6
|
+
* individual descriptions look fine in isolation, but whose CONCATENATION
|
|
7
|
+
* (or pairwise overlap) forms an injection payload targeting a downstream
|
|
8
|
+
* agent — a Shamir-secret-sharing-style split across tool descriptions.
|
|
9
|
+
* Per-tool inspection misses this because each fragment sits under any
|
|
10
|
+
* single-tool detection threshold.
|
|
11
|
+
*
|
|
12
|
+
* Relationship to prior art in this repo
|
|
13
|
+
* ---------------------------------------
|
|
14
|
+
* A CLI-only v1 of this idea already shipped directly to `main`
|
|
15
|
+
* (dream-cycle #2783, commits 381b7ebcc/581cd2bf3) as
|
|
16
|
+
* `v3/@claude-flow/cli/src/security/mcp-composition-inspector.ts` — an
|
|
17
|
+
* on-demand `ruflo security composition-scan` command using exact
|
|
18
|
+
* common-substring matching plus an injection-phrase catalog and
|
|
19
|
+
* typosquat check. That module's own header explicitly scopes itself as
|
|
20
|
+
* "a bounded engineering fix rather than an ADR-scope subsystem" and lists
|
|
21
|
+
* "Future v2: SimHash + LSH for scale" as deliberately deferred. THIS
|
|
22
|
+
* module is that v2: a reusable `@claude-flow/security` library primitive
|
|
23
|
+
* (not a CLI-only tool) built around a real SimHash fingerprint, so it can
|
|
24
|
+
* be called from a pre-task/pre-tool-use hook before a multi-tool chain
|
|
25
|
+
* executes, per this ADR's implementation target. It does not replace or
|
|
26
|
+
* import the CLI v1 — the two are independent, complementary detectors
|
|
27
|
+
* (exact-substring vs. hashed-shingle-overlap) that a caller may run
|
|
28
|
+
* together.
|
|
29
|
+
*
|
|
30
|
+
* Detection method (deterministic, no LLM call)
|
|
31
|
+
* -----------------------------------------------
|
|
32
|
+
* 1. Each tool description is normalized and split into overlapping
|
|
33
|
+
* word-shingles (default: 5-word windows). Shingling — rather than
|
|
34
|
+
* whole-description comparison — is what lets us find a SMALL embedded
|
|
35
|
+
* fragment inside an otherwise unrelated, benign description.
|
|
36
|
+
* 2. Each tool gets a 64-bit SimHash fingerprint: every shingle is hashed
|
|
37
|
+
* (FNV-1a, 64-bit) and the fingerprint bits are set by majority vote
|
|
38
|
+
* across all of a tool's shingle hashes. Two tools whose descriptions
|
|
39
|
+
* share enough content have a SMALL Hamming distance between
|
|
40
|
+
* fingerprints — this is the O(1)-per-pair coarse filter that avoids an
|
|
41
|
+
* LLM call and stays cheap even at hundreds of registered tools (fast
|
|
42
|
+
* 64-bit XOR + popcount per pair).
|
|
43
|
+
* 3. An inverted shingle-hash index (hash -> set of tool indices) is built
|
|
44
|
+
* once, in O(total shingles). For each pair flagged by the SimHash
|
|
45
|
+
* filter (or found in the index) the SAME index is used to compute the
|
|
46
|
+
* actual overlapping shingle text — this is what makes the finding
|
|
47
|
+
* reportable (the SimHash score alone can't tell an operator *what*
|
|
48
|
+
* matched).
|
|
49
|
+
* 4. A fragment's "population" (how many distinct tools carry it) caps
|
|
50
|
+
* false positives: shared shingles that appear in more than
|
|
51
|
+
* `maxFragmentPopulation` (default 3) tools are template language
|
|
52
|
+
* (e.g. every ruflo `memory_*` tool's boilerplate), not an attack —
|
|
53
|
+
* Shamir-split attacks concentrate a fragment in a small conspiracy of
|
|
54
|
+
* 2-3 tools. Same population-cap idea as the CLI v1, reimplemented here
|
|
55
|
+
* against the hash index instead of raw substrings.
|
|
56
|
+
*
|
|
57
|
+
* This is a heuristic detector, not a security boundary: it reports
|
|
58
|
+
* SUSPECTS. Default action is warn + log; blocking is opt-in via
|
|
59
|
+
* `CLAUDE_FLOW_MCP_COMPOSITION_BLOCK=1` (see {@link evaluateToolComposition}).
|
|
60
|
+
*
|
|
61
|
+
* @module @claude-flow/security/mcp-composition-inspector
|
|
62
|
+
*/
|
|
63
|
+
export interface McpToolDescriptor {
|
|
64
|
+
name: string;
|
|
65
|
+
description: string;
|
|
66
|
+
}
|
|
67
|
+
export interface CompositionInspectorOptions {
|
|
68
|
+
/** Words per shingle window. Default 5. */
|
|
69
|
+
shingleSize?: number;
|
|
70
|
+
/** SimHash similarity (1 - Hamming/64) at/above which a pair is a candidate. Default 0.6. */
|
|
71
|
+
simhashThreshold?: number;
|
|
72
|
+
/** Fraction of a tool's shingles shared with a peer (low-population only) at/above which a pair is flagged. Default 0.25. */
|
|
73
|
+
fragmentOverlapThreshold?: number;
|
|
74
|
+
/** Max number of distinct tools a shingle may appear in before it's treated as template language, not an attack fragment. Default 3. */
|
|
75
|
+
maxFragmentPopulation?: number;
|
|
76
|
+
/** Minimum character length for a shingle to be indexed (filters trivial/common short phrases). Default 12. */
|
|
77
|
+
minShingleChars?: number;
|
|
78
|
+
/** Max sample shared fragments recorded per finding (display only). Default 5. */
|
|
79
|
+
maxSampleFragments?: number;
|
|
80
|
+
}
|
|
81
|
+
export interface CompositionFinding {
|
|
82
|
+
toolA: string;
|
|
83
|
+
toolB: string;
|
|
84
|
+
/** 1 - (Hamming distance / 64) between the two tools' SimHash fingerprints. */
|
|
85
|
+
simhashSimilarity: number;
|
|
86
|
+
/** sharedLowPopulationShingles / min(shingleCount(A), shingleCount(B)). */
|
|
87
|
+
fragmentOverlapScore: number;
|
|
88
|
+
/** Sample of the actual shared shingle text driving the finding (truncated). */
|
|
89
|
+
sharedFragments: string[];
|
|
90
|
+
/** Max population (distinct tools) observed among the shared shingles that triggered this finding. */
|
|
91
|
+
fragmentPopulation: number;
|
|
92
|
+
reason: string;
|
|
93
|
+
}
|
|
94
|
+
export interface CompositionInspectionStats {
|
|
95
|
+
toolsScanned: number;
|
|
96
|
+
pairsCompared: number;
|
|
97
|
+
shinglesIndexed: number;
|
|
98
|
+
/** Pairs whose SimHash similarity alone crossed simhashThreshold (diagnostic — includes pairs later excluded for having no low-population shared shingle). */
|
|
99
|
+
candidatePairsFromSimhash: number;
|
|
100
|
+
}
|
|
101
|
+
export interface CompositionInspectionResult {
|
|
102
|
+
findings: CompositionFinding[];
|
|
103
|
+
stats: CompositionInspectionStats;
|
|
104
|
+
}
|
|
105
|
+
export interface CompositionGuardResult {
|
|
106
|
+
result: CompositionInspectionResult;
|
|
107
|
+
action: 'none' | 'warn' | 'block';
|
|
108
|
+
blocked: boolean;
|
|
109
|
+
message?: string;
|
|
110
|
+
}
|
|
111
|
+
/** FNV-1a, 64-bit. Deterministic, dependency-free, good avalanche for short strings. */
|
|
112
|
+
export declare function fnv1a64(input: string): bigint;
|
|
113
|
+
/**
|
|
114
|
+
* Classic SimHash: bit-vote a 64-bit fingerprint across a list of token
|
|
115
|
+
* hashes. Near-duplicate token sets (even with some fragments differing)
|
|
116
|
+
* produce fingerprints with a small Hamming distance.
|
|
117
|
+
*/
|
|
118
|
+
export declare function simhash64(shingles: readonly string[]): bigint;
|
|
119
|
+
/** Hamming distance between two 64-bit fingerprints (0..64). */
|
|
120
|
+
export declare function hammingDistance64(a: bigint, b: bigint): number;
|
|
121
|
+
export declare function inspectToolComposition(tools: readonly McpToolDescriptor[], options?: CompositionInspectorOptions): CompositionInspectionResult;
|
|
122
|
+
/** Reads `CLAUDE_FLOW_MCP_COMPOSITION_BLOCK` fresh on every call. '1' or 'true' (case-insensitive) enables blocking; unset/anything else keeps the default warn+log posture. */
|
|
123
|
+
export declare function isCompositionBlockEnabled(): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Runs {@link inspectToolComposition} and applies the ADR-320 default
|
|
126
|
+
* posture: warn + log (via `console.warn`) unless
|
|
127
|
+
* `CLAUDE_FLOW_MCP_COMPOSITION_BLOCK=1`, in which case the chain is marked
|
|
128
|
+
* `blocked: true` — the caller (the pre-task hook / MCP dispatcher) decides
|
|
129
|
+
* what "blocked" means operationally; this function does not throw or abort
|
|
130
|
+
* anything itself.
|
|
131
|
+
*/
|
|
132
|
+
export declare function evaluateToolComposition(tools: readonly McpToolDescriptor[], options?: CompositionInspectorOptions): CompositionGuardResult;
|
|
133
|
+
//# sourceMappingURL=mcp-composition-inspector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-composition-inspector.d.ts","sourceRoot":"","sources":["../src/mcp-composition-inspector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAMH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6HAA6H;IAC7H,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,wIAAwI;IACxI,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,+GAA+G;IAC/G,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gFAAgF;IAChF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,sGAAsG;IACtG,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,8JAA8J;IAC9J,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,KAAK,EAAE,0BAA0B,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,2BAA2B,CAAC;IACpC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAUD,wFAAwF;AACxF,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO7C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAe7D;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ9D;AAkCD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,OAAO,GAAE,2BAAgC,GACxC,2BAA2B,CAyF7B;AAQD,gLAAgL;AAChL,wBAAgB,yBAAyB,IAAI,OAAO,CAGnD;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,OAAO,GAAE,2BAAgC,GACxC,sBAAsB,CAwBxB"}
|