@axonflow/openclaw 0.1.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/CHANGELOG.md +19 -0
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/audit.d.ts +23 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +26 -0
- package/dist/audit.js.map +1 -0
- package/dist/axonflow-client.d.ts +47 -0
- package/dist/axonflow-client.d.ts.map +1 -0
- package/dist/axonflow-client.js +180 -0
- package/dist/axonflow-client.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +56 -0
- package/dist/config.js.map +1 -0
- package/dist/governance.d.ts +40 -0
- package/dist/governance.d.ts.map +1 -0
- package/dist/governance.js +64 -0
- package/dist/governance.js.map +1 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-audit.d.ts +55 -0
- package/dist/llm-audit.d.ts.map +1 -0
- package/dist/llm-audit.js +60 -0
- package/dist/llm-audit.js.map +1 -0
- package/dist/message-guard.d.ts +25 -0
- package/dist/message-guard.d.ts.map +1 -0
- package/dist/message-guard.js +46 -0
- package/dist/message-guard.js.map +1 -0
- package/openclaw.plugin.json +96 -0
- package/package.json +93 -0
- package/policies/README.md +118 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* before_tool_call hook — input governance.
|
|
3
|
+
*
|
|
4
|
+
* Evaluates tool arguments against AxonFlow policies before execution.
|
|
5
|
+
* Can block the call, require human approval, or allow through.
|
|
6
|
+
*/
|
|
7
|
+
import { shouldGovernTool } from "./config.js";
|
|
8
|
+
/** Derive connector_type from tool name for AxonFlow policy evaluation. */
|
|
9
|
+
export function deriveConnectorType(toolName) {
|
|
10
|
+
return `openclaw.${toolName}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create the before_tool_call hook handler.
|
|
14
|
+
*
|
|
15
|
+
* Decision logic:
|
|
16
|
+
* 1. If tool is excluded from governance: allow through (no check)
|
|
17
|
+
* 2. Call mcp_check_input with tool args serialized as JSON
|
|
18
|
+
* 3. If blocked by policy: return { block: true, blockReason }
|
|
19
|
+
* 4. If tool is in highRiskTools AND allowed: return { requireApproval }
|
|
20
|
+
* 5. Otherwise: allow through
|
|
21
|
+
*/
|
|
22
|
+
export function createBeforeToolCallHandler(client, config) {
|
|
23
|
+
return async (event) => {
|
|
24
|
+
if (!shouldGovernTool(event.toolName, config)) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const connectorType = deriveConnectorType(event.toolName);
|
|
28
|
+
const statement = JSON.stringify(event.params);
|
|
29
|
+
let check;
|
|
30
|
+
try {
|
|
31
|
+
check = await client.mcpCheckInput(connectorType, statement, config.defaultOperation ?? "execute");
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (config.onError === "allow") {
|
|
35
|
+
return undefined; // Fail-open: allow tool execution
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
block: true,
|
|
39
|
+
blockReason: `AxonFlow unreachable: ${err instanceof Error ? err.message : "unknown error"}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (!check.allowed) {
|
|
43
|
+
return {
|
|
44
|
+
block: true,
|
|
45
|
+
blockReason: check.block_reason ?? "Blocked by AxonFlow policy",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// High-risk tools get approval even when policy allows
|
|
49
|
+
if (config.highRiskTools &&
|
|
50
|
+
config.highRiskTools.includes(event.toolName)) {
|
|
51
|
+
return {
|
|
52
|
+
requireApproval: {
|
|
53
|
+
title: `AxonFlow: ${event.toolName} requires approval`,
|
|
54
|
+
description: `Tool call governed by AxonFlow. ${check.policies_evaluated} policies evaluated.`,
|
|
55
|
+
severity: "warning",
|
|
56
|
+
timeoutMs: 60_000,
|
|
57
|
+
timeoutBehavior: "deny",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=governance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governance.js","sourceRoot":"","sources":["../src/governance.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAgB/C,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,OAAO,YAAY,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAsB,EACtB,MAA4B;IAE5B,OAAO,KAAK,EAAE,KAKb,EAA6C,EAAE;QAC9C,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;YAC9C,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,MAAM,CAAC,aAAa,CAChC,aAAa,EACb,SAAS,EACT,MAAM,CAAC,gBAAgB,IAAI,SAAS,CACrC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;gBAC/B,OAAO,SAAS,CAAC,CAAC,kCAAkC;YACtD,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,IAAI;gBACX,WAAW,EAAE,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;aAC7F,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;gBACL,KAAK,EAAE,IAAI;gBACX,WAAW,EAAE,KAAK,CAAC,YAAY,IAAI,4BAA4B;aAChE,CAAC;QACJ,CAAC;QAED,uDAAuD;QACvD,IACE,MAAM,CAAC,aAAa;YACpB,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC7C,CAAC;YACD,OAAO;gBACL,eAAe,EAAE;oBACf,KAAK,EAAE,aAAa,KAAK,CAAC,QAAQ,oBAAoB;oBACtD,WAAW,EAAE,mCAAmC,KAAK,CAAC,kBAAkB,sBAAsB;oBAC9F,QAAQ,EAAE,SAAS;oBACnB,SAAS,EAAE,MAAM;oBACjB,eAAe,EAAE,MAAM;iBACxB;aACF,CAAC;QACJ,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AxonFlow Governance Plugin for OpenClaw
|
|
3
|
+
*
|
|
4
|
+
* Adds centralized policy enforcement, PII detection, and audit trails
|
|
5
|
+
* to OpenClaw tool execution. Works with all OpenClaw tools: built-in,
|
|
6
|
+
* plugin-provided, and MCP-backed.
|
|
7
|
+
*
|
|
8
|
+
* Install:
|
|
9
|
+
* openclaw plugins install @axonflow/openclaw
|
|
10
|
+
*
|
|
11
|
+
* Configure in your OpenClaw config:
|
|
12
|
+
* plugins:
|
|
13
|
+
* @axonflow/openclaw:
|
|
14
|
+
* endpoint: http://localhost:8080
|
|
15
|
+
* clientId: your-client-id
|
|
16
|
+
* clientSecret: your-secret
|
|
17
|
+
* highRiskTools:
|
|
18
|
+
* - web_fetch
|
|
19
|
+
* - message
|
|
20
|
+
*
|
|
21
|
+
* What this plugin does (5 hooks):
|
|
22
|
+
* 1. before_tool_call: evaluates tool arguments against AxonFlow policies
|
|
23
|
+
* 2. after_tool_call: logs tool execution to AxonFlow's audit trail
|
|
24
|
+
* 3. message_sending: scans outbound messages, cancels or redacts PII
|
|
25
|
+
* 4. llm_input: records prompt, model, provider to audit trail
|
|
26
|
+
* 5. llm_output: records response, token usage, latency to audit trail
|
|
27
|
+
*
|
|
28
|
+
* Note: tool_result_persist (output scanning) is not registered because
|
|
29
|
+
* OpenClaw's hook is sync-only and cannot make async HTTP calls to AxonFlow.
|
|
30
|
+
* Outbound messages ARE scanned via message_sending. See upstream issue
|
|
31
|
+
* for async hook support.
|
|
32
|
+
*/
|
|
33
|
+
export { AxonFlowClient } from "./axonflow-client.js";
|
|
34
|
+
export type { AxonFlowPluginConfig } from "./config.js";
|
|
35
|
+
export { resolveConfig, shouldGovernTool } from "./config.js";
|
|
36
|
+
export { deriveConnectorType } from "./governance.js";
|
|
37
|
+
/**
|
|
38
|
+
* Plugin registration function.
|
|
39
|
+
*
|
|
40
|
+
* Called by OpenClaw when the plugin is loaded. Reads configuration,
|
|
41
|
+
* creates the AxonFlow client, and registers five governance/audit hooks.
|
|
42
|
+
*
|
|
43
|
+
* Compatible with OpenClaw's `definePluginEntry` or direct registration:
|
|
44
|
+
*
|
|
45
|
+
* // With definePluginEntry:
|
|
46
|
+
* export default definePluginEntry({
|
|
47
|
+
* id: "axonflow-governance",
|
|
48
|
+
* register: registerAxonFlowGovernance,
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* // Or direct:
|
|
52
|
+
* api.registerHook("before_tool_call", handler);
|
|
53
|
+
*/
|
|
54
|
+
export declare function registerAxonFlowGovernance(api: {
|
|
55
|
+
pluginConfig?: Record<string, unknown>;
|
|
56
|
+
logger: {
|
|
57
|
+
info: (msg: string) => void;
|
|
58
|
+
error: (msg: string) => void;
|
|
59
|
+
};
|
|
60
|
+
on: (hookName: string, handler: (...args: any[]) => any, opts?: {
|
|
61
|
+
priority?: number;
|
|
62
|
+
}) => void;
|
|
63
|
+
}): void;
|
|
64
|
+
/**
|
|
65
|
+
* Default export for OpenClaw plugin loader.
|
|
66
|
+
*
|
|
67
|
+
* OpenClaw expects extensions to export a default object with `id`, `name`,
|
|
68
|
+
* and `register` function. This is the entry point when installed via
|
|
69
|
+
* `openclaw plugins install @axonflow/openclaw`.
|
|
70
|
+
*/
|
|
71
|
+
declare const _default: {
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
description: string;
|
|
75
|
+
register: typeof registerAxonFlowGovernance;
|
|
76
|
+
};
|
|
77
|
+
export default _default;
|
|
78
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAUH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,MAAM,EAAE;QAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;IACtE,EAAE,EAAE,CACF,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAChC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KACzB,IAAI,CAAC;CACX,GAAG,IAAI,CA4BP;AAED;;;;;;GAMG;;;;;;;AACH,wBAKE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AxonFlow Governance Plugin for OpenClaw
|
|
3
|
+
*
|
|
4
|
+
* Adds centralized policy enforcement, PII detection, and audit trails
|
|
5
|
+
* to OpenClaw tool execution. Works with all OpenClaw tools: built-in,
|
|
6
|
+
* plugin-provided, and MCP-backed.
|
|
7
|
+
*
|
|
8
|
+
* Install:
|
|
9
|
+
* openclaw plugins install @axonflow/openclaw
|
|
10
|
+
*
|
|
11
|
+
* Configure in your OpenClaw config:
|
|
12
|
+
* plugins:
|
|
13
|
+
* @axonflow/openclaw:
|
|
14
|
+
* endpoint: http://localhost:8080
|
|
15
|
+
* clientId: your-client-id
|
|
16
|
+
* clientSecret: your-secret
|
|
17
|
+
* highRiskTools:
|
|
18
|
+
* - web_fetch
|
|
19
|
+
* - message
|
|
20
|
+
*
|
|
21
|
+
* What this plugin does (5 hooks):
|
|
22
|
+
* 1. before_tool_call: evaluates tool arguments against AxonFlow policies
|
|
23
|
+
* 2. after_tool_call: logs tool execution to AxonFlow's audit trail
|
|
24
|
+
* 3. message_sending: scans outbound messages, cancels or redacts PII
|
|
25
|
+
* 4. llm_input: records prompt, model, provider to audit trail
|
|
26
|
+
* 5. llm_output: records response, token usage, latency to audit trail
|
|
27
|
+
*
|
|
28
|
+
* Note: tool_result_persist (output scanning) is not registered because
|
|
29
|
+
* OpenClaw's hook is sync-only and cannot make async HTTP calls to AxonFlow.
|
|
30
|
+
* Outbound messages ARE scanned via message_sending. See upstream issue
|
|
31
|
+
* for async hook support.
|
|
32
|
+
*/
|
|
33
|
+
import { AxonFlowClient } from "./axonflow-client.js";
|
|
34
|
+
import { resolveConfig } from "./config.js";
|
|
35
|
+
import { createBeforeToolCallHandler } from "./governance.js";
|
|
36
|
+
import { createAfterToolCallHandler } from "./audit.js";
|
|
37
|
+
import { createMessageSendingHandler } from "./message-guard.js";
|
|
38
|
+
import { createLlmInputHandler, createLlmOutputHandler } from "./llm-audit.js";
|
|
39
|
+
// Re-export for external consumers
|
|
40
|
+
export { AxonFlowClient } from "./axonflow-client.js";
|
|
41
|
+
export { resolveConfig, shouldGovernTool } from "./config.js";
|
|
42
|
+
export { deriveConnectorType } from "./governance.js";
|
|
43
|
+
/**
|
|
44
|
+
* Plugin registration function.
|
|
45
|
+
*
|
|
46
|
+
* Called by OpenClaw when the plugin is loaded. Reads configuration,
|
|
47
|
+
* creates the AxonFlow client, and registers five governance/audit hooks.
|
|
48
|
+
*
|
|
49
|
+
* Compatible with OpenClaw's `definePluginEntry` or direct registration:
|
|
50
|
+
*
|
|
51
|
+
* // With definePluginEntry:
|
|
52
|
+
* export default definePluginEntry({
|
|
53
|
+
* id: "axonflow-governance",
|
|
54
|
+
* register: registerAxonFlowGovernance,
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // Or direct:
|
|
58
|
+
* api.registerHook("before_tool_call", handler);
|
|
59
|
+
*/
|
|
60
|
+
export function registerAxonFlowGovernance(api) {
|
|
61
|
+
const config = resolveConfig(api.pluginConfig);
|
|
62
|
+
const client = new AxonFlowClient(config);
|
|
63
|
+
api.logger.info(`AxonFlow governance active: endpoint=${config.endpoint}, ` +
|
|
64
|
+
`highRiskTools=[${(config.highRiskTools ?? []).join(",")}]`);
|
|
65
|
+
// Hook 1: Input governance (before tool execution)
|
|
66
|
+
const beforeToolCall = createBeforeToolCallHandler(client, config);
|
|
67
|
+
api.on("before_tool_call", beforeToolCall, { priority: 10 });
|
|
68
|
+
// Hook 2: Audit logging (after tool execution)
|
|
69
|
+
const afterToolCall = createAfterToolCallHandler(client, config);
|
|
70
|
+
api.on("after_tool_call", afterToolCall, { priority: 90 });
|
|
71
|
+
// Hook 3: Outbound message governance (before message reaches user)
|
|
72
|
+
const messageSending = createMessageSendingHandler(client, config);
|
|
73
|
+
api.on("message_sending", messageSending, { priority: 10 });
|
|
74
|
+
// Hook 4-5: LLM call audit (observe-only, cannot block/modify)
|
|
75
|
+
const llmCallState = new Map();
|
|
76
|
+
const llmInput = createLlmInputHandler(client, config, llmCallState);
|
|
77
|
+
api.on("llm_input", llmInput, { priority: 90 });
|
|
78
|
+
const llmOutput = createLlmOutputHandler(client, config, llmCallState);
|
|
79
|
+
api.on("llm_output", llmOutput, { priority: 90 });
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Default export for OpenClaw plugin loader.
|
|
83
|
+
*
|
|
84
|
+
* OpenClaw expects extensions to export a default object with `id`, `name`,
|
|
85
|
+
* and `register` function. This is the entry point when installed via
|
|
86
|
+
* `openclaw plugins install @axonflow/openclaw`.
|
|
87
|
+
*/
|
|
88
|
+
export default {
|
|
89
|
+
id: "axonflow-governance",
|
|
90
|
+
name: "AxonFlow Governance",
|
|
91
|
+
description: "Policy enforcement for tool inputs, PII scanning on outbound messages, and audit trails for OpenClaw",
|
|
92
|
+
register: registerAxonFlowGovernance,
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE/E,mCAAmC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,0BAA0B,CAAC,GAQ1C;IACC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IAE1C,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,wCAAwC,MAAM,CAAC,QAAQ,IAAI;QACzD,kBAAkB,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAC9D,CAAC;IAEF,mDAAmD;IACnD,MAAM,cAAc,GAAG,2BAA2B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnE,GAAG,CAAC,EAAE,CAAC,kBAAkB,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAE7D,+CAA+C;IAC/C,MAAM,aAAa,GAAG,0BAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjE,GAAG,CAAC,EAAE,CAAC,iBAAiB,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAE3D,oEAAoE;IACpE,MAAM,cAAc,GAAG,2BAA2B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnE,GAAG,CAAC,EAAE,CAAC,iBAAiB,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAE5D,+DAA+D;IAC/D,MAAM,YAAY,GAAG,IAAI,GAAG,EAAgF,CAAC;IAC7G,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACrE,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAEhD,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACvE,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,eAAe;IACb,EAAE,EAAE,qBAAqB;IACzB,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,sGAAsG;IACnH,QAAQ,EAAE,0BAA0B;CACrC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* llm_input and llm_output hooks — LLM call audit logging.
|
|
3
|
+
*
|
|
4
|
+
* Records what the LLM sees (prompt, model, provider) and produces
|
|
5
|
+
* (response, token usage) to AxonFlow's audit trail. These hooks are
|
|
6
|
+
* observe-only (cannot block or modify), so they provide audit
|
|
7
|
+
* evidence, not governance.
|
|
8
|
+
*/
|
|
9
|
+
import type { AxonFlowClient } from "./axonflow-client.js";
|
|
10
|
+
import type { AxonFlowPluginConfig } from "./config.js";
|
|
11
|
+
/** Shared state for correlating llm_input with llm_output. */
|
|
12
|
+
interface LLMCallState {
|
|
13
|
+
provider: string;
|
|
14
|
+
model: string;
|
|
15
|
+
prompt: string;
|
|
16
|
+
startMs: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create the llm_input hook handler.
|
|
20
|
+
*
|
|
21
|
+
* Records the prompt, model, and provider at the start of each LLM call.
|
|
22
|
+
* Stores state by runId for correlation with the llm_output handler.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createLlmInputHandler(_client: AxonFlowClient, _config: AxonFlowPluginConfig, callState: Map<string, LLMCallState>): (event: {
|
|
25
|
+
runId: string;
|
|
26
|
+
sessionId: string;
|
|
27
|
+
provider: string;
|
|
28
|
+
model: string;
|
|
29
|
+
systemPrompt?: string;
|
|
30
|
+
prompt: string;
|
|
31
|
+
historyMessages: unknown[];
|
|
32
|
+
imagesCount: number;
|
|
33
|
+
}) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Create the llm_output hook handler.
|
|
36
|
+
*
|
|
37
|
+
* Correlates with the stored llm_input state and sends a complete
|
|
38
|
+
* audit entry to AxonFlow (provider, model, prompt summary, response
|
|
39
|
+
* summary, token usage, latency).
|
|
40
|
+
*/
|
|
41
|
+
export declare function createLlmOutputHandler(client: AxonFlowClient, _config: AxonFlowPluginConfig, callState: Map<string, LLMCallState>): (event: {
|
|
42
|
+
runId: string;
|
|
43
|
+
sessionId: string;
|
|
44
|
+
provider: string;
|
|
45
|
+
model: string;
|
|
46
|
+
assistantTexts: string[];
|
|
47
|
+
lastAssistant?: unknown;
|
|
48
|
+
usage?: {
|
|
49
|
+
input?: number;
|
|
50
|
+
output?: number;
|
|
51
|
+
total?: number;
|
|
52
|
+
};
|
|
53
|
+
}) => Promise<void>;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=llm-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-audit.d.ts","sourceRoot":"","sources":["../src/llm-audit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,8DAA8D;AAC9D,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,IAE5B,OAAO;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;CACrB,KAAG,IAAI,CAmBT;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,oBAAoB,EAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,IAEtB,OAAO;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,KAAG,OAAO,CAAC,IAAI,CAAC,CAwBlB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* llm_input and llm_output hooks — LLM call audit logging.
|
|
3
|
+
*
|
|
4
|
+
* Records what the LLM sees (prompt, model, provider) and produces
|
|
5
|
+
* (response, token usage) to AxonFlow's audit trail. These hooks are
|
|
6
|
+
* observe-only (cannot block or modify), so they provide audit
|
|
7
|
+
* evidence, not governance.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Create the llm_input hook handler.
|
|
11
|
+
*
|
|
12
|
+
* Records the prompt, model, and provider at the start of each LLM call.
|
|
13
|
+
* Stores state by runId for correlation with the llm_output handler.
|
|
14
|
+
*/
|
|
15
|
+
export function createLlmInputHandler(_client, _config, callState) {
|
|
16
|
+
return (event) => {
|
|
17
|
+
callState.set(event.runId, {
|
|
18
|
+
provider: event.provider,
|
|
19
|
+
model: event.model,
|
|
20
|
+
prompt: event.prompt.slice(0, 500),
|
|
21
|
+
startMs: Date.now(),
|
|
22
|
+
});
|
|
23
|
+
// Prevent unbounded growth: evict entries older than 5 minutes.
|
|
24
|
+
// Handles cases where llm_input fires without a matching llm_output
|
|
25
|
+
// (LLM errors, timeouts, network failures).
|
|
26
|
+
const MAX_AGE_MS = 5 * 60 * 1000;
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
for (const [key, val] of callState) {
|
|
29
|
+
if (now - val.startMs > MAX_AGE_MS) {
|
|
30
|
+
callState.delete(key);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create the llm_output hook handler.
|
|
37
|
+
*
|
|
38
|
+
* Correlates with the stored llm_input state and sends a complete
|
|
39
|
+
* audit entry to AxonFlow (provider, model, prompt summary, response
|
|
40
|
+
* summary, token usage, latency).
|
|
41
|
+
*/
|
|
42
|
+
export function createLlmOutputHandler(client, _config, callState) {
|
|
43
|
+
return async (event) => {
|
|
44
|
+
const inputState = callState.get(event.runId);
|
|
45
|
+
callState.delete(event.runId);
|
|
46
|
+
const responseSummary = event.assistantTexts.join(" ").slice(0, 200);
|
|
47
|
+
const latencyMs = inputState ? Date.now() - inputState.startMs : 0;
|
|
48
|
+
try {
|
|
49
|
+
await client.auditLLMCall(inputState?.provider ?? event.provider, inputState?.model ?? event.model, inputState?.prompt ?? "", responseSummary, {
|
|
50
|
+
prompt_tokens: event.usage?.input ?? 0,
|
|
51
|
+
completion_tokens: event.usage?.output ?? 0,
|
|
52
|
+
total_tokens: event.usage?.total ?? 0,
|
|
53
|
+
}, latencyMs);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Audit failures are non-fatal
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=llm-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-audit.js","sourceRoot":"","sources":["../src/llm-audit.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAuB,EACvB,OAA6B,EAC7B,SAAoC;IAEpC,OAAO,CAAC,KASP,EAAQ,EAAE;QACT,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE;YACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YAClC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;SACpB,CAAC,CAAC;QAEH,gEAAgE;QAChE,oEAAoE;QACpE,4CAA4C;QAC5C,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;YACnC,IAAI,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC;gBACnC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAsB,EACtB,OAA6B,EAC7B,SAAoC;IAEpC,OAAO,KAAK,EAAE,KAYb,EAAiB,EAAE;QAClB,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE9B,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,YAAY,CACvB,UAAU,EAAE,QAAQ,IAAI,KAAK,CAAC,QAAQ,EACtC,UAAU,EAAE,KAAK,IAAI,KAAK,CAAC,KAAK,EAChC,UAAU,EAAE,MAAM,IAAI,EAAE,EACxB,eAAe,EACf;gBACE,aAAa,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC;gBACtC,iBAAiB,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;gBAC3C,YAAY,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC;aACtC,EACD,SAAS,CACV,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* message_sending hook — outbound message governance.
|
|
3
|
+
*
|
|
4
|
+
* Scans messages before they reach the user's channel (Telegram,
|
|
5
|
+
* Discord, Slack, WhatsApp). Can cancel messages containing PII/secrets
|
|
6
|
+
* or redact sensitive content.
|
|
7
|
+
*/
|
|
8
|
+
import type { AxonFlowClient } from "./axonflow-client.js";
|
|
9
|
+
import type { AxonFlowPluginConfig } from "./config.js";
|
|
10
|
+
/**
|
|
11
|
+
* Create the message_sending hook handler.
|
|
12
|
+
*
|
|
13
|
+
* Evaluates outbound message content against AxonFlow output policies.
|
|
14
|
+
* Can cancel (prevent sending) or redact (modify content) before delivery.
|
|
15
|
+
* Respects config.onError for fail-open/fail-closed behavior.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createMessageSendingHandler(client: AxonFlowClient, config: AxonFlowPluginConfig): (event: {
|
|
18
|
+
to: string;
|
|
19
|
+
content: string;
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
}) => Promise<{
|
|
22
|
+
content?: string;
|
|
23
|
+
cancel?: boolean;
|
|
24
|
+
} | undefined>;
|
|
25
|
+
//# sourceMappingURL=message-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-guard.d.ts","sourceRoot":"","sources":["../src/message-guard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,oBAAoB,IAEd,OAAO;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,KAAG,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAoChE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* message_sending hook — outbound message governance.
|
|
3
|
+
*
|
|
4
|
+
* Scans messages before they reach the user's channel (Telegram,
|
|
5
|
+
* Discord, Slack, WhatsApp). Can cancel messages containing PII/secrets
|
|
6
|
+
* or redact sensitive content.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Create the message_sending hook handler.
|
|
10
|
+
*
|
|
11
|
+
* Evaluates outbound message content against AxonFlow output policies.
|
|
12
|
+
* Can cancel (prevent sending) or redact (modify content) before delivery.
|
|
13
|
+
* Respects config.onError for fail-open/fail-closed behavior.
|
|
14
|
+
*/
|
|
15
|
+
export function createMessageSendingHandler(client, config) {
|
|
16
|
+
return async (event) => {
|
|
17
|
+
if (!event.content) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
let check;
|
|
21
|
+
try {
|
|
22
|
+
check = await client.mcpCheckOutput("openclaw.message_sending", event.content);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
if (config.onError === "allow") {
|
|
26
|
+
return undefined; // Fail-open: allow message through ungoverned
|
|
27
|
+
}
|
|
28
|
+
// Fail-closed: cancel the message rather than send ungoverned
|
|
29
|
+
return { cancel: true };
|
|
30
|
+
}
|
|
31
|
+
if (!check.allowed) {
|
|
32
|
+
return {
|
|
33
|
+
cancel: true,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (check.redacted_data != null) {
|
|
37
|
+
return {
|
|
38
|
+
content: typeof check.redacted_data === "string"
|
|
39
|
+
? check.redacted_data
|
|
40
|
+
: JSON.stringify(check.redacted_data),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=message-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-guard.js","sourceRoot":"","sources":["../src/message-guard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAsB,EACtB,MAA4B;IAE5B,OAAO,KAAK,EAAE,KAIb,EAA+D,EAAE;QAChE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,KAAK,CAAC;QACV,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,MAAM,CAAC,cAAc,CACjC,0BAA0B,EAC1B,KAAK,CAAC,OAAO,CACd,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;gBAC/B,OAAO,SAAS,CAAC,CAAC,8CAA8C;YAClE,CAAC;YACD,8DAA8D;YAC9D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;gBACL,MAAM,EAAE,IAAI;aACb,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EACL,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ;oBACrC,CAAC,CAAC,KAAK,CAAC,aAAa;oBACrB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC;aAC1C,CAAC;QACJ,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "axonflow-governance",
|
|
3
|
+
"uiHints": {
|
|
4
|
+
"endpoint": {
|
|
5
|
+
"label": "AxonFlow Endpoint",
|
|
6
|
+
"placeholder": "http://localhost:8080",
|
|
7
|
+
"help": "URL of your AxonFlow agent gateway"
|
|
8
|
+
},
|
|
9
|
+
"clientId": {
|
|
10
|
+
"label": "Client ID",
|
|
11
|
+
"placeholder": "your-client-id",
|
|
12
|
+
"help": "AxonFlow authentication client ID"
|
|
13
|
+
},
|
|
14
|
+
"clientSecret": {
|
|
15
|
+
"label": "Client Secret",
|
|
16
|
+
"sensitive": true,
|
|
17
|
+
"placeholder": "your-secret",
|
|
18
|
+
"help": "AxonFlow authentication client secret"
|
|
19
|
+
},
|
|
20
|
+
"highRiskTools": {
|
|
21
|
+
"label": "High-Risk Tools",
|
|
22
|
+
"placeholder": "web_fetch, message",
|
|
23
|
+
"help": "Comma-separated tool names requiring human approval even when policy allows"
|
|
24
|
+
},
|
|
25
|
+
"governedTools": {
|
|
26
|
+
"label": "Governed Tools",
|
|
27
|
+
"placeholder": "(empty = all tools)",
|
|
28
|
+
"help": "Only govern these tools. Empty means all tools are governed.",
|
|
29
|
+
"advanced": true
|
|
30
|
+
},
|
|
31
|
+
"excludedTools": {
|
|
32
|
+
"label": "Excluded Tools",
|
|
33
|
+
"placeholder": "(empty = none excluded)",
|
|
34
|
+
"help": "Exclude these tools from governance. Takes precedence over governedTools.",
|
|
35
|
+
"advanced": true
|
|
36
|
+
},
|
|
37
|
+
"defaultOperation": {
|
|
38
|
+
"label": "Default Operation",
|
|
39
|
+
"placeholder": "execute",
|
|
40
|
+
"help": "Operation type for mcp_check_input: 'execute' (default) or 'query' for read-only tools",
|
|
41
|
+
"advanced": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"configSchema": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"properties": {
|
|
48
|
+
"endpoint": {
|
|
49
|
+
"type": "string"
|
|
50
|
+
},
|
|
51
|
+
"clientId": {
|
|
52
|
+
"type": "string"
|
|
53
|
+
},
|
|
54
|
+
"clientSecret": {
|
|
55
|
+
"type": "string"
|
|
56
|
+
},
|
|
57
|
+
"highRiskTools": {
|
|
58
|
+
"type": "array",
|
|
59
|
+
"items": {
|
|
60
|
+
"type": "string"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"governedTools": {
|
|
64
|
+
"type": "array",
|
|
65
|
+
"items": {
|
|
66
|
+
"type": "string"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"excludedTools": {
|
|
70
|
+
"type": "array",
|
|
71
|
+
"items": {
|
|
72
|
+
"type": "string"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"defaultOperation": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"enum": [
|
|
78
|
+
"execute",
|
|
79
|
+
"query"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
"onError": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"enum": [
|
|
85
|
+
"block",
|
|
86
|
+
"allow"
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"required": [
|
|
91
|
+
"endpoint",
|
|
92
|
+
"clientId",
|
|
93
|
+
"clientSecret"
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@axonflow/openclaw",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Policy enforcement, approval gates, and audit trails for OpenClaw — govern tool inputs before execution, scan outbound messages for PII/secrets, and record agent activity for review and compliance",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"policies",
|
|
17
|
+
"README.md",
|
|
18
|
+
"CHANGELOG.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"openclaw.plugin.json"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"prebuild": "npm run clean",
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"lint": "eslint src/ tests/",
|
|
27
|
+
"test": "jest",
|
|
28
|
+
"test:coverage": "jest --coverage",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"axonflow",
|
|
33
|
+
"openclaw",
|
|
34
|
+
"openclaw-security",
|
|
35
|
+
"openclaw-plugin",
|
|
36
|
+
"ai-agent-security",
|
|
37
|
+
"ai-safety",
|
|
38
|
+
"governance",
|
|
39
|
+
"policy-enforcement",
|
|
40
|
+
"pii-detection",
|
|
41
|
+
"pii-redaction",
|
|
42
|
+
"data-exfiltration",
|
|
43
|
+
"prompt-injection",
|
|
44
|
+
"reverse-shell",
|
|
45
|
+
"credential-detection",
|
|
46
|
+
"audit-logging",
|
|
47
|
+
"audit-trail",
|
|
48
|
+
"tool-governance",
|
|
49
|
+
"supply-chain-security",
|
|
50
|
+
"compliance",
|
|
51
|
+
"ssrf-protection"
|
|
52
|
+
],
|
|
53
|
+
"author": "AxonFlow Team <team@getaxonflow.com>",
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/getaxonflow/axonflow-openclaw-plugin.git"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://docs.getaxonflow.com/docs/integration/openclaw/",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/getaxonflow/axonflow-openclaw-plugin/issues"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"@axonflow/sdk": ">=4.3.0",
|
|
65
|
+
"openclaw": ">=1.0.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/jest": "^29.5.0",
|
|
69
|
+
"@types/node": "^20.0.0",
|
|
70
|
+
"eslint": "^9.0.0",
|
|
71
|
+
"jest": "^29.7.0",
|
|
72
|
+
"ts-jest": "^29.1.0",
|
|
73
|
+
"typescript": "^5.4.0",
|
|
74
|
+
"typescript-eslint": "^8.58.0"
|
|
75
|
+
},
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public"
|
|
78
|
+
},
|
|
79
|
+
"peerDependenciesMeta": {
|
|
80
|
+
"@axonflow/sdk": {
|
|
81
|
+
"optional": true
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"openclaw": {
|
|
85
|
+
"extensions": [
|
|
86
|
+
"./dist/index.js"
|
|
87
|
+
],
|
|
88
|
+
"compat": {
|
|
89
|
+
"pluginApi": ">=2026.3.22",
|
|
90
|
+
"minGatewayVersion": "2026.3.22"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|