COURT_FETCH_SHARED_SECRET + LEGAL_CHAT_SHARED_SECRET migrated to Infisical nautilus:/legal-ai (2026-06-07). Updated the pm2 config comments: the stale "migrate to Infisical once the MCP server is back" TODO is now done; local env files remain the runtime source, Infisical is the SoT/record. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
75 lines
2.7 KiB
JavaScript
75 lines
2.7 KiB
JavaScript
/**
|
|
* pm2 ecosystem entry for legal-chat-service — the host-side SSE bridge
|
|
* to ``claude`` CLI that powers the /training chat tab.
|
|
*
|
|
* Security: the service spawns the claude CLI on behalf of any caller
|
|
* that hits /chat/start. claude tools include Bash, Read, Edit — so an
|
|
* unauthenticated request to /chat/start is effectively RCE-equivalent.
|
|
* Two defenses, both required:
|
|
* 1. Bind to 10.0.1.1 (docker0 bridge gateway) — only host + containers
|
|
* on docker bridges can reach the socket; nothing outside the host.
|
|
* 2. Bearer token auth — secret loaded from /home/chaim/.legal-chat-service.env
|
|
* (chmod 600) and mirrored in Coolify as LEGAL_CHAT_SHARED_SECRET.
|
|
* The service refuses to start without the secret set.
|
|
*
|
|
* Why pm2:
|
|
* - Auto-restart if the process dies (claude CLI subprocess failures
|
|
* should never leave the service in a half-dead state).
|
|
* - Log rotation matches paperclip's behavior so the chair sees
|
|
* consistent log paths under ~/.pm2/logs/.
|
|
*
|
|
* Install (once):
|
|
* pm2 start /home/chaim/legal-ai/scripts/legal-chat-service.config.cjs
|
|
* pm2 save
|
|
*
|
|
* Smoke test:
|
|
* curl http://10.0.1.1:8770/health
|
|
* # → {"ok":true,"service":"legal-chat-service"}
|
|
*
|
|
* Update:
|
|
* pm2 restart legal-chat-service --update-env
|
|
*
|
|
* Stop:
|
|
* pm2 stop legal-chat-service
|
|
*/
|
|
const fs = require("fs");
|
|
|
|
// Load LEGAL_CHAT_SHARED_SECRET from a chmod 600 file off the repo.
|
|
// The same value is mirrored in Coolify as the LEGAL_CHAT_SHARED_SECRET
|
|
// env var so the FastAPI proxy sends a matching Authorization header.
|
|
// SoT in Infisical: nautilus:/legal-ai/LEGAL_CHAT_SHARED_SECRET (migrated
|
|
// 2026-06-07). This local file remains the runtime source; rotate in both.
|
|
const ENV_FILE = "/home/chaim/.legal-chat-service.env";
|
|
const env = {
|
|
HOME: "/home/chaim",
|
|
PATH: "/home/chaim/.local/bin:/usr/local/bin:/usr/bin:/bin",
|
|
PYTHONUNBUFFERED: "1",
|
|
};
|
|
try {
|
|
const text = fs.readFileSync(ENV_FILE, "utf8");
|
|
for (const line of text.split("\n")) {
|
|
if (!line || line.trim().startsWith("#")) continue;
|
|
const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*?)\s*$/);
|
|
if (m) env[m[1]] = m[2];
|
|
}
|
|
} catch (e) {
|
|
console.error(`legal-chat-service: failed to load ${ENV_FILE}: ${e.message}`);
|
|
console.error("Service will refuse to start without LEGAL_CHAT_SHARED_SECRET.");
|
|
}
|
|
|
|
module.exports = {
|
|
apps: [
|
|
{
|
|
name: "legal-chat-service",
|
|
cwd: "/home/chaim/legal-ai/mcp-server",
|
|
script: "/home/chaim/legal-ai/mcp-server/.venv/bin/python",
|
|
args: "-m legal_mcp.chat_service.server --port 8770 --host 10.0.1.1",
|
|
env,
|
|
restart_delay: 5000,
|
|
max_restarts: 10,
|
|
autorestart: true,
|
|
max_memory_restart: "500M",
|
|
},
|
|
],
|
|
};
|