@solongate/proxy 0.48.0 → 0.48.1

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.
Files changed (57) hide show
  1. package/dist/cli-utils.d.ts +27 -0
  2. package/dist/config.d.ts +105 -0
  3. package/dist/core/capability-token.d.ts +46 -0
  4. package/dist/core/constants.d.ts +47 -0
  5. package/dist/core/context-boundary.d.ts +19 -0
  6. package/dist/core/context.d.ts +24 -0
  7. package/dist/core/errors.d.ts +51 -0
  8. package/dist/core/execution.d.ts +35 -0
  9. package/dist/core/index.d.ts +14 -0
  10. package/dist/core/input-guard.d.ts +66 -0
  11. package/dist/core/mcp-types.d.ts +35 -0
  12. package/dist/core/permissions.d.ts +27 -0
  13. package/dist/core/policy.d.ts +399 -0
  14. package/dist/core/response-scanner.d.ts +27 -0
  15. package/dist/core/schema-validator.d.ts +33 -0
  16. package/dist/core/tool.d.ts +23 -0
  17. package/dist/core/trust.d.ts +28 -0
  18. package/dist/create.d.ts +13 -0
  19. package/dist/global-install.d.ts +17 -0
  20. package/dist/index.d.ts +38 -0
  21. package/dist/index.js +211 -158
  22. package/dist/init.d.ts +18 -0
  23. package/dist/inject.d.ts +19 -0
  24. package/dist/lib.d.ts +18 -0
  25. package/dist/lib.js +103 -48
  26. package/dist/login.d.ts +2 -0
  27. package/dist/policy-engine/command-matcher.d.ts +34 -0
  28. package/dist/policy-engine/defaults.d.ts +23 -0
  29. package/dist/policy-engine/engine.d.ts +30 -0
  30. package/dist/policy-engine/evaluator.d.ts +13 -0
  31. package/dist/policy-engine/filename-matcher.d.ts +20 -0
  32. package/dist/policy-engine/index.d.ts +12 -0
  33. package/dist/policy-engine/matcher.d.ts +18 -0
  34. package/dist/policy-engine/opa/index.d.ts +4 -0
  35. package/dist/policy-engine/opa/json-to-rego.d.ts +2 -0
  36. package/dist/policy-engine/opa/opa-evaluator.d.ts +10 -0
  37. package/dist/policy-engine/opa/rego-compiler.d.ts +2 -0
  38. package/dist/policy-engine/opa/request-adapter.d.ts +17 -0
  39. package/dist/policy-engine/path-matcher.d.ts +41 -0
  40. package/dist/policy-engine/policy-store.d.ts +66 -0
  41. package/dist/policy-engine/url-matcher.d.ts +29 -0
  42. package/dist/policy-engine/validator.d.ts +7 -0
  43. package/dist/policy-engine/warnings.d.ts +10 -0
  44. package/dist/proxy.d.ts +89 -0
  45. package/dist/pull-push.d.ts +17 -0
  46. package/dist/sdk/config.d.ts +26 -0
  47. package/dist/sdk/expiring-set.d.ts +18 -0
  48. package/dist/sdk/index.d.ts +10 -0
  49. package/dist/sdk/interceptor.d.ts +45 -0
  50. package/dist/sdk/logger.d.ts +16 -0
  51. package/dist/sdk/rate-limiter.d.ts +59 -0
  52. package/dist/sdk/secure-server.d.ts +68 -0
  53. package/dist/sdk/server-verifier.d.ts +53 -0
  54. package/dist/sdk/solongate.d.ts +105 -0
  55. package/dist/sdk/token-issuer.d.ts +37 -0
  56. package/dist/sync.d.ts +82 -0
  57. package/package.json +6 -4
