@solongate/proxy 0.81.65 → 0.81.67
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 +1 -1
- package/dist/tui/index.js +1 -1
- package/hooks/.solongate/.eval-ring.jsonl +9 -0
- package/hooks/.solongate/.last-deny +1 -1
- package/hooks/.solongate/.last-eval +1 -1
- package/hooks/.solongate/.last-tool-call +1 -1
- package/hooks/guard.bundled.mjs +51 -1
- package/hooks/guard.mjs +49 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10233,7 +10233,7 @@ function SettingsPanel({
|
|
|
10233
10233
|
const id = editor.id;
|
|
10234
10234
|
setEditor(null);
|
|
10235
10235
|
if (id) run12("alert updated", () => api.settings.updateAlert(id, body), alertQ.reload);
|
|
10236
|
-
else run12(`${editor.channel} alert added`, () => api.settings.createAlert({ name: "
|
|
10236
|
+
else run12(`${editor.channel} alert added`, () => api.settings.createAlert({ name: "SolonGate alert", ...body }), alertQ.reload);
|
|
10237
10237
|
};
|
|
10238
10238
|
const activate = (r) => {
|
|
10239
10239
|
if (r.kind === "acct") {
|
package/dist/tui/index.js
CHANGED
|
@@ -3360,7 +3360,7 @@ function SettingsPanel({
|
|
|
3360
3360
|
const id = editor.id;
|
|
3361
3361
|
setEditor(null);
|
|
3362
3362
|
if (id) run("alert updated", () => api.settings.updateAlert(id, body), alertQ.reload);
|
|
3363
|
-
else run(`${editor.channel} alert added`, () => api.settings.createAlert({ name: "
|
|
3363
|
+
else run(`${editor.channel} alert added`, () => api.settings.createAlert({ name: "SolonGate alert", ...body }), alertQ.reload);
|
|
3364
3364
|
};
|
|
3365
3365
|
const activate = (r) => {
|
|
3366
3366
|
if (r.kind === "acct") {
|
|
@@ -60,3 +60,12 @@
|
|
|
60
60
|
{"ms":3,"ts":1784374848281,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
61
61
|
{"ms":4,"ts":1784375224287,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
62
62
|
{"ms":5,"ts":1784375813890,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
63
|
+
{"ms":3,"ts":1784376258704,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
64
|
+
{"ms":6,"ts":1784376281596,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
65
|
+
{"ms":6,"ts":1784376313566,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
66
|
+
{"ms":6,"ts":1784376391108,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
67
|
+
{"ms":5,"ts":1784376414971,"tool":"Write","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
68
|
+
{"ms":3,"ts":1784376423302,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
69
|
+
{"ms":2,"ts":1784376491365,"tool":"Bash","session":"t2"}
|
|
70
|
+
{"ms":3,"ts":1784376536945,"tool":"Bash","session":"t2"}
|
|
71
|
+
{"ms":6,"ts":1784376555716,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"tool":"Bash","ts":
|
|
1
|
+
{"tool":"Bash","ts":1784376536900}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"ms":
|
|
1
|
+
{"ms":6,"ts":1784376555716,"tool":"Bash","session":"f5933c65-c315-4440-9afb-7136fce6b695"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1784376536991
|
package/hooks/guard.bundled.mjs
CHANGED
|
@@ -6536,7 +6536,7 @@ 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 = 40;
|
|
6540
6540
|
function localLogsOnly(security) {
|
|
6541
6541
|
if (security && typeof security === "object") {
|
|
6542
6542
|
const l = security.localLogs;
|
|
@@ -7746,6 +7746,56 @@ if (!REFRESH_MODE) {
|
|
|
7746
7746
|
};
|
|
7747
7747
|
const args = data.tool_input;
|
|
7748
7748
|
const toolName = data.tool_name || "";
|
|
7749
|
+
try {
|
|
7750
|
+
const _ak = (AGENT_ID || "default").replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7751
|
+
const _cf = join(resolve(homedir(), ".solongate"), ".policy-cache-" + _ak + ".json");
|
|
7752
|
+
let _selfProt = true, _sec = null, _cacheOk = false;
|
|
7753
|
+
try {
|
|
7754
|
+
const _c = JSON.parse(readFileSync(_cf, "utf-8"));
|
|
7755
|
+
_cacheOk = true;
|
|
7756
|
+
if (_c && typeof _c.selfProtect === "boolean")
|
|
7757
|
+
_selfProt = _c.selfProtect;
|
|
7758
|
+
if (_c && _c.security !== void 0)
|
|
7759
|
+
_sec = _c.security;
|
|
7760
|
+
} catch {
|
|
7761
|
+
}
|
|
7762
|
+
const _tr = _cacheOk && _selfProt ? tamperCheck(toolName, args) : null;
|
|
7763
|
+
if (_tr) {
|
|
7764
|
+
const _logEntry = {
|
|
7765
|
+
tool: toolName,
|
|
7766
|
+
arguments: args,
|
|
7767
|
+
decision: "DENY",
|
|
7768
|
+
reason: _tr,
|
|
7769
|
+
permission: guessPermission(toolName),
|
|
7770
|
+
source: `${AGENT_TYPE}-guard`,
|
|
7771
|
+
agent_id: AGENT_TYPE,
|
|
7772
|
+
agent_name: AGENT_NAME,
|
|
7773
|
+
session_id: data.session_id || "",
|
|
7774
|
+
evaluation_time_ms: Date.now() - _evalStart
|
|
7775
|
+
};
|
|
7776
|
+
try {
|
|
7777
|
+
writeLocalLog(_sec, { ts: (/* @__PURE__ */ new Date()).toISOString(), ..._logEntry });
|
|
7778
|
+
} catch {
|
|
7779
|
+
}
|
|
7780
|
+
try {
|
|
7781
|
+
if (!localLogsOnly(_sec))
|
|
7782
|
+
await fetch(API_URL + "/api/v1/audit-logs", {
|
|
7783
|
+
method: "POST",
|
|
7784
|
+
headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
|
|
7785
|
+
body: JSON.stringify(_logEntry),
|
|
7786
|
+
signal: AbortSignal.timeout(3e3)
|
|
7787
|
+
});
|
|
7788
|
+
} catch {
|
|
7789
|
+
}
|
|
7790
|
+
process.stderr.write(`[SolonGate ROUTE] BLACK (block)
|
|
7791
|
+
`);
|
|
7792
|
+
writeDenyFlag(toolName);
|
|
7793
|
+
blockTool(_tr);
|
|
7794
|
+
}
|
|
7795
|
+
} catch (_e) {
|
|
7796
|
+
if (_e === SG_DONE)
|
|
7797
|
+
throw _e;
|
|
7798
|
+
}
|
|
7749
7799
|
const hookCwd = data.cwd || process.cwd();
|
|
7750
7800
|
let policy;
|
|
7751
7801
|
let selfProtectEnabled = true;
|
package/hooks/guard.mjs
CHANGED
|
@@ -32,7 +32,7 @@ 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 = 40;
|
|
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.
|
|
@@ -1562,6 +1562,54 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
|
|
|
1562
1562
|
const args = data.tool_input;
|
|
1563
1563
|
const toolName = data.tool_name || '';
|
|
1564
1564
|
|
|
1565
|
+
// ── FAST tamper path (hook v40) ───────────────────────────────────────
|
|
1566
|
+
// Tamper protection is independent of the cloud policy, so decide it BEFORE
|
|
1567
|
+
// the slow policy resolution (cache read + WASM + background refresh). That
|
|
1568
|
+
// slow work made the earliest guard processes in a concurrent denial burst
|
|
1569
|
+
// exceed Claude Code's PreToolUse hook timeout and get SIGKILLed mid-write,
|
|
1570
|
+
// dropping the local log. Here we cheap-read the cache for selfProtect +
|
|
1571
|
+
// localLogs config and, on a tamper hit, log + block IMMEDIATELY — no WASM,
|
|
1572
|
+
// no refresh — so the process is fast and never killed. Falls through
|
|
1573
|
+
// untouched when there is no tamper hit.
|
|
1574
|
+
try {
|
|
1575
|
+
const _ak = (AGENT_ID || 'default').replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
1576
|
+
const _cf = join(resolve(homedir(), '.solongate'), '.policy-cache-' + _ak + '.json');
|
|
1577
|
+
let _selfProt = true, _sec = null, _cacheOk = false;
|
|
1578
|
+
try {
|
|
1579
|
+
const _c = JSON.parse(readFileSync(_cf, 'utf-8'));
|
|
1580
|
+
_cacheOk = true;
|
|
1581
|
+
if (_c && typeof _c.selfProtect === 'boolean') _selfProt = _c.selfProtect;
|
|
1582
|
+
if (_c && _c.security !== undefined) _sec = _c.security;
|
|
1583
|
+
} catch {}
|
|
1584
|
+
// Only fast-path when we actually read the cache (so _sec is the real
|
|
1585
|
+
// localLogs config). On a cache miss, fall through to the full flow, which
|
|
1586
|
+
// resolves the policy properly and still blocks tamper.
|
|
1587
|
+
const _tr = (_cacheOk && _selfProt) ? tamperCheck(toolName, args) : null;
|
|
1588
|
+
if (_tr) {
|
|
1589
|
+
const _logEntry = {
|
|
1590
|
+
tool: toolName, arguments: args,
|
|
1591
|
+
decision: 'DENY', reason: _tr,
|
|
1592
|
+
permission: guessPermission(toolName),
|
|
1593
|
+
source: `${AGENT_TYPE}-guard`,
|
|
1594
|
+
agent_id: AGENT_TYPE, agent_name: AGENT_NAME,
|
|
1595
|
+
session_id: data.session_id || '',
|
|
1596
|
+
evaluation_time_ms: Date.now() - _evalStart,
|
|
1597
|
+
};
|
|
1598
|
+
try { writeLocalLog(_sec, { ts: new Date().toISOString(), ..._logEntry }); } catch {}
|
|
1599
|
+
try {
|
|
1600
|
+
if (!localLogsOnly(_sec)) await fetch(API_URL + '/api/v1/audit-logs', {
|
|
1601
|
+
method: 'POST',
|
|
1602
|
+
headers: { 'Content-Type': 'application/json', ...AUTH_HEADERS },
|
|
1603
|
+
body: JSON.stringify(_logEntry),
|
|
1604
|
+
signal: AbortSignal.timeout(3000),
|
|
1605
|
+
});
|
|
1606
|
+
} catch {}
|
|
1607
|
+
process.stderr.write(`[SolonGate ROUTE] BLACK (block)\n`);
|
|
1608
|
+
writeDenyFlag(toolName);
|
|
1609
|
+
blockTool(_tr); // throws SG_DONE — skips the slow policy path entirely
|
|
1610
|
+
}
|
|
1611
|
+
} catch (_e) { if (_e === SG_DONE) throw _e; /* else: fall through to full flow */ }
|
|
1612
|
+
|
|
1565
1613
|
// (self-protection + PI hook layers removed per project decision)
|
|
1566
1614
|
|
|
1567
1615
|
// Load policy. Priority:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.67",
|
|
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": {
|