@solongate/proxy 0.81.60 → 0.81.62
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.
|
@@ -15,3 +15,41 @@
|
|
|
15
15
|
{"ms":2,"ts":1784326365762,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
16
16
|
{"ms":3,"ts":1784326398280,"tool":"Edit","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
17
17
|
{"ms":1,"ts":1784326403539,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
18
|
+
{"ms":2,"ts":1784359530309,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
19
|
+
{"ms":4,"ts":1784359565744,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
20
|
+
{"ms":3,"ts":1784359892056,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
21
|
+
{"ms":2,"ts":1784359899408,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
22
|
+
{"ms":3,"ts":1784359942766,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
23
|
+
{"ms":3,"ts":1784359948446,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
24
|
+
{"ms":5,"ts":1784360088630,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
25
|
+
{"ms":2,"ts":1784360093227,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
26
|
+
{"ms":4,"ts":1784360125661,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
27
|
+
{"ms":2,"ts":1784360134508,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
28
|
+
{"ms":5,"ts":1784360234461,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
29
|
+
{"ms":4,"ts":1784360256656,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
30
|
+
{"ms":5,"ts":1784365255204,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
31
|
+
{"ms":4,"ts":1784365279092,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
32
|
+
{"ms":4,"ts":1784365328385,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
33
|
+
{"ms":4,"ts":1784365360712,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
34
|
+
{"ms":4,"ts":1784365375478,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
35
|
+
{"ms":3,"ts":1784365383985,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
36
|
+
{"ms":9,"ts":1784365415903,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
37
|
+
{"ms":4,"ts":1784365422626,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
38
|
+
{"ms":5,"ts":1784365497358,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
39
|
+
{"ms":4,"ts":1784365509533,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
40
|
+
{"ms":4,"ts":1784365523577,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
41
|
+
{"ms":1,"ts":1784365524083,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
42
|
+
{"ms":2,"ts":1784365525077,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
43
|
+
{"ms":3,"ts":1784365525605,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
44
|
+
{"ms":3,"ts":1784365526627,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
45
|
+
{"ms":2,"ts":1784365527031,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
46
|
+
{"ms":5,"ts":1784366243066,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
47
|
+
{"ms":3,"ts":1784366250503,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
48
|
+
{"ms":4,"ts":1784366281171,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
49
|
+
{"ms":2,"ts":1784366288049,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
50
|
+
{"ms":3,"ts":1784367337998,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
51
|
+
{"ms":2,"ts":1784367345104,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
52
|
+
{"ms":4,"ts":1784367420866,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
53
|
+
{"ms":2,"ts":1784367428790,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
54
|
+
{"ms":3,"ts":1784369708978,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
55
|
+
{"ms":4,"ts":1784369720104,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"tool":"Bash","ts":
|
|
1
|
+
{"tool":"Bash","ts":1784365527031}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"ms":
|
|
1
|
+
{"ms":4,"ts":1784369720104,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1784369709035
|
package/hooks/guard.bundled.mjs
CHANGED
|
@@ -6536,11 +6536,28 @@ import { resolve, join, dirname, isAbsolute } from "node:path";
|
|
|
6536
6536
|
import { homedir } from "node:os";
|
|
6537
6537
|
import { gunzipSync } from "node:zlib";
|
|
6538
6538
|
import { createHash } from "node:crypto";
|
|
6539
|
-
var HOOK_VERSION =
|
|
6539
|
+
var HOOK_VERSION = 36;
|
|
6540
6540
|
function localLogsOnly(security) {
|
|
6541
|
-
|
|
6542
|
-
|
|
6541
|
+
if (security && typeof security === "object") {
|
|
6542
|
+
const l = security.localLogs;
|
|
6543
|
+
return !!(l && l.enabled && typeof l.path === "string" && l.path.trim());
|
|
6544
|
+
}
|
|
6545
|
+
try {
|
|
6546
|
+
const m = JSON.parse(readFileSync(join(resolve(homedir(), ".solongate"), ".local-logs-mode.json"), "utf-8"));
|
|
6547
|
+
return !!(m && m.localOnly);
|
|
6548
|
+
} catch {
|
|
6549
|
+
return false;
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
function writeLocalMarker(security) {
|
|
6553
|
+
try {
|
|
6554
|
+
const l = security && security.localLogs;
|
|
6555
|
+
const localOnly = !!(l && l.enabled && typeof l.path === "string" && l.path.trim());
|
|
6556
|
+
writeFileSync(join(resolve(homedir(), ".solongate"), ".local-logs-mode.json"), JSON.stringify({ localOnly, ts: Date.now() }));
|
|
6557
|
+
} catch {
|
|
6558
|
+
}
|
|
6543
6559
|
}
|
|
6560
|
+
var _invalidPathNoted = false;
|
|
6544
6561
|
function resolveLocalLogDir(rawPath) {
|
|
6545
6562
|
const dir = String(rawPath || "").trim().replace(/[\\/]+$/, "");
|
|
6546
6563
|
if (!dir)
|
|
@@ -6548,13 +6565,16 @@ function resolveLocalLogDir(rawPath) {
|
|
|
6548
6565
|
if (isAbsolute(dir))
|
|
6549
6566
|
return dir;
|
|
6550
6567
|
const fallback = resolve(homedir(), ".solongate", "local-logs");
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
resolve(homedir(), ".solongate",
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6568
|
+
if (!_invalidPathNoted) {
|
|
6569
|
+
_invalidPathNoted = true;
|
|
6570
|
+
try {
|
|
6571
|
+
mkdirSync(resolve(homedir(), ".solongate"), { recursive: true });
|
|
6572
|
+
writeFileSync(
|
|
6573
|
+
resolve(homedir(), ".solongate", ".local-logs-invalid-path"),
|
|
6574
|
+
JSON.stringify({ configured: dir, fallback, ts: Date.now() })
|
|
6575
|
+
);
|
|
6576
|
+
} catch {
|
|
6577
|
+
}
|
|
6558
6578
|
}
|
|
6559
6579
|
return fallback;
|
|
6560
6580
|
}
|
|
@@ -6753,6 +6773,7 @@ async function refreshPolicyCache() {
|
|
|
6753
6773
|
writeFileSync(cacheFile, JSON.stringify({ _ts: Date.now(), policy, selfProtect, security, hookVersions }));
|
|
6754
6774
|
} catch {
|
|
6755
6775
|
}
|
|
6776
|
+
writeLocalMarker(security);
|
|
6756
6777
|
} catch {
|
|
6757
6778
|
}
|
|
6758
6779
|
}
|
|
@@ -7751,8 +7772,10 @@ if (!REFRESH_MODE) {
|
|
|
7751
7772
|
dashboardPolicy = cached.policy;
|
|
7752
7773
|
if (typeof cached.selfProtect === "boolean")
|
|
7753
7774
|
selfProtectEnabled = cached.selfProtect;
|
|
7754
|
-
if (cached.security !== void 0)
|
|
7775
|
+
if (cached.security !== void 0) {
|
|
7755
7776
|
securityCfg = cached.security;
|
|
7777
|
+
writeLocalMarker(securityCfg);
|
|
7778
|
+
}
|
|
7756
7779
|
if (cached.hookVersions)
|
|
7757
7780
|
CLOUD_HOOK_VERSIONS = cached.hookVersions;
|
|
7758
7781
|
}
|
package/hooks/guard.mjs
CHANGED
|
@@ -32,13 +32,36 @@ import { createHash } from 'node:crypto';
|
|
|
32
32
|
// the installed hook self-updates when the cloud version is higher (see
|
|
33
33
|
// maybeSelfUpdate). This is what makes guard fixes propagate without a manual
|
|
34
34
|
// reinstall — the same trust model as the OPA WASM this hook already runs.
|
|
35
|
-
const HOOK_VERSION =
|
|
35
|
+
const HOOK_VERSION = 36;
|
|
36
36
|
|
|
37
37
|
// True when local log storage is ON. In that mode logs are kept LOCAL ONLY and
|
|
38
38
|
// nothing is sent to the cloud audit log.
|
|
39
39
|
function localLogsOnly(security) {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
if (security && typeof security === 'object') {
|
|
41
|
+
const l = security.localLogs;
|
|
42
|
+
return !!(l && l.enabled && typeof l.path === 'string' && l.path.trim());
|
|
43
|
+
}
|
|
44
|
+
// security UNKNOWN (cold start / policy-cache miss / mid-toggle): consult the
|
|
45
|
+
// persisted local-mode marker so a DENY is NEVER leaked to the cloud when this
|
|
46
|
+
// device is in local-only mode. Without this fallback the first call(s) before
|
|
47
|
+
// the policy cache warms POST the denial to the cloud and fire webhooks/alerts
|
|
48
|
+
// even though the user chose local-only.
|
|
49
|
+
try {
|
|
50
|
+
const m = JSON.parse(readFileSync(join(resolve(homedir(), '.solongate'), '.local-logs-mode.json'), 'utf-8'));
|
|
51
|
+
return !!(m && m.localOnly);
|
|
52
|
+
} catch { return false; }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Persist whether this device is in local-only mode, INDEPENDENT of the policy
|
|
56
|
+
// cache, so localLogsOnly() answers correctly even on a cache-miss call. Written
|
|
57
|
+
// on every policy refresh; switching back to cloud sets localOnly:false so cloud
|
|
58
|
+
// POSTs resume.
|
|
59
|
+
function writeLocalMarker(security) {
|
|
60
|
+
try {
|
|
61
|
+
const l = security && security.localLogs;
|
|
62
|
+
const localOnly = !!(l && l.enabled && typeof l.path === 'string' && l.path.trim());
|
|
63
|
+
writeFileSync(join(resolve(homedir(), '.solongate'), '.local-logs-mode.json'), JSON.stringify({ localOnly, ts: Date.now() }));
|
|
64
|
+
} catch {}
|
|
42
65
|
}
|
|
43
66
|
|
|
44
67
|
// Resolve the FOLDER local logs may be written into. It MUST be absolute on
|
|
@@ -49,16 +72,24 @@ function localLogsOnly(security) {
|
|
|
49
72
|
// When the configured path isn't absolute here, fall back to a fixed home folder
|
|
50
73
|
// so entries are never lost and never leak into a project, and record the bad
|
|
51
74
|
// path so the dashboard/user can be told their path isn't valid on this device.
|
|
75
|
+
let _invalidPathNoted = false;
|
|
52
76
|
function resolveLocalLogDir(rawPath) {
|
|
53
77
|
const dir = String(rawPath || '').trim().replace(/[\\/]+$/, '');
|
|
54
78
|
if (!dir) return null;
|
|
55
79
|
if (isAbsolute(dir)) return dir;
|
|
56
80
|
const fallback = resolve(homedir(), '.solongate', 'local-logs');
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
81
|
+
// Non-absolute path (e.g. a Windows path on Linux): fall back. The diagnostic
|
|
82
|
+
// marker is written at most ONCE per process, NOT on every denial — a per-call
|
|
83
|
+
// writeFileSync here widened the window where a concurrent guard process dies
|
|
84
|
+
// before its audit append lands (dropped denials under a simultaneous burst).
|
|
85
|
+
if (!_invalidPathNoted) {
|
|
86
|
+
_invalidPathNoted = true;
|
|
87
|
+
try {
|
|
88
|
+
mkdirSync(resolve(homedir(), '.solongate'), { recursive: true });
|
|
89
|
+
writeFileSync(resolve(homedir(), '.solongate', '.local-logs-invalid-path'),
|
|
90
|
+
JSON.stringify({ configured: dir, fallback, ts: Date.now() }));
|
|
91
|
+
} catch { /* ignore */ }
|
|
92
|
+
}
|
|
62
93
|
return fallback;
|
|
63
94
|
}
|
|
64
95
|
|
|
@@ -279,6 +310,7 @@ async function refreshPolicyCache() {
|
|
|
279
310
|
} catch {}
|
|
280
311
|
// Always advance _ts (success or failure) so the hot path backs off between refreshes.
|
|
281
312
|
try { writeFileSync(cacheFile, JSON.stringify({ _ts: Date.now(), policy, selfProtect, security, hookVersions })); } catch {}
|
|
313
|
+
writeLocalMarker(security);
|
|
282
314
|
} catch {}
|
|
283
315
|
}
|
|
284
316
|
if (REFRESH_MODE) { try { setTimeout(() => { try { process.exit(process.exitCode || 0); } catch {} }, 8000).unref(); } catch {} refreshPolicyCache().finally(() => { process.exitCode = 0; }); }
|
|
@@ -1553,7 +1585,7 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
|
|
|
1553
1585
|
refreshDue = false;
|
|
1554
1586
|
if (cached.policy) dashboardPolicy = cached.policy;
|
|
1555
1587
|
if (typeof cached.selfProtect === 'boolean') selfProtectEnabled = cached.selfProtect;
|
|
1556
|
-
if (cached.security !== undefined) securityCfg = cached.security;
|
|
1588
|
+
if (cached.security !== undefined) { securityCfg = cached.security; writeLocalMarker(securityCfg); }
|
|
1557
1589
|
if (cached.hookVersions) CLOUD_HOOK_VERSIONS = cached.hookVersions;
|
|
1558
1590
|
}
|
|
1559
1591
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.62",
|
|
4
4
|
"description": "AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|