@sanctuary-framework/mcp-server 0.5.13 → 0.5.15
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/cli.cjs +8697 -5500
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +8695 -5498
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +8441 -5264
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +549 -6
- package/dist/index.d.ts +549 -6
- package/dist/index.js +8435 -5263
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
3
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
4
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
2
5
|
|
|
3
6
|
interface SanctuaryConfig {
|
|
4
7
|
version: string;
|
|
@@ -1488,11 +1491,15 @@ declare const MODEL_PRESETS: {
|
|
|
1488
1491
|
* Scans tool arguments for role override, security bypass, encoding evasion,
|
|
1489
1492
|
* data exfiltration, and prompt stuffing signals.
|
|
1490
1493
|
*
|
|
1494
|
+
* SEC-034/SEC-035: Enhanced with Unicode sanitization pre-pass, decoded content
|
|
1495
|
+
* re-scanning, token budget analysis, and outbound content scanning.
|
|
1496
|
+
*
|
|
1491
1497
|
* Security invariants:
|
|
1492
1498
|
* - Always returns a result, never throws
|
|
1493
1499
|
* - Typical scan completes in < 5ms
|
|
1494
1500
|
* - False positives minimized via field-aware scanning
|
|
1495
1501
|
* - Recursive scanning of nested objects/arrays
|
|
1502
|
+
* - Outbound scanning catches secret leaks and injection artifact survival
|
|
1496
1503
|
*/
|
|
1497
1504
|
interface InjectionDetectorConfig {
|
|
1498
1505
|
enabled: boolean;
|
|
@@ -1523,6 +1530,14 @@ declare class InjectionDetector {
|
|
|
1523
1530
|
* @returns DetectionResult with all detected signals
|
|
1524
1531
|
*/
|
|
1525
1532
|
scan(toolName: string, args: Record<string, unknown>): DetectionResult;
|
|
1533
|
+
/**
|
|
1534
|
+
* SEC-035: Scan outbound content for secret leaks, data exfiltration,
|
|
1535
|
+
* internal path exposure, and injection artifact survival.
|
|
1536
|
+
*
|
|
1537
|
+
* @param content The outbound content string to scan
|
|
1538
|
+
* @returns DetectionResult with outbound-specific signal types
|
|
1539
|
+
*/
|
|
1540
|
+
scanOutbound(content: string): DetectionResult;
|
|
1526
1541
|
/**
|
|
1527
1542
|
* Recursively scan a value and all nested values.
|
|
1528
1543
|
*/
|
|
@@ -1532,7 +1547,82 @@ declare class InjectionDetector {
|
|
|
1532
1547
|
*/
|
|
1533
1548
|
private scanString;
|
|
1534
1549
|
/**
|
|
1535
|
-
*
|
|
1550
|
+
* Count invisible Unicode characters in a string.
|
|
1551
|
+
* Includes zero-width chars, soft hyphens, directional marks,
|
|
1552
|
+
* variation selectors, and other invisible categories.
|
|
1553
|
+
*/
|
|
1554
|
+
private countInvisibleChars;
|
|
1555
|
+
/**
|
|
1556
|
+
* Strip invisible characters from a string for clean pattern matching.
|
|
1557
|
+
* Returns a new string with all invisible chars removed.
|
|
1558
|
+
*/
|
|
1559
|
+
private stripInvisibleChars;
|
|
1560
|
+
/**
|
|
1561
|
+
* SEC-034: Token budget attack detection.
|
|
1562
|
+
* Some Unicode sequences expand dramatically during tokenization (e.g., CJK
|
|
1563
|
+
* ideographs, combining characters, emoji sequences). If the estimated token
|
|
1564
|
+
* cost per character is anomalously high, this may be a wallet-drain payload.
|
|
1565
|
+
*
|
|
1566
|
+
* Heuristic: count chars that typically tokenize into multiple tokens.
|
|
1567
|
+
* If the ratio of estimated tokens to char count exceeds 3x, flag it.
|
|
1568
|
+
*/
|
|
1569
|
+
private detectTokenBudgetAttack;
|
|
1570
|
+
/**
|
|
1571
|
+
* Detect encoded content (base64, hex, HTML entities, URL encoding),
|
|
1572
|
+
* decode it, and re-scan the decoded content through injection patterns.
|
|
1573
|
+
* If the decoded content contains injection patterns, flag as encoding_evasion.
|
|
1574
|
+
*/
|
|
1575
|
+
private detectEncodedPayloads;
|
|
1576
|
+
/**
|
|
1577
|
+
* Check if a string contains any injection patterns (role override or security bypass).
|
|
1578
|
+
*/
|
|
1579
|
+
private containsInjectionPatterns;
|
|
1580
|
+
/**
|
|
1581
|
+
* Safely decode a base64 string. Returns null if it's not valid base64
|
|
1582
|
+
* or doesn't decode to a meaningful string.
|
|
1583
|
+
*/
|
|
1584
|
+
private safeBase64Decode;
|
|
1585
|
+
/**
|
|
1586
|
+
* Safely decode a hex string. Returns null on failure.
|
|
1587
|
+
*/
|
|
1588
|
+
private safeHexDecode;
|
|
1589
|
+
/**
|
|
1590
|
+
* Decode HTML numeric entities (&#xHH; and &#DDD;) in a string.
|
|
1591
|
+
*/
|
|
1592
|
+
private decodeHtmlEntities;
|
|
1593
|
+
/**
|
|
1594
|
+
* Safely decode a URL-encoded string. Returns null on failure.
|
|
1595
|
+
*/
|
|
1596
|
+
private safeUrlDecode;
|
|
1597
|
+
/**
|
|
1598
|
+
* Heuristic: does this look like readable text (vs. binary garbage)?
|
|
1599
|
+
* Checks that most characters are printable ASCII or common Unicode.
|
|
1600
|
+
*/
|
|
1601
|
+
private looksLikeText;
|
|
1602
|
+
/**
|
|
1603
|
+
* Detect API keys and secrets in outbound content.
|
|
1604
|
+
*/
|
|
1605
|
+
private detectSecretPatterns;
|
|
1606
|
+
/**
|
|
1607
|
+
* Detect data exfiltration via markdown images with data-carrying query params.
|
|
1608
|
+
*/
|
|
1609
|
+
private detectOutboundExfiltration;
|
|
1610
|
+
/**
|
|
1611
|
+
* Detect internal filesystem path leaks in outbound content.
|
|
1612
|
+
*/
|
|
1613
|
+
private detectInternalPathLeaks;
|
|
1614
|
+
/**
|
|
1615
|
+
* Detect private IP addresses and localhost references in outbound content.
|
|
1616
|
+
*/
|
|
1617
|
+
private detectPrivateNetworkLeaks;
|
|
1618
|
+
/**
|
|
1619
|
+
* Detect role markers / prompt template artifacts in outbound content.
|
|
1620
|
+
* These should never appear in agent output — their presence indicates
|
|
1621
|
+
* injection artifact survival.
|
|
1622
|
+
*/
|
|
1623
|
+
private detectOutputRoleMarkers;
|
|
1624
|
+
/**
|
|
1625
|
+
* Detect base64 strings, base64url, and zero-width character evasion.
|
|
1536
1626
|
*/
|
|
1537
1627
|
private detectEncodingEvasion;
|
|
1538
1628
|
/**
|
|
@@ -1564,10 +1654,13 @@ declare class InjectionDetector {
|
|
|
1564
1654
|
*/
|
|
1565
1655
|
private isStructuredField;
|
|
1566
1656
|
/**
|
|
1567
|
-
* SEC-032: Map common cross-script confusable characters to their
|
|
1568
|
-
* NFKC normalization handles fullwidth and compatibility
|
|
1569
|
-
* Cyrillic/Greek lookalikes to
|
|
1570
|
-
*
|
|
1657
|
+
* SEC-032/SEC-034: Map common cross-script confusable characters to their
|
|
1658
|
+
* Latin equivalents. NFKC normalization handles fullwidth and compatibility
|
|
1659
|
+
* forms, but does NOT map Cyrillic/Greek/Armenian/Georgian lookalikes to
|
|
1660
|
+
* Latin (they're distinct codepoints by design).
|
|
1661
|
+
*
|
|
1662
|
+
* Extended to 50+ confusable pairs covering Cyrillic, Greek, Armenian,
|
|
1663
|
+
* Georgian, Cherokee, and mathematical/symbol lookalikes.
|
|
1571
1664
|
*/
|
|
1572
1665
|
private normalizeConfusables;
|
|
1573
1666
|
/**
|
|
@@ -1833,6 +1926,8 @@ type InjectionAlertCallback = (alert: {
|
|
|
1833
1926
|
result: DetectionResult;
|
|
1834
1927
|
timestamp: string;
|
|
1835
1928
|
}) => void;
|
|
1929
|
+
/** Resolver for proxy tool tiers — provided by the ProxyRouter */
|
|
1930
|
+
type ProxyTierResolver = (toolName: string) => (1 | 2 | 3) | null;
|
|
1836
1931
|
declare class ApprovalGate {
|
|
1837
1932
|
private policy;
|
|
1838
1933
|
private baseline;
|
|
@@ -1840,7 +1935,12 @@ declare class ApprovalGate {
|
|
|
1840
1935
|
private auditLog;
|
|
1841
1936
|
private injectionDetector;
|
|
1842
1937
|
private onInjectionAlert?;
|
|
1938
|
+
private proxyTierResolver?;
|
|
1843
1939
|
constructor(policy: PrincipalPolicy, baseline: BaselineTracker, channel: ApprovalChannel, auditLog: AuditLog, injectionDetector?: InjectionDetector, onInjectionAlert?: InjectionAlertCallback);
|
|
1940
|
+
/**
|
|
1941
|
+
* Set the proxy tier resolver. Called after the proxy router is initialized.
|
|
1942
|
+
*/
|
|
1943
|
+
setProxyTierResolver(resolver: ProxyTierResolver): void;
|
|
1844
1944
|
/**
|
|
1845
1945
|
* Evaluate a tool call against the Principal Policy.
|
|
1846
1946
|
*
|
|
@@ -1886,6 +1986,13 @@ type ToolHandler = (args: Record<string, unknown>) => Promise<{
|
|
|
1886
1986
|
text: string;
|
|
1887
1987
|
}>;
|
|
1888
1988
|
}>;
|
|
1989
|
+
/** Tool definition for registration */
|
|
1990
|
+
interface ToolDefinition {
|
|
1991
|
+
name: string;
|
|
1992
|
+
description: string;
|
|
1993
|
+
inputSchema: Record<string, unknown>;
|
|
1994
|
+
handler: ToolHandler;
|
|
1995
|
+
}
|
|
1889
1996
|
|
|
1890
1997
|
/**
|
|
1891
1998
|
* Sanctuary MCP Server — L2 Context Gating: Automatic Enforcer
|
|
@@ -2004,6 +2111,426 @@ declare class ContextGateEnforcer {
|
|
|
2004
2111
|
resetStats(): void;
|
|
2005
2112
|
}
|
|
2006
2113
|
|
|
2114
|
+
/**
|
|
2115
|
+
* Sanctuary MCP Server — Sovereignty Profile
|
|
2116
|
+
*
|
|
2117
|
+
* Encrypted store for the sovereignty profile configuration.
|
|
2118
|
+
* Controls which Sanctuary features are active and how they behave.
|
|
2119
|
+
*
|
|
2120
|
+
* The profile is stored encrypted in a reserved namespace (_sovereignty_profile)
|
|
2121
|
+
* using AES-256-GCM with HKDF domain separation, following the same pattern
|
|
2122
|
+
* as ContextGatePolicyStore.
|
|
2123
|
+
*
|
|
2124
|
+
* Security invariants:
|
|
2125
|
+
* - Profile is stored in a reserved namespace (underscore-prefixed)
|
|
2126
|
+
* - L1 state tools cannot read or write reserved namespaces
|
|
2127
|
+
* - Profile changes only come through dedicated profile tools (Tier 1)
|
|
2128
|
+
* or the dashboard
|
|
2129
|
+
* - All changes are audit-logged
|
|
2130
|
+
*/
|
|
2131
|
+
|
|
2132
|
+
interface UpstreamServer {
|
|
2133
|
+
name: string;
|
|
2134
|
+
transport: {
|
|
2135
|
+
type: "stdio" | "sse";
|
|
2136
|
+
command?: string;
|
|
2137
|
+
args?: string[];
|
|
2138
|
+
url?: string;
|
|
2139
|
+
env?: Record<string, string>;
|
|
2140
|
+
};
|
|
2141
|
+
enabled: boolean;
|
|
2142
|
+
default_tier: 1 | 2 | 3;
|
|
2143
|
+
tool_overrides?: Record<string, {
|
|
2144
|
+
tier: 1 | 2 | 3;
|
|
2145
|
+
}>;
|
|
2146
|
+
}
|
|
2147
|
+
interface SovereigntyProfile {
|
|
2148
|
+
version: 1;
|
|
2149
|
+
features: {
|
|
2150
|
+
audit_logging: {
|
|
2151
|
+
enabled: boolean;
|
|
2152
|
+
};
|
|
2153
|
+
injection_detection: {
|
|
2154
|
+
enabled: boolean;
|
|
2155
|
+
sensitivity?: "low" | "medium" | "high";
|
|
2156
|
+
};
|
|
2157
|
+
context_gating: {
|
|
2158
|
+
enabled: boolean;
|
|
2159
|
+
policy_id?: string;
|
|
2160
|
+
};
|
|
2161
|
+
approval_gate: {
|
|
2162
|
+
enabled: true;
|
|
2163
|
+
};
|
|
2164
|
+
zk_proofs: {
|
|
2165
|
+
enabled: boolean;
|
|
2166
|
+
};
|
|
2167
|
+
};
|
|
2168
|
+
upstream_servers?: UpstreamServer[];
|
|
2169
|
+
updated_at: string;
|
|
2170
|
+
}
|
|
2171
|
+
/** Partial feature update — all fields optional */
|
|
2172
|
+
interface SovereigntyProfileUpdate {
|
|
2173
|
+
audit_logging?: {
|
|
2174
|
+
enabled?: boolean;
|
|
2175
|
+
};
|
|
2176
|
+
injection_detection?: {
|
|
2177
|
+
enabled?: boolean;
|
|
2178
|
+
sensitivity?: "low" | "medium" | "high";
|
|
2179
|
+
};
|
|
2180
|
+
context_gating?: {
|
|
2181
|
+
enabled?: boolean;
|
|
2182
|
+
policy_id?: string;
|
|
2183
|
+
};
|
|
2184
|
+
approval_gate?: {
|
|
2185
|
+
enabled?: true;
|
|
2186
|
+
};
|
|
2187
|
+
zk_proofs?: {
|
|
2188
|
+
enabled?: boolean;
|
|
2189
|
+
};
|
|
2190
|
+
upstream_servers?: UpstreamServer[];
|
|
2191
|
+
}
|
|
2192
|
+
declare function createDefaultProfile(): SovereigntyProfile;
|
|
2193
|
+
/**
|
|
2194
|
+
* Sovereignty profile store — encrypted under L1 sovereignty.
|
|
2195
|
+
*
|
|
2196
|
+
* Stores the active sovereignty profile in a reserved namespace.
|
|
2197
|
+
* On first load, creates the default profile automatically.
|
|
2198
|
+
*/
|
|
2199
|
+
declare class SovereigntyProfileStore {
|
|
2200
|
+
private storage;
|
|
2201
|
+
private encryptionKey;
|
|
2202
|
+
private profile;
|
|
2203
|
+
constructor(storage: StorageBackend, masterKey: Uint8Array);
|
|
2204
|
+
/**
|
|
2205
|
+
* Load the active sovereignty profile from encrypted storage.
|
|
2206
|
+
* Creates the default profile on first run.
|
|
2207
|
+
*/
|
|
2208
|
+
load(): Promise<SovereigntyProfile>;
|
|
2209
|
+
/**
|
|
2210
|
+
* Get the current profile. Must call load() first.
|
|
2211
|
+
*/
|
|
2212
|
+
get(): SovereigntyProfile;
|
|
2213
|
+
/**
|
|
2214
|
+
* Apply a partial update to the profile.
|
|
2215
|
+
* Returns the updated profile.
|
|
2216
|
+
*/
|
|
2217
|
+
update(updates: SovereigntyProfileUpdate): Promise<SovereigntyProfile>;
|
|
2218
|
+
/**
|
|
2219
|
+
* Persist the current profile to encrypted storage.
|
|
2220
|
+
*/
|
|
2221
|
+
private persist;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
/**
|
|
2225
|
+
* Sanctuary MCP Server — Proxy Client Manager
|
|
2226
|
+
*
|
|
2227
|
+
* Manages MCP client connections to upstream servers. Handles connection
|
|
2228
|
+
* lifecycle, reconnection with exponential backoff, and tool discovery.
|
|
2229
|
+
*
|
|
2230
|
+
* Security invariants:
|
|
2231
|
+
* - Upstream servers are configured via the sovereignty profile (Tier 1 gated)
|
|
2232
|
+
* - Connection failures do not block Sanctuary startup
|
|
2233
|
+
* - Tool discovery is re-run on every successful reconnection
|
|
2234
|
+
* - Environment variables for upstream transports are passed through, not stored in logs
|
|
2235
|
+
*/
|
|
2236
|
+
|
|
2237
|
+
type ConnectionState = "disconnected" | "connecting" | "connected" | "error";
|
|
2238
|
+
interface UpstreamTool {
|
|
2239
|
+
name: string;
|
|
2240
|
+
description: string;
|
|
2241
|
+
inputSchema: Record<string, unknown>;
|
|
2242
|
+
}
|
|
2243
|
+
interface UpstreamConnection {
|
|
2244
|
+
server: UpstreamServer;
|
|
2245
|
+
client: Client | null;
|
|
2246
|
+
transport: StdioClientTransport | SSEClientTransport | null;
|
|
2247
|
+
state: ConnectionState;
|
|
2248
|
+
tools: UpstreamTool[];
|
|
2249
|
+
error?: string;
|
|
2250
|
+
retryCount: number;
|
|
2251
|
+
retryTimer?: ReturnType<typeof setTimeout>;
|
|
2252
|
+
}
|
|
2253
|
+
/** Callback for state changes */
|
|
2254
|
+
type ConnectionStateCallback = (serverName: string, state: ConnectionState, toolCount: number, error?: string) => void;
|
|
2255
|
+
declare class ClientManager {
|
|
2256
|
+
private connections;
|
|
2257
|
+
private onStateChange?;
|
|
2258
|
+
private shutdownRequested;
|
|
2259
|
+
constructor(options?: {
|
|
2260
|
+
onStateChange?: ConnectionStateCallback;
|
|
2261
|
+
});
|
|
2262
|
+
/**
|
|
2263
|
+
* Configure upstream servers. Disconnects removed servers, connects new ones.
|
|
2264
|
+
* Non-blocking — connection failures are handled asynchronously.
|
|
2265
|
+
*/
|
|
2266
|
+
configure(servers: UpstreamServer[]): Promise<void>;
|
|
2267
|
+
/**
|
|
2268
|
+
* Get all discovered tools across all connected upstream servers.
|
|
2269
|
+
*/
|
|
2270
|
+
getAllTools(): Map<string, UpstreamTool[]>;
|
|
2271
|
+
/**
|
|
2272
|
+
* Get connection status for all configured servers.
|
|
2273
|
+
*/
|
|
2274
|
+
getStatus(): Array<{
|
|
2275
|
+
name: string;
|
|
2276
|
+
state: ConnectionState;
|
|
2277
|
+
transport_type: string;
|
|
2278
|
+
tool_count: number;
|
|
2279
|
+
error?: string;
|
|
2280
|
+
}>;
|
|
2281
|
+
/**
|
|
2282
|
+
* Get the upstream server config by name.
|
|
2283
|
+
*/
|
|
2284
|
+
getServerConfig(name: string): UpstreamServer | undefined;
|
|
2285
|
+
/**
|
|
2286
|
+
* Call a tool on an upstream server.
|
|
2287
|
+
*/
|
|
2288
|
+
callTool(serverName: string, toolName: string, args: Record<string, unknown>): Promise<{
|
|
2289
|
+
content: Array<{
|
|
2290
|
+
type: string;
|
|
2291
|
+
text?: string;
|
|
2292
|
+
[key: string]: unknown;
|
|
2293
|
+
}>;
|
|
2294
|
+
}>;
|
|
2295
|
+
/**
|
|
2296
|
+
* Shut down all connections cleanly.
|
|
2297
|
+
*/
|
|
2298
|
+
shutdown(): Promise<void>;
|
|
2299
|
+
/**
|
|
2300
|
+
* Connect to an upstream server (non-blocking).
|
|
2301
|
+
* Spawns connection attempt in background — does not throw.
|
|
2302
|
+
*/
|
|
2303
|
+
private connectServer;
|
|
2304
|
+
/**
|
|
2305
|
+
* Perform the actual connection to an upstream server.
|
|
2306
|
+
*/
|
|
2307
|
+
private doConnect;
|
|
2308
|
+
/**
|
|
2309
|
+
* Discover tools from a connected upstream server.
|
|
2310
|
+
*/
|
|
2311
|
+
private discoverTools;
|
|
2312
|
+
/**
|
|
2313
|
+
* Schedule a reconnection attempt with exponential backoff.
|
|
2314
|
+
*/
|
|
2315
|
+
private scheduleRetry;
|
|
2316
|
+
/**
|
|
2317
|
+
* Disconnect a specific upstream server.
|
|
2318
|
+
*/
|
|
2319
|
+
private disconnectServer;
|
|
2320
|
+
/**
|
|
2321
|
+
* Notify listener of state change.
|
|
2322
|
+
*/
|
|
2323
|
+
private notifyStateChange;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
/**
|
|
2327
|
+
* Sanctuary MCP Server — L2 Operational Isolation: Call Governor
|
|
2328
|
+
*
|
|
2329
|
+
* Runtime governance for proxied tool calls. Wraps the proxy forwarding
|
|
2330
|
+
* path with four enforcement mechanisms:
|
|
2331
|
+
*
|
|
2332
|
+
* 1. Volume limit — sliding-window cap on total tool calls
|
|
2333
|
+
* 2. Rate detection — per-tool call frequency check (loop detection)
|
|
2334
|
+
* 3. Duplicate detection — SHA-256 hash of tool+args, cache recent results
|
|
2335
|
+
* 4. Lifetime counter — hard stop after N total calls per session
|
|
2336
|
+
*
|
|
2337
|
+
* All state is in-memory. Resets on server restart.
|
|
2338
|
+
*
|
|
2339
|
+
* Security invariants:
|
|
2340
|
+
* - Governor cannot be bypassed — it sits in the enforcement chain
|
|
2341
|
+
* - Lifetime limit is a hard stop (requires reset or restart)
|
|
2342
|
+
* - Rate escalation triggers Tier 2 human approval
|
|
2343
|
+
* - Duplicate cache uses cryptographic hashing (SHA-256)
|
|
2344
|
+
*/
|
|
2345
|
+
interface GovernorConfig {
|
|
2346
|
+
/** Total calls allowed in the sliding volume window (default: 200) */
|
|
2347
|
+
volume_limit: number;
|
|
2348
|
+
/** Volume window size in milliseconds (default: 600000 = 10 min) */
|
|
2349
|
+
volume_window_ms: number;
|
|
2350
|
+
/** Per-tool calls allowed in the rate window before escalation (default: 20) */
|
|
2351
|
+
rate_limit: number;
|
|
2352
|
+
/** Rate window size in milliseconds (default: 60000 = 1 min) */
|
|
2353
|
+
rate_window_ms: number;
|
|
2354
|
+
/** Duplicate cache TTL in milliseconds (default: 60000 = 1 min) */
|
|
2355
|
+
duplicate_ttl_ms: number;
|
|
2356
|
+
/** Total calls before hard stop for the session (default: 1000) */
|
|
2357
|
+
lifetime_limit: number;
|
|
2358
|
+
/** Per-server config overrides keyed by server name */
|
|
2359
|
+
per_server_overrides?: Record<string, Partial<GovernorConfig>>;
|
|
2360
|
+
}
|
|
2361
|
+
interface GovernorCheckResult {
|
|
2362
|
+
/** Whether the call is allowed to proceed */
|
|
2363
|
+
allowed: boolean;
|
|
2364
|
+
/** Reason the call was blocked or flagged */
|
|
2365
|
+
reason?: "volume_exceeded" | "rate_exceeded" | "lifetime_exceeded" | "duplicate_cached";
|
|
2366
|
+
/** If duplicate, the cached response */
|
|
2367
|
+
cached_result?: unknown;
|
|
2368
|
+
/** If true, escalate to Tier 2 (human approval required) */
|
|
2369
|
+
escalate?: boolean;
|
|
2370
|
+
}
|
|
2371
|
+
interface GovernorStatus {
|
|
2372
|
+
/** Current call count in the volume window */
|
|
2373
|
+
volume_current: number;
|
|
2374
|
+
/** Volume limit from config */
|
|
2375
|
+
volume_limit: number;
|
|
2376
|
+
/** Total calls this session */
|
|
2377
|
+
lifetime_current: number;
|
|
2378
|
+
/** Lifetime limit from config */
|
|
2379
|
+
lifetime_limit: number;
|
|
2380
|
+
/** Per-tool call count in the current rate window */
|
|
2381
|
+
rate_by_tool: Record<string, number>;
|
|
2382
|
+
/** Number of entries in the duplicate cache */
|
|
2383
|
+
duplicate_cache_size: number;
|
|
2384
|
+
/** Whether the governor has been hard-stopped */
|
|
2385
|
+
hard_stopped: boolean;
|
|
2386
|
+
}
|
|
2387
|
+
declare class CallGovernor {
|
|
2388
|
+
private config;
|
|
2389
|
+
/** Sliding window of all call timestamps for volume tracking */
|
|
2390
|
+
private volumeWindow;
|
|
2391
|
+
/** Per-tool sliding window of call timestamps for rate tracking */
|
|
2392
|
+
private rateWindows;
|
|
2393
|
+
/** Duplicate cache: SHA-256(server+tool+args) -> cached result + expiry */
|
|
2394
|
+
private duplicateCache;
|
|
2395
|
+
/** Total calls this session */
|
|
2396
|
+
private lifetimeCount;
|
|
2397
|
+
/** Hard stop flag — set when lifetime limit is reached */
|
|
2398
|
+
private hardStopped;
|
|
2399
|
+
constructor(config?: Partial<GovernorConfig>);
|
|
2400
|
+
/**
|
|
2401
|
+
* Check if a call is allowed and apply governance.
|
|
2402
|
+
*
|
|
2403
|
+
* Evaluation order:
|
|
2404
|
+
* 1. Lifetime limit (hard stop — not recoverable without reset)
|
|
2405
|
+
* 2. Volume limit (sliding window)
|
|
2406
|
+
* 3. Rate limit per tool (escalates to Tier 2)
|
|
2407
|
+
* 4. Duplicate detection (returns cached result)
|
|
2408
|
+
*/
|
|
2409
|
+
check(serverName: string, toolName: string, args: Record<string, unknown>): GovernorCheckResult;
|
|
2410
|
+
/**
|
|
2411
|
+
* Record a successful call result for duplicate caching.
|
|
2412
|
+
*/
|
|
2413
|
+
recordResult(serverName: string, toolName: string, args: Record<string, unknown>, result: unknown): void;
|
|
2414
|
+
/**
|
|
2415
|
+
* Get current governor status for dashboard display.
|
|
2416
|
+
*/
|
|
2417
|
+
getStatus(): GovernorStatus;
|
|
2418
|
+
/**
|
|
2419
|
+
* Reset all counters (Tier 1 — requires approval).
|
|
2420
|
+
* Clears volume window, rate windows, duplicate cache,
|
|
2421
|
+
* lifetime counter, and hard stop flag.
|
|
2422
|
+
*/
|
|
2423
|
+
reset(): void;
|
|
2424
|
+
/**
|
|
2425
|
+
* Get the effective config for a given server, merging per-server overrides.
|
|
2426
|
+
*/
|
|
2427
|
+
private getEffectiveConfig;
|
|
2428
|
+
/**
|
|
2429
|
+
* Compute a SHA-256 hash of server + tool + canonical args.
|
|
2430
|
+
* Used for duplicate detection.
|
|
2431
|
+
*/
|
|
2432
|
+
private computeCallHash;
|
|
2433
|
+
/**
|
|
2434
|
+
* Deterministic JSON serialization with sorted keys.
|
|
2435
|
+
*/
|
|
2436
|
+
private stableStringify;
|
|
2437
|
+
/**
|
|
2438
|
+
* Prune volume window entries older than the window size.
|
|
2439
|
+
* Uses shift() from the front — timestamps are appended in order.
|
|
2440
|
+
*/
|
|
2441
|
+
private pruneVolumeWindow;
|
|
2442
|
+
/**
|
|
2443
|
+
* Prune a per-tool rate window.
|
|
2444
|
+
*/
|
|
2445
|
+
private pruneRateWindow;
|
|
2446
|
+
/**
|
|
2447
|
+
* Prune expired entries from the duplicate cache.
|
|
2448
|
+
* Amortized O(1) — only prunes when cache exceeds a size threshold.
|
|
2449
|
+
*/
|
|
2450
|
+
private pruneDuplicateCache;
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
/**
|
|
2454
|
+
* Sanctuary MCP Server — Proxy Router
|
|
2455
|
+
*
|
|
2456
|
+
* Routes proxied tool calls through the full Sanctuary enforcement chain:
|
|
2457
|
+
* injection detection, approval gate evaluation, context gating, and audit logging.
|
|
2458
|
+
*
|
|
2459
|
+
* Upstream tools are registered under the namespace `proxy/{server_name}/{tool_name}`.
|
|
2460
|
+
* This ensures no collision with native `sanctuary/*` tools and makes the provenance
|
|
2461
|
+
* of every tool call explicit.
|
|
2462
|
+
*
|
|
2463
|
+
* Security invariants:
|
|
2464
|
+
* - Every proxied call passes through injection scan + gate + audit (no bypass path)
|
|
2465
|
+
* - Denied calls return a generic denial message (same as native Sanctuary denials)
|
|
2466
|
+
* - Upstream errors are passed through to the agent unmodified
|
|
2467
|
+
* - Native sanctuary/* tools are never affected by the proxy layer
|
|
2468
|
+
*/
|
|
2469
|
+
|
|
2470
|
+
interface ProxyRouterOptions {
|
|
2471
|
+
/** Optional callback when the context gate should filter arguments */
|
|
2472
|
+
contextGateFilter?: (toolName: string, args: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
2473
|
+
/** Optional call governor for runtime governance */
|
|
2474
|
+
governor?: CallGovernor;
|
|
2475
|
+
}
|
|
2476
|
+
declare class ProxyRouter {
|
|
2477
|
+
private clientManager;
|
|
2478
|
+
private injectionDetector;
|
|
2479
|
+
private auditLog;
|
|
2480
|
+
private options;
|
|
2481
|
+
constructor(clientManager: ClientManager, injectionDetector: InjectionDetector, auditLog: AuditLog, options?: ProxyRouterOptions);
|
|
2482
|
+
/**
|
|
2483
|
+
* Convert all discovered upstream tools to Sanctuary ToolDefinitions.
|
|
2484
|
+
* Each tool is registered as `proxy/{server_name}/{tool_name}`.
|
|
2485
|
+
*/
|
|
2486
|
+
getProxiedTools(): ToolDefinition[];
|
|
2487
|
+
/**
|
|
2488
|
+
* Determine the tier for a proxied tool call.
|
|
2489
|
+
* Checks tool_overrides first, then falls back to default_tier.
|
|
2490
|
+
*/
|
|
2491
|
+
getTierForTool(serverName: string, toolName: string): 1 | 2 | 3;
|
|
2492
|
+
/**
|
|
2493
|
+
* Parse a proxy tool name into server name and tool name.
|
|
2494
|
+
* Returns null if the name doesn't match the proxy namespace.
|
|
2495
|
+
*/
|
|
2496
|
+
static parseProxyToolName(fullName: string): {
|
|
2497
|
+
serverName: string;
|
|
2498
|
+
toolName: string;
|
|
2499
|
+
} | null;
|
|
2500
|
+
/**
|
|
2501
|
+
* Create a handler for a specific proxied tool.
|
|
2502
|
+
* The handler runs the full enforcement chain before forwarding.
|
|
2503
|
+
*/
|
|
2504
|
+
private createHandler;
|
|
2505
|
+
/**
|
|
2506
|
+
* Call an upstream tool with a timeout.
|
|
2507
|
+
*/
|
|
2508
|
+
private callWithTimeout;
|
|
2509
|
+
/**
|
|
2510
|
+
* Normalize an upstream response to the standard Sanctuary response format.
|
|
2511
|
+
*/
|
|
2512
|
+
private normalizeResponse;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
/**
|
|
2516
|
+
* Sanctuary MCP Server — System Prompt Generator
|
|
2517
|
+
*
|
|
2518
|
+
* Pure function that takes a SovereigntyProfile and generates a system
|
|
2519
|
+
* prompt snippet instructing the agent on which Sanctuary features are
|
|
2520
|
+
* active and how to use them.
|
|
2521
|
+
*
|
|
2522
|
+
* The prompt is generic (not harness-specific) and intended to be pasted
|
|
2523
|
+
* into any agent's system configuration.
|
|
2524
|
+
*/
|
|
2525
|
+
|
|
2526
|
+
/**
|
|
2527
|
+
* Generate a system prompt snippet from the active sovereignty profile.
|
|
2528
|
+
*
|
|
2529
|
+
* The output is a copy-pasteable text block that instructs the agent on
|
|
2530
|
+
* which Sanctuary features are active and how to interact with them.
|
|
2531
|
+
*/
|
|
2532
|
+
declare function generateSystemPrompt(profile: SovereigntyProfile): string;
|
|
2533
|
+
|
|
2007
2534
|
/**
|
|
2008
2535
|
* Sanctuary MCP Server — In-Memory Storage Backend
|
|
2009
2536
|
*
|
|
@@ -2171,6 +2698,8 @@ declare class DashboardApprovalChannel implements ApprovalChannel {
|
|
|
2171
2698
|
private handshakeResults;
|
|
2172
2699
|
private shrOpts;
|
|
2173
2700
|
private _sanctuaryConfig;
|
|
2701
|
+
private profileStore;
|
|
2702
|
+
private clientManager;
|
|
2174
2703
|
private dashboardHTML;
|
|
2175
2704
|
private loginHTML;
|
|
2176
2705
|
private authToken;
|
|
@@ -2197,6 +2726,8 @@ declare class DashboardApprovalChannel implements ApprovalChannel {
|
|
|
2197
2726
|
handshakeResults?: Map<string, HandshakeResult>;
|
|
2198
2727
|
shrOpts?: SHRGeneratorOptions;
|
|
2199
2728
|
sanctuaryConfig?: SanctuaryConfig;
|
|
2729
|
+
profileStore?: SovereigntyProfileStore;
|
|
2730
|
+
clientManager?: ClientManager;
|
|
2200
2731
|
}): void;
|
|
2201
2732
|
/**
|
|
2202
2733
|
* Mark this dashboard as running in standalone mode.
|
|
@@ -2284,6 +2815,18 @@ declare class DashboardApprovalChannel implements ApprovalChannel {
|
|
|
2284
2815
|
private handleIdentity;
|
|
2285
2816
|
private handleHandshakes;
|
|
2286
2817
|
private handleSHR;
|
|
2818
|
+
private handleSovereigntyProfileGet;
|
|
2819
|
+
private handleSovereigntyProfileUpdate;
|
|
2820
|
+
/**
|
|
2821
|
+
* GET /api/proxy/servers — list upstream proxy servers and their status.
|
|
2822
|
+
*/
|
|
2823
|
+
private handleProxyServers;
|
|
2824
|
+
/**
|
|
2825
|
+
* POST /api/proxy/servers — update upstream server configuration.
|
|
2826
|
+
* This is a dashboard action (human-initiated), so it's allowed with audit logging
|
|
2827
|
+
* rather than requiring Tier 1 approval.
|
|
2828
|
+
*/
|
|
2829
|
+
private handleProxyServersUpdate;
|
|
2287
2830
|
broadcastSSE(event: string, data: unknown): void;
|
|
2288
2831
|
/**
|
|
2289
2832
|
* Broadcast an audit entry to connected dashboards.
|
|
@@ -2794,4 +3337,4 @@ declare function createSanctuaryServer(options?: {
|
|
|
2794
3337
|
storage?: StorageBackend;
|
|
2795
3338
|
}): Promise<SanctuaryServer>;
|
|
2796
3339
|
|
|
2797
|
-
export { ATTESTATION_VERSION, ApprovalGate, type AttestationBody, type AttestationVerificationResult, AuditLog, AutoApproveChannel, BaselineTracker, type BridgeAttestationRequest, type BridgeAttestationResult, type BridgeCommitment, type BridgeVerificationResult, TEMPLATES as CONTEXT_GATE_TEMPLATES, CallbackApprovalChannel, CommitmentStore, type ConcordiaOutcome, type ContextAction, type ContextFilterResult, ContextGateEnforcer, type ContextGatePolicy, ContextGatePolicyStore, type ContextGateRule, type ContextGateTemplate, DashboardApprovalChannel, type DashboardConfig, type DetectionResult, type EnforcerConfig, type FederationCapabilities, type FederationPeer, FederationRegistry, type FieldClassification, type FieldFilterResult, FilesystemStorage, type GateResult, type HandshakeChallenge, type HandshakeCompletion, type HandshakeResponse, type HandshakeResult, InMemoryModelProvenanceStore, InjectionDetector, type InjectionDetectorConfig, type InjectionSignal, MODEL_PRESETS, MemoryStorage, type ModelProvenance, type ModelProvenanceStore, type PedersenCommitment, type PeerTrustEvaluation, type PolicyRecommendation, PolicyStore, type PrincipalPolicy, type ProviderCategory, ReputationStore, type SHRBody, type SHRGeneratorOptions, type SHRVerificationResult, type SanctuaryConfig, type SanctuaryServer, type SignedAttestation, type SignedSHR, type SovereigntyTier, StateStore, StderrApprovalChannel, TIER_WEIGHTS, type TierMetadata, type TieredAttestation, WebhookApprovalChannel, type WebhookCallbackPayload, type WebhookConfig, type WebhookPayload, type ZKProofOfKnowledge, type ZKRangeProof, canonicalize, classifyField, completeHandshake, computeWeightedScore, createBridgeCommitment, createPedersenCommitment, createProofOfKnowledge, createRangeProof, createSanctuaryServer, evaluateField, filterContext, generateAttestation, generateSHR, getTemplate, initiateHandshake, listTemplateIds, loadConfig, loadPrincipalPolicy, recommendPolicy, resolveTier, respondToHandshake, signPayload, tierDistribution, verifyAttestation, verifyBridgeCommitment, verifyCompletion, verifyPedersenCommitment, verifyProofOfKnowledge, verifyRangeProof, verifySHR, verifySignature };
|
|
3340
|
+
export { ATTESTATION_VERSION, ApprovalGate, type AttestationBody, type AttestationVerificationResult, AuditLog, AutoApproveChannel, BaselineTracker, type BridgeAttestationRequest, type BridgeAttestationResult, type BridgeCommitment, type BridgeVerificationResult, TEMPLATES as CONTEXT_GATE_TEMPLATES, CallbackApprovalChannel, ClientManager, CommitmentStore, type ConcordiaOutcome, type ConnectionState, type ContextAction, type ContextFilterResult, ContextGateEnforcer, type ContextGatePolicy, ContextGatePolicyStore, type ContextGateRule, type ContextGateTemplate, DashboardApprovalChannel, type DashboardConfig, type DetectionResult, type EnforcerConfig, type FederationCapabilities, type FederationPeer, FederationRegistry, type FieldClassification, type FieldFilterResult, FilesystemStorage, type GateResult, type HandshakeChallenge, type HandshakeCompletion, type HandshakeResponse, type HandshakeResult, InMemoryModelProvenanceStore, InjectionDetector, type InjectionDetectorConfig, type InjectionSignal, MODEL_PRESETS, MemoryStorage, type ModelProvenance, type ModelProvenanceStore, type PedersenCommitment, type PeerTrustEvaluation, type PolicyRecommendation, PolicyStore, type PrincipalPolicy, type ProviderCategory, ProxyRouter, type ProxyRouterOptions, ReputationStore, type SHRBody, type SHRGeneratorOptions, type SHRVerificationResult, type SanctuaryConfig, type SanctuaryServer, type SignedAttestation, type SignedSHR, type SovereigntyProfile, SovereigntyProfileStore, type SovereigntyProfileUpdate, type SovereigntyTier, StateStore, StderrApprovalChannel, TIER_WEIGHTS, type TierMetadata, type TieredAttestation, type UpstreamConnection, type UpstreamServer, type UpstreamTool, WebhookApprovalChannel, type WebhookCallbackPayload, type WebhookConfig, type WebhookPayload, type ZKProofOfKnowledge, type ZKRangeProof, canonicalize, classifyField, completeHandshake, computeWeightedScore, createBridgeCommitment, createDefaultProfile, createPedersenCommitment, createProofOfKnowledge, createRangeProof, createSanctuaryServer, evaluateField, filterContext, generateAttestation, generateSHR, generateSystemPrompt, getTemplate, initiateHandshake, listTemplateIds, loadConfig, loadPrincipalPolicy, recommendPolicy, resolveTier, respondToHandshake, signPayload, tierDistribution, verifyAttestation, verifyBridgeCommitment, verifyCompletion, verifyPedersenCommitment, verifyProofOfKnowledge, verifyRangeProof, verifySHR, verifySignature };
|