package/dist/init.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * solongate init — Automatically wrap MCP servers with SolonGate protection.
4
+ *
5
+ * Reads your existing MCP configuration, wraps each server with the
6
+ * SolonGate proxy, and writes the protected configuration back.
7
+ *
8
+ * Usage:
9
+ * solongate-init [options]
10
+ *
11
+ * Options:
12
+ * --config <path> Path to MCP config file (default: auto-detect)
13
+ * --policy <file> Custom policy JSON file (auto-detects policy.json)
14
+ * --all Protect all servers without prompting
15
+ * --dry-run Show what would change without writing
16
+ * --restore Restore original config from backup
17
+ */
18
+ export {};
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * solongate inject — Auto-inject SolonGate SDK into an existing MCP server.
4
+ *
5
+ * Detects a TypeScript MCP server project, installs the SDK, and makes minimal
6
+ * source code changes to add SolonGate protection. Creates a backup so
7
+ * changes can be reverted with --restore.
8
+ *
9
+ * Usage:
10
+ * solongate-proxy inject [options]
11
+ *
12
+ * Options:
13
+ * --file <path> Entry file to modify (default: auto-detect)
14
+ * --dry-run Preview changes without writing
15
+ * --restore Restore from backup
16
+ * --skip-install Don't install SDK package
17
+ * -h, --help Show help
18
+ */
19
+ export {};
package/dist/lib.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @solongate/proxy — Library exports.
3
+ *
4
+ * Re-exports SDK classes (SolonGate, SecureMcpServer, RateLimiter, etc.)
5
+ * so that external consumers can import from '@solongate/proxy' without
6
+ * needing a separate @solongate/sdk package.
7
+ */
8
+ export { SolonGate, LicenseError } from './sdk/solongate.js';
9
+ export { SecureMcpServer, type SecureMcpServerOptions } from './sdk/secure-server.js';
10
+ export { interceptToolCall, ExfiltrationChainTracker, type InterceptorOptions } from './sdk/interceptor.js';
11
+ export { resolveConfig, DEFAULT_CONFIG, type SolonGateConfig } from './sdk/config.js';
12
+ export { SecurityLogger } from './sdk/logger.js';
13
+ export { TokenIssuer } from './sdk/token-issuer.js';
14
+ export { ServerVerifier, type SignedMcpRequest, type SignatureValidationResult } from './sdk/server-verifier.js';
15
+ export { RateLimiter, type RateLimitResult } from './sdk/rate-limiter.js';
16
+ export { TrustLevel, Permission, PolicyEffect, type PolicyRule, type PolicySet, type PolicyDecision, type SecurityContext, type ExecutionRequest, type ExecutionResult, type ToolCapability, type McpCallToolParams, type McpCallToolResult, type CapabilityToken, type TokenConfig, type InputGuardConfig, type ThreatType, type DetectedThreat, type SanitizationResult, SolonGateError, PolicyDeniedError, SchemaValidationError, RateLimitError as CoreRateLimitError, InputGuardError, NetworkError, createSecurityContext, createDeniedToolResult, validateToolInput, sanitizeInput, detectPathTraversal, detectShellInjection, detectWildcardAbuse, detectSSRF, detectSQLInjection, detectExfiltration, detectBoundaryEscape, checkLengthLimits, checkEntropyLimits, scanResponse, RESPONSE_WARNING_MARKER, BOUNDARY_PREFIX, BOUNDARY_SUFFIX, tagUserInput, stripBoundaryTags, type ResponseScanConfig, type ResponseThreatType, type ResponseThreat, type ResponseScanResult, type TaggedArguments, } from './core/index.js';
17
+ export { PolicyEngine, PolicyStore, type PolicyVersion, type PolicyDiff, createDefaultDenyPolicySet, createPermissivePolicySet, createReadOnlyPolicySet, } from './policy-engine/index.js';
18
+ export { SolonGateProxy } from './proxy.js';
package/dist/lib.js CHANGED
@@ -6150,8 +6150,7 @@ var init_src = __esm({
6150
6150
  }
6151
6151
  });
6152
6152
 
6153
- // ../core/dist/index.js
6154
- import { z } from "zod";
6153
+ // src/core/errors.ts
6155
6154
  var SolonGateError = class extends Error {
6156
6155
  code;
6157
6156
  timestamp;
@@ -6228,11 +6227,16 @@ var NetworkError = class extends SolonGateError {
6228
6227
  this.name = "NetworkError";
6229
6228
  }
6230
6229
  };
6230
+
6231
+ // src/core/trust.ts
6231
6232
  var TrustLevel = {
6232
6233
  UNTRUSTED: "UNTRUSTED",
6233
6234
  VERIFIED: "VERIFIED",
6234
6235
  TRUSTED: "TRUSTED"
6235
6236
  };
