@solongate/proxy 0.58.0 → 0.59.0
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/audit/index.js +0 -0
- package/dist/create.js +0 -0
- package/dist/global-install.js +1 -1
- package/dist/index.js +341 -52
- package/dist/inject.js +0 -0
- package/dist/login.js +5 -39
- package/dist/logs-server.d.ts +1 -0
- package/dist/logs-server.js +174 -0
- package/dist/pull-push.js +0 -0
- package/dist/shield.js +106 -7
- package/hooks/.solongate/.last-deny +1 -0
- package/hooks/.solongate/.last-eval +1 -0
- package/hooks/.solongate/.last-tool-call +1 -0
- package/hooks/audit.mjs +565 -544
- package/hooks/guard.bundled.mjs +21 -2
- package/hooks/guard.mjs +1626 -1604
- package/hooks/shield.mjs +271 -271
- package/hooks/stop.mjs +75 -75
- package/package.json +74 -74
package/hooks/stop.mjs
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* SolonGate Stop Hook (Stop event)
|
|
4
|
-
* Logs a single ALLOW when Claude responds WITHOUT any tool calls.
|
|
5
|
-
* If tool calls were made, audit.mjs already logged them — this hook skips.
|
|
6
|
-
* Auto-installed by: npx @solongate/proxy login
|
|
7
|
-
*/
|
|
8
|
-
import { readFileSync, existsSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
9
|
-
import { resolve, join } from 'node:path';
|
|
10
|
-
|
|
11
|
-
function loadEnvKey(dir) {
|
|
12
|
-
try {
|
|
13
|
-
const envPath = resolve(dir, '.env');
|
|
14
|
-
if (!existsSync(envPath)) return {};
|
|
15
|
-
const lines = readFileSync(envPath, 'utf-8').split('\n');
|
|
16
|
-
const env = {};
|
|
17
|
-
for (const line of lines) {
|
|
18
|
-
const m = line.match(/^([A-Z_]+)=(.*)$/);
|
|
19
|
-
if (m) env[m[1]] = m[2].replace(/^["']|["']$/g, '').trim();
|
|
20
|
-
}
|
|
21
|
-
return env;
|
|
22
|
-
} catch { return {}; }
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const dotenv = loadEnvKey(process.cwd());
|
|
26
|
-
const API_KEY = process.env.SOLONGATE_API_KEY || dotenv.SOLONGATE_API_KEY || '';
|
|
27
|
-
const API_URL = process.env.SOLONGATE_API_URL || dotenv.SOLONGATE_API_URL || 'https://api.solongate.com';
|
|
28
|
-
|
|
29
|
-
// Agent identity from CLI args: node stop.mjs <agent_id> <agent_name>
|
|
30
|
-
const AGENT_ID = process.argv[2] || 'claude-code';
|
|
31
|
-
const AGENT_NAME = process.argv[3] || 'Claude Code';
|
|
32
|
-
|
|
33
|
-
if (!API_KEY || !API_KEY.startsWith('sg_live_')) process.exit(0);
|
|
34
|
-
|
|
35
|
-
// Flag file: audit.mjs writes this when a tool call was logged in this turn.
|
|
36
|
-
// If the flag exists, tool calls were made → skip (already logged).
|
|
37
|
-
// If the flag doesn't exist, no tool calls → log 1 ALLOW for the text response.
|
|
38
|
-
const flagDir = resolve('.solongate');
|
|
39
|
-
const flagFile = join(flagDir, '.last-tool-call');
|
|
40
|
-
|
|
41
|
-
let input = '';
|
|
42
|
-
process.stdin.on('data', c => input += c);
|
|
43
|
-
process.stdin.on('end', async () => {
|
|
44
|
-
try {
|
|
45
|
-
// Check if tool calls were made in this turn
|
|
46
|
-
if (existsSync(flagFile)) {
|
|
47
|
-
// Tool calls happened → audit.mjs already logged them. Clean up flag.
|
|
48
|
-
try { unlinkSync(flagFile); } catch {}
|
|
49
|
-
process.exit(0);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// No tool calls → log 1 ALLOW for the text-only response (fire-and-forget)
|
|
53
|
-
fetch(`${API_URL}/api/v1/audit-logs`, {
|
|
54
|
-
method: 'POST',
|
|
55
|
-
headers: {
|
|
56
|
-
'Authorization': `Bearer ${API_KEY}`,
|
|
57
|
-
'Content-Type': 'application/json',
|
|
58
|
-
},
|
|
59
|
-
body: JSON.stringify({
|
|
60
|
-
tool: '_response',
|
|
61
|
-
arguments: {},
|
|
62
|
-
decision: 'ALLOW',
|
|
63
|
-
reason: 'text response (no tool calls)',
|
|
64
|
-
source: `${AGENT_ID}-hook`,
|
|
65
|
-
evaluationTimeMs: 0,
|
|
66
|
-
agent_id: AGENT_ID,
|
|
67
|
-
agent_name: AGENT_NAME,
|
|
68
|
-
}),
|
|
69
|
-
signal: AbortSignal.timeout(5000),
|
|
70
|
-
}).catch(() => {}).finally(() => process.exit(0));
|
|
71
|
-
setTimeout(() => process.exit(0), 3000);
|
|
72
|
-
} catch {
|
|
73
|
-
process.exit(0);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* SolonGate Stop Hook (Stop event)
|
|
4
|
+
* Logs a single ALLOW when Claude responds WITHOUT any tool calls.
|
|
5
|
+
* If tool calls were made, audit.mjs already logged them — this hook skips.
|
|
6
|
+
* Auto-installed by: npx @solongate/proxy login
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, existsSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
9
|
+
import { resolve, join } from 'node:path';
|
|
10
|
+
|
|
11
|
+
function loadEnvKey(dir) {
|
|
12
|
+
try {
|
|
13
|
+
const envPath = resolve(dir, '.env');
|
|
14
|
+
if (!existsSync(envPath)) return {};
|
|
15
|
+
const lines = readFileSync(envPath, 'utf-8').split('\n');
|
|
16
|
+
const env = {};
|
|
17
|
+
for (const line of lines) {
|
|
18
|
+
const m = line.match(/^([A-Z_]+)=(.*)$/);
|
|
19
|
+
if (m) env[m[1]] = m[2].replace(/^["']|["']$/g, '').trim();
|
|
20
|
+
}
|
|
21
|
+
return env;
|
|
22
|
+
} catch { return {}; }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const dotenv = loadEnvKey(process.cwd());
|
|
26
|
+
const API_KEY = process.env.SOLONGATE_API_KEY || dotenv.SOLONGATE_API_KEY || '';
|
|
27
|
+
const API_URL = process.env.SOLONGATE_API_URL || dotenv.SOLONGATE_API_URL || 'https://api.solongate.com';
|
|
28
|
+
|
|
29
|
+
// Agent identity from CLI args: node stop.mjs <agent_id> <agent_name>
|
|
30
|
+
const AGENT_ID = process.argv[2] || 'claude-code';
|
|
31
|
+
const AGENT_NAME = process.argv[3] || 'Claude Code';
|
|
32
|
+
|
|
33
|
+
if (!API_KEY || !API_KEY.startsWith('sg_live_')) process.exit(0);
|
|
34
|
+
|
|
35
|
+
// Flag file: audit.mjs writes this when a tool call was logged in this turn.
|
|
36
|
+
// If the flag exists, tool calls were made → skip (already logged).
|
|
37
|
+
// If the flag doesn't exist, no tool calls → log 1 ALLOW for the text response.
|
|
38
|
+
const flagDir = resolve('.solongate');
|
|
39
|
+
const flagFile = join(flagDir, '.last-tool-call');
|
|
40
|
+
|
|
41
|
+
let input = '';
|
|
42
|
+
process.stdin.on('data', c => input += c);
|
|
43
|
+
process.stdin.on('end', async () => {
|
|
44
|
+
try {
|
|
45
|
+
// Check if tool calls were made in this turn
|
|
46
|
+
if (existsSync(flagFile)) {
|
|
47
|
+
// Tool calls happened → audit.mjs already logged them. Clean up flag.
|
|
48
|
+
try { unlinkSync(flagFile); } catch {}
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// No tool calls → log 1 ALLOW for the text-only response (fire-and-forget)
|
|
53
|
+
fetch(`${API_URL}/api/v1/audit-logs`, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers: {
|
|
56
|
+
'Authorization': `Bearer ${API_KEY}`,
|
|
57
|
+
'Content-Type': 'application/json',
|
|
58
|
+
},
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
tool: '_response',
|
|
61
|
+
arguments: {},
|
|
62
|
+
decision: 'ALLOW',
|
|
63
|
+
reason: 'text response (no tool calls)',
|
|
64
|
+
source: `${AGENT_ID}-hook`,
|
|
65
|
+
evaluationTimeMs: 0,
|
|
66
|
+
agent_id: AGENT_ID,
|
|
67
|
+
agent_name: AGENT_NAME,
|
|
68
|
+
}),
|
|
69
|
+
signal: AbortSignal.timeout(5000),
|
|
70
|
+
}).catch(() => {}).finally(() => process.exit(0));
|
|
71
|
+
setTimeout(() => process.exit(0), 3000);
|
|
72
|
+
} catch {
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
});
|
package/package.json
CHANGED
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.
|
|
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
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"solongate": "./dist/index.js",
|
|
8
|
-
"solongate-proxy": "./dist/index.js",
|
|
9
|
-
"solongate-audit": "./dist/audit/index.js",
|
|
10
|
-
"proxy": "./dist/index.js"
|
|
11
|
-
},
|
|
12
|
-
"main": "./dist/lib.js",
|
|
13
|
-
"types": "./dist/lib.d.ts",
|
|
14
|
-
"exports": {
|
|
15
|
-
".": {
|
|
16
|
-
"types": "./dist/lib.d.ts",
|
|
17
|
-
"import": "./dist/lib.js"
|
|
18
|
-
},
|
|
19
|
-
"./cli": {
|
|
20
|
-
"types": "./dist/index.d.ts",
|
|
21
|
-
"import": "./dist/index.js"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"files": [
|
|
25
|
-
"dist",
|
|
26
|
-
"hooks",
|
|
27
|
-
"README.md"
|
|
28
|
-
],
|
|
29
|
-
"scripts": {
|
|
30
|
-
"build": "tsup && pnpm build:types && pnpm build:hooks",
|
|
31
|
-
"build:types": "node scripts/build-types.mjs",
|
|
32
|
-
"build:hooks": "node scripts/bundle-hooks.mjs",
|
|
33
|
-
"dev": "tsx src/index.ts",
|
|
34
|
-
"typecheck": "tsc --noEmit",
|
|
35
|
-
"clean": "rm -rf dist .turbo"
|
|
36
|
-
},
|
|
37
|
-
"keywords": [
|
|
38
|
-
"ai-tool-security",
|
|
39
|
-
"ai-tool-proxy",
|
|
40
|
-
"security",
|
|
41
|
-
"proxy",
|
|
42
|
-
"gateway",
|
|
43
|
-
"firewall",
|
|
44
|
-
"ai-security",
|
|
45
|
-
"tool-security",
|
|
46
|
-
"claude",
|
|
47
|
-
"solongate",
|
|
48
|
-
"path-traversal",
|
|
49
|
-
"rate-limiting"
|
|
50
|
-
],
|
|
51
|
-
"author": "SolonGate <hello@solongate.com>",
|
|
52
|
-
"license": "MIT",
|
|
53
|
-
"homepage": "https://solongate.com",
|
|
54
|
-
"repository": {
|
|
55
|
-
"type": "git",
|
|
56
|
-
"url": "https://github.com/solongate/solongate"
|
|
57
|
-
},
|
|
58
|
-
"engines": {
|
|
59
|
-
"node": ">=18.0.0"
|
|
60
|
-
},
|
|
61
|
-
"dependencies": {
|
|
62
|
-
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
63
|
-
"zod": "^3.25.0"
|
|
64
|
-
},
|
|
65
|
-
"devDependencies": {
|
|
66
|
-
"@open-policy-agent/opa-wasm": "^1.10.0",
|
|
67
|
-
"chalk": "^5.3.0",
|
|
68
|
-
"@solongate/tsconfig": "workspace:*",
|
|
69
|
-
"esbuild": "^0.19.12",
|
|
70
|
-
"tsup": "^8.3.0",
|
|
71
|
-
"tsx": "^4.19.0",
|
|
72
|
-
"typescript": "^5.7.0"
|
|
73
|
-
}
|
|
74
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@solongate/proxy",
|
|
3
|
+
"version": "0.59.0",
|
|
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
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"solongate": "./dist/index.js",
|
|
8
|
+
"solongate-proxy": "./dist/index.js",
|
|
9
|
+
"solongate-audit": "./dist/audit/index.js",
|
|
10
|
+
"proxy": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/lib.js",
|
|
13
|
+
"types": "./dist/lib.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/lib.d.ts",
|
|
17
|
+
"import": "./dist/lib.js"
|
|
18
|
+
},
|
|
19
|
+
"./cli": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"hooks",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsup && pnpm build:types && pnpm build:hooks",
|
|
31
|
+
"build:types": "node scripts/build-types.mjs",
|
|
32
|
+
"build:hooks": "node scripts/bundle-hooks.mjs",
|
|
33
|
+
"dev": "tsx src/index.ts",
|
|
34
|
+
"typecheck": "tsc --noEmit",
|
|
35
|
+
"clean": "rm -rf dist .turbo"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"ai-tool-security",
|
|
39
|
+
"ai-tool-proxy",
|
|
40
|
+
"security",
|
|
41
|
+
"proxy",
|
|
42
|
+
"gateway",
|
|
43
|
+
"firewall",
|
|
44
|
+
"ai-security",
|
|
45
|
+
"tool-security",
|
|
46
|
+
"claude",
|
|
47
|
+
"solongate",
|
|
48
|
+
"path-traversal",
|
|
49
|
+
"rate-limiting"
|
|
50
|
+
],
|
|
51
|
+
"author": "SolonGate <hello@solongate.com>",
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"homepage": "https://solongate.com",
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "https://github.com/solongate/solongate"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18.0.0"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
63
|
+
"zod": "^3.25.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@open-policy-agent/opa-wasm": "^1.10.0",
|
|
67
|
+
"chalk": "^5.3.0",
|
|
68
|
+
"@solongate/tsconfig": "workspace:*",
|
|
69
|
+
"esbuild": "^0.19.12",
|
|
70
|
+
"tsup": "^8.3.0",
|
|
71
|
+
"tsx": "^4.19.0",
|
|
72
|
+
"typescript": "^5.7.0"
|
|
73
|
+
}
|
|
74
|
+
}
|