UNPKG

@openguardrails/moltguard

Version:

AI agent security plugin for OpenClaw: prompt injection detection, PII sanitization, and monitoring dashboard

206 lines (193 loc) 8.45 kB
export const id = 280; export const ids = [280]; export const modules = { /***/ 5280: /***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ detectionRouter: () => (/* binding */ detectionRouter) /* harmony export */ }); /* harmony import */ var express__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(316); /* harmony import */ var _og_db__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6020); /* harmony import */ var _services_core_client_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6808); var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_og_db__WEBPACK_IMPORTED_MODULE_1__, _services_core_client_js__WEBPACK_IMPORTED_MODULE_2__]); ([_og_db__WEBPACK_IMPORTED_MODULE_1__, _services_core_client_js__WEBPACK_IMPORTED_MODULE_2__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); const scanners = (0,_og_db__WEBPACK_IMPORTED_MODULE_1__/* .scannerQueries */ .nk)(_og_db__WEBPACK_IMPORTED_MODULE_1__.db); const policies = (0,_og_db__WEBPACK_IMPORTED_MODULE_1__/* .policyQueries */ .Lz)(_og_db__WEBPACK_IMPORTED_MODULE_1__.db); const usage = (0,_og_db__WEBPACK_IMPORTED_MODULE_1__/* .usageQueries */ .gB)(_og_db__WEBPACK_IMPORTED_MODULE_1__.db); const detectionResults = (0,_og_db__WEBPACK_IMPORTED_MODULE_1__/* .detectionResultQueries */ .xd)(_og_db__WEBPACK_IMPORTED_MODULE_1__.db); const settings = (0,_og_db__WEBPACK_IMPORTED_MODULE_1__/* .settingsQueries */ .sz)(_og_db__WEBPACK_IMPORTED_MODULE_1__.db); const detectionRouter = (0,express__WEBPACK_IMPORTED_MODULE_0__.Router)(); /** * POST /api/detect * Detection proxy endpoint. * Flow: * 1. Check core key is configured * 2. Get scanner config * 3. Call core /v1/detect * 4. Evaluate policies * 5. Record usage + detection result * 6. Return response */ detectionRouter.post("/", async (req, res, next) => { try { const tenantId = res.locals.tenantId; // 1. Check core key const coreKey = await settings.get("og_core_key"); if (!coreKey) { res.status(503).json({ success: false, error: "core key not configured. Go to Settings to add your key.", }); return; } // 2. Get scanner config const allScanners = await scanners.getAll(tenantId); const coreScanners = allScanners.map((s) => ({ scannerId: s.scannerId, name: s.name, description: s.description, isEnabled: s.isEnabled, })); // Validate request body const { messages, format, role, agentId } = req.body; if (!messages || !Array.isArray(messages) || messages.length === 0) { res.status(400).json({ success: false, error: "messages array is required and must not be empty" }); return; } // 3. Call core const coreResult = await (0,_services_core_client_js__WEBPACK_IMPORTED_MODULE_2__/* .callCoreDetect */ .l)(messages, coreScanners, { format, role }); // 4. Evaluate policies let policyAction = null; if (!coreResult.safe) { const enabledPolicies = await policies.getEnabled(tenantId); for (const policy of enabledPolicies) { const policyScannerIds = policy.scannerIds; const matchesCategory = coreResult.categories.some((c) => policyScannerIds.includes(c)); if (matchesCategory && coreResult.sensitivity_score >= policy.sensitivityThreshold) { policyAction = policy.action; break; } } } // 5. Record usage + detection result await usage.log({ agentId: agentId || null, endpoint: "/api/detect", statusCode: 200, responseSafe: coreResult.safe, categories: coreResult.categories, latencyMs: coreResult.latency_ms, requestId: coreResult.request_id, tenantId, }); await detectionResults.create({ agentId: agentId || null, safe: coreResult.safe, categories: coreResult.categories, sensitivityScore: coreResult.sensitivity_score, findings: coreResult.findings, latencyMs: coreResult.latency_ms, requestId: coreResult.request_id, tenantId, }); // 6. Return response with policy action const response = { ...coreResult, ...(policyAction && { policy_action: policyAction }), }; if (policyAction === "block") { res.status(403).json({ success: true, data: response, blocked: true }); return; } res.json({ success: true, data: response }); } catch (err) { if (err instanceof Error && (err.message.includes("ECONNREFUSED") || err.message.includes("fetch failed"))) { res.status(503).json({ success: false, error: "Detection service is temporarily unavailable. Please try again later." }); return; } next(err); } }); //# sourceMappingURL=detection.js.map __webpack_async_result__(); } catch(e) { __webpack_async_result__(e); } }); /***/ }), /***/ 6808: /***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ l: () => (/* binding */ callCoreDetect) /* harmony export */ }); /* unused harmony export checkCoreHealth */ /* harmony import */ var _og_db__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6020); /* harmony import */ var _runtime_config_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(824); var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_og_db__WEBPACK_IMPORTED_MODULE_0__]); _og_db__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; const settings = (0,_og_db__WEBPACK_IMPORTED_MODULE_0__/* .settingsQueries */ .sz)(_og_db__WEBPACK_IMPORTED_MODULE_0__.db); /** Get core URL from settings or env */ async function getCoreUrl() { return (await settings.get("og_core_url")) || (0,_runtime_config_js__WEBPACK_IMPORTED_MODULE_1__/* .getEnvCoreUrl */ .i)(); } /** Get core key from settings */ async function getCoreKey() { return (await settings.get("og_core_key")) || ""; } /** * Call core detection API. * Uses core key from settings for authentication. */ async function callCoreDetect(messages, scanners, options) { const coreUrl = await getCoreUrl(); const coreKey = await getCoreKey(); const body = { messages, scanners, format: options?.format, role: options?.role, }; const headers = { "Content-Type": "application/json", }; if (coreKey) { headers["Authorization"] = `Bearer ${coreKey}`; } const res = await fetch(`${coreUrl}/v1/detect`, { method: "POST", headers, body: JSON.stringify(body), }); if (!res.ok) { const text = await res.text(); throw new Error(`core returned ${res.status}: ${text}`); } const json = await res.json(); if (!json.success) { throw new Error(`core error: ${json.error}`); } return json.data; } /** Check core health with timeout */ async function checkCoreHealth() { try { const coreUrl = await getCoreUrl(); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout const res = await fetch(`${coreUrl}/health`, { signal: controller.signal, }); clearTimeout(timeoutId); const json = await res.json(); return json.status === "ok"; } catch { return false; } } //# sourceMappingURL=core-client.js.map __webpack_async_result__(); } catch(e) { __webpack_async_result__(e); } }); /***/ }) }; //# sourceMappingURL=280.index.js.map