6237
+
6238
+ // src/core/permissions.ts
6239
+ import { z } from "zod";
6236
6240
  var Permission = {
6237
6241
  READ: "READ",
6238
6242
  WRITE: "WRITE",
@@ -6259,50 +6263,55 @@ var NO_PERMISSIONS = Object.freeze(
6259
6263
  var READ_ONLY = Object.freeze(
6260
6264
  /* @__PURE__ */ new Set([Permission.READ])
6261
6265
  );
6266
+
6267
+ // src/core/policy.ts
6268
+ import { z as z2 } from "zod";
6262
6269
  var PolicyEffect = {
6263
6270
  ALLOW: "ALLOW",
6264
6271
  DENY: "DENY"
6265
6272
  };
6266
- var PolicyRuleSchema = z.object({
6267
- id: z.string().min(1).max(256),
6268
- description: z.string().max(1024),
6269
- effect: z.enum(["ALLOW", "DENY"]),
6270
- priority: z.number().int().min(0).max(1e4).default(1e3),
6271
- toolPattern: z.string().min(1).max(512),
6272
- permission: z.enum(["READ", "WRITE", "EXECUTE", "NETWORK"]).optional(),
6273
- minimumTrustLevel: z.enum(["UNTRUSTED", "VERIFIED", "TRUSTED"]),
6274
- argumentConstraints: z.record(z.unknown()).optional(),
6275
- pathConstraints: z.object({
6276
- allowed: z.array(z.string()).optional(),
6277
- denied: z.array(z.string()).optional(),
6278
- rootDirectory: z.string().optional(),
6279
- allowSymlinks: z.boolean().optional()
6273
+ var PolicyRuleSchema = z2.object({
6274
+ id: z2.string().min(1).max(256),
6275
+ description: z2.string().max(1024),
6276
+ effect: z2.enum(["ALLOW", "DENY"]),
6277
+ priority: z2.number().int().min(0).max(1e4).default(1e3),
6278
+ toolPattern: z2.string().min(1).max(512),
6279
+ permission: z2.enum(["READ", "WRITE", "EXECUTE", "NETWORK"]).optional(),
6280
+ minimumTrustLevel: z2.enum(["UNTRUSTED", "VERIFIED", "TRUSTED"]),
6281
+ argumentConstraints: z2.record(z2.unknown()).optional(),
6282
+ pathConstraints: z2.object({
6283
+ allowed: z2.array(z2.string()).optional(),
6284
+ denied: z2.array(z2.string()).optional(),
6285
+ rootDirectory: z2.string().optional(),
6286
+ allowSymlinks: z2.boolean().optional()
6280
6287
  }).optional(),
6281
- commandConstraints: z.object({
6282
- allowed: z.array(z.string()).optional(),
6283
- denied: z.array(z.string()).optional()
6288
+ commandConstraints: z2.object({
6289
+ allowed: z2.array(z2.string()).optional(),
6290
+ denied: z2.array(z2.string()).optional()
6284
6291
  }).optional(),
6285
- filenameConstraints: z.object({
6286
- allowed: z.array(z.string()).optional(),
6287
- denied: z.array(z.string()).optional()
6292
+ filenameConstraints: z2.object({
6293
+ allowed: z2.array(z2.string()).optional(),
6294
+ denied: z2.array(z2.string()).optional()
6288
6295
  }).optional(),
6289
- urlConstraints: z.object({
6290
- allowed: z.array(z.string()).optional(),
6291
- denied: z.array(z.string()).optional()
6296
+ urlConstraints: z2.object({
6297
+ allowed: z2.array(z2.string()).optional(),
6298
+ denied: z2.array(z2.string()).optional()
6292
6299
  }).optional(),
6293
- enabled: z.boolean().default(true),
6294
- createdAt: z.string().datetime(),
6295
- updatedAt: z.string().datetime()
6300
+ enabled: z2.boolean().default(true),
6301
+ createdAt: z2.string().datetime(),
6302
+ updatedAt: z2.string().datetime()
6296
6303
  });
6297
- var PolicySetSchema = z.object({
6298
- id: z.string().min(1).max(256),
6299
- name: z.string().min(1).max(256),
6300
- description: z.string().max(2048),
6301
- version: z.number().int().min(0),
6302
- rules: z.array(PolicyRuleSchema),
6303
- createdAt: z.string().datetime(),
6304
- updatedAt: z.string().datetime()
6304
+ var PolicySetSchema = z2.object({
6305
+ id: z2.string().min(1).max(256),
6306
+ name: z2.string().min(1).max(256),
6307
+ description: z2.string().max(2048),
6308
+ version: z2.number().int().min(0),
6309
+ rules: z2.array(PolicyRuleSchema),
6310
+ createdAt: z2.string().datetime(),
6311
+ updatedAt: z2.string().datetime()
6305
6312
  });
6313
+
6314
+ // src/core/context.ts
6306
6315
  function createSecurityContext(params) {
6307
6316
  return {
6308
6317
  trustLevel: "UNTRUSTED",
@@ -6313,6 +6322,8 @@ function createSecurityContext(params) {
6313
6322
  ...params
6314
6323
  };
6315
6324
  }
6325
+
6326
+ // src/core/constants.ts
6316
6327
  var DEFAULT_POLICY_EFFECT = "DENY";
6317
6328
  var MAX_RULES_PER_POLICY_SET = 1e3;
6318
6329
  var MAX_ARGUMENT_DEPTH = 10;
@@ -6333,6 +6344,8 @@ var UNSAFE_CONFIGURATION_WARNINGS = {
6333
6344
  RATE_LIMIT_ZERO: "A rate limit of 0 means unlimited calls. This removes protection against runaway loops.",
6334
6345
  DISABLED_VALIDATION: "Disabling schema validation removes input sanitization protections."
6335
6346
  };
6347
+
6348
+ // src/core/mcp-types.ts
6336
6349
  function createDeniedToolResult(reason) {
6337
6350
  return {
6338
6351
  content: [
@@ -6348,6 +6361,9 @@ function createDeniedToolResult(reason) {
6348
6361
  isError: true
6349
6362
  };
6350
6363
  }
6364
+
6365
+ // src/core/schema-validator.ts
6366
+ import { z as z3 } from "zod";
6351
6367
  var DEFAULT_OPTIONS = {
6352
6368
  maxDepth: MAX_ARGUMENT_DEPTH,
6353
6369
  maxSizeBytes: MAX_ARGUMENTS_SIZE_BYTES,
@@ -6423,6 +6439,8 @@ function measureDepth(value, currentDepth) {
6423
6439
  }
6424
6440
  return maxChildDepth;
6425
6441
  }
6442
+
6443
+ // src/core/input-guard.ts
6426
6444
  var DEFAULT_INPUT_GUARD_CONFIG = Object.freeze({
6427
6445
  pathTraversal: true,
6428
6446
  shellInjection: true,
@@ -6797,6 +6815,8 @@ function sanitizeObject(basePath, obj, config) {
6797
6815
  function truncate(str, maxLen) {
6798
6816
  return str.length > maxLen ? str.slice(0, maxLen) + "..." : str;
6799
6817
  }
6818
+
6819
+ // src/core/response-scanner.ts
6800
6820
  var DEFAULT_RESPONSE_SCAN_CONFIG = Object.freeze({
6801
6821
  injectedInstruction: true,
6802
6822
  hiddenDirective: true,
@@ -6906,6 +6926,8 @@ var RESPONSE_WARNING_MARKER = "[SOLONGATE WARNING: response may contain injected
6906
6926
  function truncate2(str, maxLen) {
6907
6927
  return str.length > maxLen ? str.slice(0, maxLen) + "..." : str;
6908
6928
  }
6929
+
6930
+ // src/core/context-boundary.ts
6909
6931
  function tagUserInput(args) {
6910
6932
  return tagObject(args);
6911
6933
  }
@@ -6931,13 +6953,13 @@ function tagObject(obj) {
6931
6953
  function stripBoundaryTags(text) {
6932
6954
  return text.replaceAll(BOUNDARY_PREFIX, "").replaceAll(BOUNDARY_SUFFIX, "");
6933
6955
  }
6956
+
6957
+ // src/core/capability-token.ts
6934
6958
  var DEFAULT_TOKEN_TTL_SECONDS = 30;
6935
6959
  var TOKEN_ALGORITHM = "HS256";
6936
6960
  var MIN_SECRET_LENGTH = 32;
6937
6961
 
6938
- // ../policy-engine/dist/index.js
6939
- import { gunzipSync } from "zlib";
6940
- import { createHash, randomUUID } from "crypto";
6962
+ // src/policy-engine/validator.ts
6941
6963
  function validatePolicySet(input) {
6942
6964
  const errors = [];
6943
6965
  const warnings = [];
@@ -6987,6 +7009,8 @@ function validatePolicySet(input) {
6987
7009
  warnings
6988
7010
  };
6989
7011
  }
7012
+
7013
+ // src/policy-engine/warnings.ts
6990
7014
  function analyzeSecurityWarnings(policySet) {
6991
7015
  const warnings = [];
6992
7016
  for (const rule of policySet.rules) {
@@ -7028,6 +7052,8 @@ function analyzeRuleWarnings(rule) {
7028
7052
  }
7029
7053
  return warnings;
7030
7054
  }
7055
+
7056
+ // src/policy-engine/defaults.ts
7031
7057
  function createDefaultDenyPolicySet() {
7032
7058
  const now = (/* @__PURE__ */ new Date()).toISOString();
7033
7059
  return {
@@ -7151,6 +7177,11 @@ function createReadOnlyPolicySet(toolPattern) {
7151
7177
  updatedAt: now
7152
7178
  };
7153
7179
  }
7180
+
7181
+ // src/policy-engine/opa/opa-evaluator.ts
7182
+ import { gunzipSync } from "zlib";
7183
+
7184
+ // src/policy-engine/path-matcher.ts
7154
7185
  var PATH_FIELDS = /* @__PURE__ */ new Set([
7155
7186
  "path",
7156
7187
  "file",
@@ -7197,6 +7228,8 @@ function extractPathArguments(args) {
7197
7228
  }
7198
7229
  return paths;
7199
7230
  }
7231
+
7232
+ // src/policy-engine/command-matcher.ts
7200
7233
  var COMMAND_FIELDS = /* @__PURE__ */ new Set([
7201
7234
  "command",
7202
7235
  "cmd",
@@ -7318,6 +7351,8 @@ function extractCommandArguments(args) {
7318
7351
  commands.push(...expanded);
7319
7352
  return commands;
7320
7353
  }
7354
+
7355
+ // src/policy-engine/url-matcher.ts
7321
7356
  var URL_FIELDS = /* @__PURE__ */ new Set([
7322
7357
  "url",
7323
7358
  "href",
@@ -7372,6 +7407,8 @@ function extractUrlArguments(args) {
7372
7407
  }
7373
7408
  return urls;
7374
7409
  }
7410
+
7411
+ // src/policy-engine/filename-matcher.ts
7375
7412
  var SENSITIVE_FILENAMES = [
7376
7413
  ".env",
7377
7414
  ".env.local",
@@ -7559,6 +7596,8 @@ function looksLikeFilename(s) {
7559
7596
  if (KNOWN_EXTENSIONLESS_FILES.has(s.toLowerCase())) return true;
7560
7597
  return false;
7561
7598
  }
7599
+
7600
+ // src/policy-engine/opa/request-adapter.ts
7562
7601
  function toOpaInput(request) {
7563
7602
  const args = request.arguments ?? {};
7564
7603
  return {
@@ -7572,6 +7611,8 @@ function toOpaInput(request) {
7572
7611
  filenames: extractFilenames(args)
7573
7612
  };
7574
7613
  }
7614
+
7615
+ // src/policy-engine/opa/opa-evaluator.ts
7575
7616
  var loadPolicyFn = null;
7576
7617
  async function getLoadPolicy() {
7577
7618
  if (!loadPolicyFn) {
@@ -7674,6 +7715,8 @@ var OpaEvaluator = class {
7674
7715
  this.policy.setData(data);
7675
7716
  }
7676
7717
  };
7718
+
7719
+ // src/policy-engine/engine.ts
7677
7720
  var PolicyEngine = class {
7678
7721
  policySet;
7679
7722
  timeoutMs;
@@ -7776,11 +7819,16 @@ var PolicyEngine = class {
7776
7819
  this.policySet = createDefaultDenyPolicySet();
7777
7820
  }
7778
7821
  };
7822
+
7823
+ // src/policy-engine/matcher.ts
7779
7824
  var TRUST_LEVEL_ORDER = {
7780
7825
  [TrustLevel.UNTRUSTED]: 0,
7781
7826
  [TrustLevel.VERIFIED]: 1,
7782
7827
  [TrustLevel.TRUSTED]: 2
7783
7828
  };
7829
+
7830
+ // src/policy-engine/policy-store.ts
7831
+ import { createHash } from "crypto";
7784
7832
  function stableStringify(val) {
7785
7833
  return JSON.stringify(
7786
7834
  val,
@@ -7882,6 +7930,13 @@ var PolicyStore = class {
7882
7930
  }
7883
7931
  };
7884
7932
 
7933
+ // src/policy-engine/opa/rego-compiler.ts
7934
+ import { execFileSync } from "child_process";
7935
+ import { writeFileSync, readFileSync, mkdirSync, rmSync } from "fs";
7936
+ import { join } from "path";
7937
+ import { tmpdir } from "os";
7938
+ import { randomUUID } from "crypto";
7939
+
7885
7940
  // src/sdk/config.ts
7886
7941
  var DEFAULT_CONFIG = Object.freeze({
7887
7942
  validateSchemas: true,
@@ -8935,13 +8990,13 @@ import {
8935
8990
  ListResourceTemplatesRequestSchema
8936
8991
  } from "@modelcontextprotocol/sdk/types.js";
8937
8992
  import { createServer as createHttpServer } from "http";
8938
- import { resolve as resolve2, join as join2 } from "path";
8939
- import { mkdirSync as mkdirSync2, appendFileSync } from "fs";
8993
+ import { resolve as resolve2, join as join3 } from "path";
8994
+ import { mkdirSync as mkdirSync3, appendFileSync } from "fs";
8940
8995
 
8941
8996
  // src/config.ts
8942
- import { readFileSync, existsSync } from "fs";
8997
+ import { readFileSync as readFileSync2, existsSync } from "fs";
8943
8998
  import { appendFile } from "fs/promises";
8944
- import { resolve, join } from "path";
8999
+ import { resolve, join as join2 } from "path";
8945
9000
  import { homedir } from "os";
8946
9001
  var DEFAULT_API_URL = "https://api.solongate.com";
8947
9002
  async function fetchCloudPolicy(apiKey, apiUrl, policyId) {
@@ -9041,7 +9096,7 @@ async function sendAuditLog(apiKey, apiUrl, entry) {
9041
9096
  }
9042
9097
 
9043
9098
  // src/sync.ts
9044
- import { readFileSync as readFileSync2, writeFileSync, watch, existsSync as existsSync2 } from "fs";
9099
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, watch, existsSync as existsSync2 } from "fs";
9045
9100
  var log = (...args) => process.stderr.write(`[SolonGate Sync] ${args.map(String).join(" ")}
9046
9101
  `);
9047
9102
  var PolicySyncManager = class {
@@ -9130,7 +9185,7 @@ var PolicySyncManager = class {
9130
9185
  log("Policy file deleted \u2014 keeping current policy");
9131
9186
  return;
9132
9187
  }
9133
- const content = readFileSync2(filePath, "utf-8");
9188
+ const content = readFileSync3(filePath, "utf-8");
9134
9189
  const newPolicy = JSON.parse(content);
9135
9190
  if (newPolicy.version <= this.localVersion) {
9136
9191
  newPolicy.version = Math.max(this.localVersion, this.cloudVersion) + 1;
@@ -9239,7 +9294,7 @@ var PolicySyncManager = class {
9239
9294
  try {
9240
9295
  const { id: _id, ...rest } = policy;
9241
9296
  const json = JSON.stringify(rest, null, 2) + "\n";
9242
- writeFileSync(this.localPath, json, "utf-8");
9297
+ writeFileSync2(this.localPath, json, "utf-8");
9243
9298
  } catch (err) {
9244
9299
  log(`File write error: ${err instanceof Error ? err.message : String(err)}`);
9245
9300
  }
@@ -9516,8 +9571,8 @@ var SolonGateProxy = class {
9516
9571
  pid: process.pid
9517
9572
  };
9518
9573
  const debugDir = resolve2(".solongate");
9519
- mkdirSync2(debugDir, { recursive: true });
9520
- appendFileSync(join2(debugDir, ".debug-proxy"), JSON.stringify(debugInfo) + "\n");
9574
+ mkdirSync3(debugDir, { recursive: true });
9575
+ appendFileSync(join3(debugDir, ".debug-proxy"), JSON.stringify(debugInfo) + "\n");
9521
9576
  } catch {
9522
9577
  }
9523
9578
  if (clientVersion?.name && !this.config.agentName) {
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,34 @@
1
+ import type { PolicyRule } from '../core/index.js';
2
+ type CommandConstraints = NonNullable<PolicyRule['commandConstraints']>;
3
+ /**
4
+ * Extracts inner commands from subshell wrappers (bash -c, eval, etc.)
5
+ * Returns the original command plus any extracted inner commands.
6
+ */
7
+ export declare function extractInnerCommands(command: string, depth?: number): string[];
8
+ /**
9
+ * Extracts command-like arguments from tool call arguments.
10
+ * Uses known field names plus heuristic detection for command-like strings
11
+ * in any field, and recurses into nested objects/arrays.
12
+ */
13
+ export declare function extractCommandArguments(args: Readonly<Record<string, unknown>>): string[];
14
+ /**
15
+ * Glob-style command pattern matching.
16
+ * Matches against the command string (first word) or full command line.
17
+ *
18
+ * Patterns:
19
+ * 'ls' → exact match on command name
20
+ * 'git*' → command starts with 'git'
21
+ * '*sql*' → command contains 'sql'
22
+ * 'rm -rf *' → full command line starts with 'rm -rf '
23
+ */
24
+ export declare function matchCommandPattern(command: string, pattern: string): boolean;
25
+ /**
26
+ * Checks if a command is allowed by the given constraints.
27
+ *
28
+ * Evaluation order:
29
+ * 1. If denied list exists, command must NOT match any denied pattern
30
+ * 2. If allowed list exists, command must match at least one allowed pattern
31
+ * 3. If neither list exists, command is allowed (constraints are optional)
32
+ */
33
+ export declare function isCommandAllowed(command: string, constraints: CommandConstraints): boolean;
34
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { PolicySet } from '../core/index.js';
2
+ /**
3
+ * Creates the default "deny all" policy set.
4
+ * This is the starting policy for any new SolonGate deployment.
5
+ */
6
+ export declare function createDefaultDenyPolicySet(): PolicySet;
7
+ /**
8
+ * Creates a permissive "allow all" policy set.
9
+ * Allows all tool executions — useful for development or when
10
+ * using SolonGate only for monitoring and audit logging.
11
+ */
12
+ export declare function createPermissivePolicySet(): PolicySet;
13
+ /**
14
+ * Creates a read-only policy set for a specific tool pattern.
15
+ * Allows reads for VERIFIED requests only.
16
+ */
17
+ export declare function createReadOnlyPolicySet(toolPattern: string): PolicySet;
18
+ /**
19
+ * Creates a sandboxed policy set for a given root directory.
20
+ * Allows file operations within rootDir, blocks dangerous commands,
21
+ * denies access to sensitive files.
22
+ */
23
+ export declare function createSandboxedPolicySet(rootDir: string): PolicySet;
@@ -0,0 +1,30 @@
1
+ import type { PolicySet, PolicyDecision, ExecutionRequest } from '../core/index.js';
2
+ import { type ValidationResult } from './validator.js';
3
+ import { type SecurityWarning } from './warnings.js';
4
+ import { PolicyStore, type PolicyVersion } from './policy-store.js';
5
+ export declare class PolicyEngine {
6
+ private policySet;
7
+ private readonly timeoutMs;
8
+ private readonly store;
9
+ private opaEvaluator;
10
+ constructor(options?: {
11
+ policySet?: PolicySet;
12
+ timeoutMs?: number;
13
+ store?: PolicyStore;
14
+ wasmBundle?: BufferSource;
15
+ });
16
+ private _pendingWasm;
17
+ initOpa(): Promise<void>;
18
+ loadWasmBundle(wasmBundle: BufferSource): Promise<void>;
19
+ evaluate(request: ExecutionRequest): PolicyDecision;
20
+ getEvaluatorMode(): 'opa' | 'opa-unloaded';
21
+ loadPolicySet(policySet: PolicySet, options?: {
22
+ reason?: string;
23
+ createdBy?: string;
24
+ }): ValidationResult;
25
+ rollback(version: number): PolicyVersion;
26
+ getPolicySet(): Readonly<PolicySet>;
27
+ getSecurityWarnings(): readonly SecurityWarning[];
28
+ getStore(): PolicyStore | null;
29
+ reset(): void;
30
+ }
@@ -0,0 +1,13 @@
1
+ import type { PolicySet, PolicyDecision, ExecutionRequest } from '../core/index.js';
2
+ /**
3
+ * Evaluates a policy set against an execution request.
4
+ *
5
+ * Pure function: no side effects, no I/O, fully deterministic.
6
+ *
7
+ * Algorithm:
8
+ * 1. Sort rules by priority (ascending - lower number = higher priority)
9
+ * 2. Find the first matching rule
10
+ * 3. If a rule matches, return its effect
11
+ * 4. If no rule matches, return DENY (default-deny)
12
+ */
13
+ export declare function evaluatePolicy(policySet: PolicySet, request: ExecutionRequest): PolicyDecision;
@@ -0,0 +1,20 @@
1
+ import type { PolicyRule } from '../core/index.js';
2
+ type FilenameConstraints = NonNullable<PolicyRule['filenameConstraints']>;
3
+ /**
4
+ * Extracts filenames from ALL string arguments using shell-agnostic scanning.
5
+ *
6
+ * Architecture: OS-permission style enforcement.
7
+ * Instead of trying to parse every shell trick, we strip ALL shell syntax
8
+ * and scan the raw text. If a protected filename appears in ANY form,
9
+ * it gets extracted and checked against policy constraints.
10
+ */
11
+ export declare function extractFilenames(args: Readonly<Record<string, unknown>>): string[];
12
+ /**
13
+ * Glob-style filename pattern matching (case-insensitive).
14
+ */
15
+ export declare function matchFilenamePattern(filename: string, pattern: string): boolean;
16
+ /**
17
+ * Checks if a filename is allowed by the given constraints.
18
+ */
19
+ export declare function isFilenameAllowed(filename: string, constraints: FilenameConstraints): boolean;
20
+ export {};
@@ -0,0 +1,12 @@
1
+ export { PolicyEngine } from './engine.js';
2
+ export { evaluatePolicy } from './evaluator.js';
3
+ export { ruleMatchesRequest, toolPatternMatches, trustLevelMeetsMinimum } from './matcher.js';
4
+ export { validatePolicyRule, validatePolicySet, type ValidationResult } from './validator.js';
5
+ export { analyzeSecurityWarnings, type SecurityWarning } from './warnings.js';
6
+ export { createDefaultDenyPolicySet, createPermissivePolicySet, createReadOnlyPolicySet, createSandboxedPolicySet } from './defaults.js';
7
+ export { isPathAllowed, isWithinRoot, matchPathPattern, normalizePath, extractPathArguments, } from './path-matcher.js';
8
+ export { isCommandAllowed, matchCommandPattern, extractCommandArguments, } from './command-matcher.js';
9
+ export { isFilenameAllowed, matchFilenamePattern, extractFilenames, } from './filename-matcher.js';
10
+ export { isUrlAllowed, matchUrlPattern, extractUrlArguments, } from './url-matcher.js';
11
+ export { PolicyStore, type PolicyVersion, type PolicyDiff } from './policy-store.js';
12
+ export { OpaEvaluator, convertPolicySetToRego, compileRegoToWasm, isOpaAvailable, toOpaInput, type OpaInput, type OpaDecision } from './opa/index.js';
@@ -0,0 +1,18 @@
1
+ import type { PolicyRule, ExecutionRequest } from '../core/index.js';
2
+ import { TrustLevel } from '../core/index.js';
3
+ /**
4
+ * Pure function: determines if a policy rule matches an execution request.
5
+ * No side effects. No I/O. Fully deterministic.
6
+ */
7
+ export declare function ruleMatchesRequest(rule: PolicyRule, request: ExecutionRequest): boolean;
8
+ /**
9
+ * Glob-style tool name pattern matching.
10
+ * Supports:
11
+ * '*' → match all
12
+ * 'prefix*' → starts with prefix
13
+ * '*suffix' → ends with suffix
14
+ * '*infix*' → contains infix
15
+ * Does NOT support regex (ReDoS prevention).
16
+ */
17
+ export declare function toolPatternMatches(pattern: string, toolName: string): boolean;
18
+ export declare function trustLevelMeetsMinimum(actual: TrustLevel, minimum: TrustLevel): boolean;
@@ -0,0 +1,4 @@
1
+ export { OpaEvaluator } from './opa-evaluator.js';
2
+ export { convertPolicySetToRego } from './json-to-rego.js';
3
+ export { compileRegoToWasm, isOpaAvailable } from './rego-compiler.js';
4
+ export { toOpaInput, type OpaInput, type OpaDecision } from './request-adapter.js';
@@ -0,0 +1,2 @@
1
+ import type { PolicySet } from '../../core/index.js';
2
+ export declare function convertPolicySetToRego(policySet: PolicySet): string;
@@ -0,0 +1,10 @@
1
+ import type { PolicyDecision, ExecutionRequest } from '../../core/index.js';
2
+ export declare class OpaEvaluator {
3
+ private policy;
4
+ private initialized;
5
+ loadBundle(wasmBundle: BufferSource): Promise<void>;
6
+ loadWasm(wasmBytes: BufferSource): Promise<void>;
7
+ evaluate(request: ExecutionRequest): PolicyDecision;
8
+ isReady(): boolean;
9
+ setData(data: unknown): void;
10
+ }
@@ -0,0 +1,2 @@
1
+ export declare function compileRegoToWasm(regoSource: string, entrypoint?: string): Promise<Buffer>;
2
+ export declare function isOpaAvailable(): boolean;
@@ -0,0 +1,17 @@
1
+ import type { ExecutionRequest } from '../../core/index.js';
2
+ export interface OpaInput {
3
+ tool_name: string;
4
+ permission: string;
5
+ trust_level: string;
6
+ arguments: Record<string, unknown>;
7
+ paths: string[];
8
+ commands: string[];
9
+ urls: string[];
10
+ filenames: string[];
11
+ }
12
+ export interface OpaDecision {
13
+ effect: 'ALLOW' | 'DENY';
14
+ reason: string;
15
+ matched_rule: string | null;
16
+ }
17
+ export declare function toOpaInput(request: ExecutionRequest): OpaInput;
@@ -0,0 +1,41 @@
1
+ import type { PolicyRule } from '../core/index.js';
2
+ type PathConstraints = NonNullable<PolicyRule['pathConstraints']>;
3
+ /**
4
+ * Normalizes a file path for consistent matching.
5
+ * Resolves . and .. segments, normalizes separators.
6
+ */
7
+ export declare function normalizePath(path: string): string;
8
+ /**
9
+ * Checks if a path is within a root directory (sandbox boundary).
10
+ * Prevents escaping via .., symlinks, etc.
11
+ */
12
+ export declare function isWithinRoot(path: string, root: string): boolean;
13
+ /**
14
+ * Glob-style path pattern matching.
15
+ * Supports:
16
+ * - * matches any single path segment (not /)
17
+ * - ** matches any number of path segments
18
+ * - Exact match
19
+ *
20
+ * Does NOT support regex (ReDoS prevention).
21
+ */
22
+ export declare function matchPathPattern(path: string, pattern: string): boolean;
23
+ /**
24
+ * Checks if a path is allowed by the given constraints.
25
+ *
26
+ * Evaluation order:
27
+ * 1. If rootDirectory is set, path must be within it
28
+ * 2. If denied list exists, path must NOT match any denied pattern
29
+ * 3. If allowed list exists, path must match at least one allowed pattern
30
+ * 4. If neither list exists, path is allowed (constraints are optional)
31
+ */
32
+ export declare function isPathAllowed(path: string, constraints: PathConstraints): boolean;
33
+ /**
34
+ * Extracts path-like arguments from tool call arguments.
35
+ * Uses multiple heuristics:
36
+ * 1. Known path field names — always extract
37
+ * 2. Strings containing / or \ (original heuristic)
38
+ * 3. Strings starting with . (.env, ./foo)
39
+ */
40
+ export declare function extractPathArguments(args: Readonly<Record<string, unknown>>): string[];
41
+ export {};