@solongate/proxy 0.25.2 → 0.25.4
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/index.js +60 -2
- package/dist/init.js +5 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -79,6 +79,27 @@ async function sendAuditLog(apiKey, apiUrl, entry) {
|
|
|
79
79
|
`);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
+
async function fetchAiJudgeConfig(apiKey, apiUrl) {
|
|
83
|
+
try {
|
|
84
|
+
const res = await fetch(`${apiUrl}/api/v1/project-config/ai-judge`, {
|
|
85
|
+
headers: {
|
|
86
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
87
|
+
"X-API-Key": apiKey
|
|
88
|
+
},
|
|
89
|
+
signal: AbortSignal.timeout(5e3)
|
|
90
|
+
});
|
|
91
|
+
if (!res.ok) return null;
|
|
92
|
+
const data = await res.json();
|
|
93
|
+
return {
|
|
94
|
+
enabled: Boolean(data.enabled),
|
|
95
|
+
model: String(data.model ?? "llama-3.1-8b-instant"),
|
|
96
|
+
endpoint: String(data.endpoint ?? "https://api.groq.com/openai"),
|
|
97
|
+
timeoutMs: Number(data.timeoutMs ?? 5e3)
|
|
98
|
+
};
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
82
103
|
function ensureCatchAllAllow(policy) {
|
|
83
104
|
const hasCatchAllAllow = policy.rules.some(
|
|
84
105
|
(r) => r.effect === "ALLOW" && r.toolPattern === "*" && r.enabled !== false
|
|
@@ -620,11 +641,14 @@ function ensureEnvFile() {
|
|
|
620
641
|
const envPath = resolve2(".env");
|
|
621
642
|
if (!existsSync3(envPath)) {
|
|
622
643
|
const envContent = `# SolonGate Configuration
|
|
623
|
-
# Get your API key from: https://dashboard.solongate.com/api-keys
|
|
624
644
|
# IMPORTANT: Never commit this file to git!
|
|
625
645
|
|
|
626
|
-
# Your SolonGate API key \u2014
|
|
646
|
+
# Your SolonGate API key \u2014 get one at https://dashboard.solongate.com
|
|
627
647
|
SOLONGATE_API_KEY=sg_live_your_key_here
|
|
648
|
+
|
|
649
|
+
# AI Judge (semantic security layer) \u2014 get a free key at https://console.groq.com/keys
|
|
650
|
+
# Enable with: npx @solongate/proxy --ai-judge ...
|
|
651
|
+
GROQ_API_KEY=gsk_your_groq_key_here
|
|
628
652
|
`;
|
|
629
653
|
writeFileSync2(envPath, envContent);
|
|
630
654
|
console.log(` Created .env`);
|
|
@@ -6416,6 +6440,40 @@ var SolonGateProxy = class {
|
|
|
6416
6440
|
this.registerToolsToCloud();
|
|
6417
6441
|
this.registerServerToCloud();
|
|
6418
6442
|
this.startPolicySync();
|
|
6443
|
+
if (this.config.apiKey && !this.config.apiKey.startsWith("sg_test_")) {
|
|
6444
|
+
try {
|
|
6445
|
+
const cloudJudge = await fetchAiJudgeConfig(this.config.apiKey, apiUrl);
|
|
6446
|
+
if (cloudJudge) {
|
|
6447
|
+
if (this.config.aiJudge?.enabled) {
|
|
6448
|
+
log2("AI Judge: CLI flags override cloud config.");
|
|
6449
|
+
} else if (cloudJudge.enabled) {
|
|
6450
|
+
let groqKey;
|
|
6451
|
+
const dotenvPath = (await import("path")).resolve(".env");
|
|
6452
|
+
const { existsSync: existsSync7, readFileSync: readFileSync6 } = await import("fs");
|
|
6453
|
+
if (existsSync7(dotenvPath)) {
|
|
6454
|
+
const content = readFileSync6(dotenvPath, "utf-8");
|
|
6455
|
+
const match = content.match(/^GROQ_API_KEY=(.+)/m);
|
|
6456
|
+
if (match) groqKey = match[1].trim();
|
|
6457
|
+
}
|
|
6458
|
+
if (!groqKey) groqKey = process.env.GROQ_API_KEY;
|
|
6459
|
+
if (groqKey) {
|
|
6460
|
+
this.config.aiJudge = {
|
|
6461
|
+
enabled: true,
|
|
6462
|
+
model: cloudJudge.model,
|
|
6463
|
+
endpoint: cloudJudge.endpoint,
|
|
6464
|
+
apiKey: groqKey,
|
|
6465
|
+
timeoutMs: cloudJudge.timeoutMs
|
|
6466
|
+
};
|
|
6467
|
+
log2(`AI Judge enabled via dashboard (model: ${cloudJudge.model}).`);
|
|
6468
|
+
} else {
|
|
6469
|
+
log2("AI Judge enabled in dashboard but GROQ_API_KEY not found in .env \u2014 skipping.");
|
|
6470
|
+
}
|
|
6471
|
+
}
|
|
6472
|
+
}
|
|
6473
|
+
} catch (err) {
|
|
6474
|
+
log2(`AI Judge cloud config fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6475
|
+
}
|
|
6476
|
+
}
|
|
6419
6477
|
if (this.config.aiJudge?.enabled) {
|
|
6420
6478
|
const protectedFiles = this.extractProtectedFiles();
|
|
6421
6479
|
const protectedPaths = this.extractProtectedPaths();
|
package/dist/init.js
CHANGED
|
@@ -283,11 +283,14 @@ function ensureEnvFile() {
|
|
|
283
283
|
const envPath = resolve(".env");
|
|
284
284
|
if (!existsSync(envPath)) {
|
|
285
285
|
const envContent = `# SolonGate Configuration
|
|
286
|
-
# Get your API key from: https://dashboard.solongate.com/api-keys
|
|
287
286
|
# IMPORTANT: Never commit this file to git!
|
|
288
287
|
|
|
289
|
-
# Your SolonGate API key \u2014
|
|
288
|
+
# Your SolonGate API key \u2014 get one at https://dashboard.solongate.com
|
|
290
289
|
SOLONGATE_API_KEY=sg_live_your_key_here
|
|
290
|
+
|
|
291
|
+
# AI Judge (semantic security layer) \u2014 get a free key at https://console.groq.com/keys
|
|
292
|
+
# Enable with: npx @solongate/proxy --ai-judge ...
|
|
293
|
+
GROQ_API_KEY=gsk_your_groq_key_here
|
|
291
294
|
`;
|
|
292
295
|
writeFileSync(envPath, envContent);
|
|
293
296
|
console.log(` Created .env`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.4",
|
|
4
4
|
"description": "MCP security proxy — protect any MCP server with customizable policies, path/command constraints, rate limiting, and audit logging. Zero code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|