@axonflow/openclaw 0.2.0 → 1.0.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/README.md +35 -16
- package/dist/axonflow-client.d.ts +17 -2
- package/dist/axonflow-client.d.ts.map +1 -1
- package/dist/axonflow-client.js +39 -8
- package/dist/axonflow-client.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -7
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -1
- package/policies/README.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.0] - 2026-04-05
|
|
4
|
+
|
|
5
|
+
### BREAKING CHANGES
|
|
6
|
+
|
|
7
|
+
- **`X-Tenant-ID` header removed.** The plugin no longer sends `X-Tenant-ID`. The server derives tenant from OAuth2 Client Credentials (Basic auth). Requires platform v6.0.0+.
|
|
8
|
+
- **`tenantId` config removed.** Both `clientId` and `clientSecret` default to `"community"` when not configured. The `tenantId` field is removed — tenant is derived server-side.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `searchAuditEvents()` method on `AxonFlowClient` for individual audit event inspection. Enables debugging why something was blocked, generating compliance reports, and answering "what did the agent do in the last hour?"
|
|
13
|
+
- Hardened E2E test suite: 24 tests covering dangerous command blocking (reverse shell, rm -rf, SSRF, path traversal, credential access), PII detection with redaction assertions, and audit search.
|
|
14
|
+
|
|
15
|
+
### Security
|
|
16
|
+
|
|
17
|
+
- Bumped `@anthropic-ai/sdk` transitive dependency from 0.80.0 to 0.82.0 (fixes CVE-2026-34451: memory tool path validation sandbox escape).
|
|
18
|
+
- Replaced polynomial regex in endpoint URL normalization with iterative loop (ReDoS mitigation).
|
|
19
|
+
- Added explicit `permissions: contents: read` to CI workflow (least privilege).
|
|
20
|
+
- Removed hardcoded Base64 auth string from test file (secret scanning false positive).
|
|
21
|
+
|
|
3
22
|
## [0.2.0] - 2026-04-01 (initial public release)
|
|
4
23
|
|
|
5
24
|
### Added
|
package/README.md
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
**Policy enforcement, approval gates, and audit trails for [OpenClaw](https://github.com/openclaw/openclaw).**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Why
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- prevent PII or secrets from being sent to users
|
|
11
|
-
- keep an audit trail of agent activity with policy context
|
|
7
|
+
OpenClaw is widely deployed with [13+ CVEs disclosed in 2026](https://github.com/jgamblin/OpenClawCVEs/) (multiple CVSS 9.8+), [135,000+ publicly exposed instances](https://www.bitsight.com/blog/openclaw-ai-security-risks-exposed-instances), and [1,184 malicious skills](https://cyberpress.org/clawhavoc-poisons-openclaws-clawhub-with-1184-malicious-skills/) poisoned in ClawHub via the ClawHavoc supply chain attack. OpenClaw provides agent runtime and tool execution but no centralized policy enforcement, no PII scanning, and no compliance-grade audit trails.
|
|
8
|
+
|
|
9
|
+
This plugin adds the governance layer. AxonFlow governs, OpenClaw orchestrates. No LLM provider keys needed — OpenClaw handles all LLM calls, AxonFlow only enforces policies and records audit trails. Your data stays on your infrastructure.
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
This plugin is useful when you want to:
|
|
12
|
+
- block dangerous tool calls (reverse shells, SSRF, destructive commands) before they run
|
|
13
|
+
- detect and redact PII and secrets in outbound messages before delivery
|
|
14
|
+
- require human approval for high-risk tools (exec, web_fetch, message)
|
|
15
|
+
- keep a compliance-grade audit trail of every tool call and LLM interaction
|
|
16
|
+
- gain visibility into token usage and LLM activity across agents via audit trails
|
|
14
17
|
|
|
15
18
|
## What It Does
|
|
16
19
|
|
|
@@ -40,6 +43,19 @@ What is not protected yet:
|
|
|
40
43
|
|
|
41
44
|
If OpenClaw adds async support for `tool_result_persist`, AxonFlow can add transcript/result scanning immediately. Upstream issue: [openclaw/openclaw#58558](https://github.com/openclaw/openclaw/issues/58558).
|
|
42
45
|
|
|
46
|
+
## Prerequisites
|
|
47
|
+
|
|
48
|
+
This plugin connects to [AxonFlow](https://github.com/getaxonflow/axonflow), a self-hosted governance platform, for policy evaluation and audit logging. AxonFlow must be running before you use the plugin. Your data stays on your infrastructure.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Start AxonFlow (Docker — runs entirely on your machine)
|
|
52
|
+
git clone https://github.com/getaxonflow/axonflow.git
|
|
53
|
+
cd axonflow
|
|
54
|
+
docker compose up -d
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
See [Getting Started](https://docs.getaxonflow.com/docs/getting-started/) for full setup options.
|
|
58
|
+
|
|
43
59
|
## Install
|
|
44
60
|
|
|
45
61
|
```bash
|
|
@@ -54,8 +70,10 @@ In your OpenClaw config:
|
|
|
54
70
|
plugins:
|
|
55
71
|
@axonflow/openclaw:
|
|
56
72
|
endpoint: http://localhost:8080
|
|
57
|
-
clientId
|
|
58
|
-
|
|
73
|
+
# clientId and clientSecret default to community mode.
|
|
74
|
+
# Set these to your evaluation/enterprise credentials when you have a license.
|
|
75
|
+
# clientId: your-tenant-id
|
|
76
|
+
# clientSecret: your-license-key
|
|
59
77
|
highRiskTools:
|
|
60
78
|
- web_fetch
|
|
61
79
|
- message
|
|
@@ -66,8 +84,14 @@ plugins:
|
|
|
66
84
|
| Option | Required | Default | Description |
|
|
67
85
|
|--------|----------|---------|-------------|
|
|
68
86
|
| `endpoint` | Yes | — | AxonFlow agent gateway URL |
|
|
69
|
-
| `clientId` |
|
|
70
|
-
| `clientSecret` |
|
|
87
|
+
| `clientId` | No | `"community"` | Tenant identity for data isolation. Override for evaluation/enterprise. |
|
|
88
|
+
| `clientSecret` | No | `""` | License key for evaluation/enterprise features. Requires `clientId` to be set. |
|
|
89
|
+
|
|
90
|
+
**Valid configurations:**
|
|
91
|
+
- Both omitted → community mode (`clientId` defaults to `"community"`)
|
|
92
|
+
- `clientId` only → community mode with custom tenant identity
|
|
93
|
+
- Both set → licensed mode (evaluation/enterprise)
|
|
94
|
+
- `clientSecret` only → **error** (licensed mode requires explicit tenant identity to prevent data going to the wrong tenant)
|
|
71
95
|
| `highRiskTools` | No | `[]` | Tools that require human approval even when policy allows |
|
|
72
96
|
| `governedTools` | No | `[]` (all) | Tools to govern. Empty = all tools. |
|
|
73
97
|
| `excludedTools` | No | `[]` | Tools to exclude from governance |
|
|
@@ -135,11 +159,6 @@ Opt out:
|
|
|
135
159
|
|
|
136
160
|
Telemetry is automatically suppressed for localhost/loopback endpoints.
|
|
137
161
|
|
|
138
|
-
## Prerequisites
|
|
139
|
-
|
|
140
|
-
- [AxonFlow](https://github.com/getaxonflow/axonflow) running (Docker or production)
|
|
141
|
-
- OpenClaw 1.0+
|
|
142
|
-
|
|
143
162
|
## Starter Policies
|
|
144
163
|
|
|
145
164
|
See [policies/README.md](./policies/README.md) for recommended policy setup for OpenClaw deployments, including protections against reverse shells, credential exfiltration, SSRF, path traversal, and agent config file poisoning.
|
|
@@ -19,14 +19,13 @@ export interface MCPCheckOutputResponse {
|
|
|
19
19
|
export declare class AxonFlowClient {
|
|
20
20
|
private readonly endpoint;
|
|
21
21
|
private readonly authHeader;
|
|
22
|
-
private readonly tenantId;
|
|
23
22
|
constructor(config: AxonFlowPluginConfig);
|
|
24
23
|
private baseHeaders;
|
|
25
24
|
mcpCheckInput(connectorType: string, statement: string, operation?: string): Promise<MCPCheckInputResponse>;
|
|
26
25
|
mcpCheckOutput(connectorType: string, message: string): Promise<MCPCheckOutputResponse>;
|
|
27
26
|
/**
|
|
28
27
|
* Log a tool execution to the audit trail.
|
|
29
|
-
* Uses POST /api/v1/audit/tool-call (
|
|
28
|
+
* Uses POST /api/v1/audit/tool-call (tenant derived from Basic auth).
|
|
30
29
|
*/
|
|
31
30
|
auditToolCall(toolName: string, params: Record<string, unknown>, result?: unknown, error?: string, durationMs?: number): Promise<void>;
|
|
32
31
|
/**
|
|
@@ -42,6 +41,22 @@ export declare class AxonFlowClient {
|
|
|
42
41
|
completion_tokens: number;
|
|
43
42
|
total_tokens: number;
|
|
44
43
|
}, latencyMs: number): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Search individual audit event records.
|
|
46
|
+
*
|
|
47
|
+
* Returns tool call details, policy evaluations, and timestamps
|
|
48
|
+
* for compliance evidence and debugging.
|
|
49
|
+
*/
|
|
50
|
+
searchAuditEvents(options?: {
|
|
51
|
+
startTime?: string;
|
|
52
|
+
endTime?: string;
|
|
53
|
+
requestType?: string;
|
|
54
|
+
limit?: number;
|
|
55
|
+
}): Promise<{
|
|
56
|
+
entries: unknown[];
|
|
57
|
+
total: number;
|
|
58
|
+
error?: string;
|
|
59
|
+
}>;
|
|
45
60
|
healthCheck(): Promise<boolean>;
|
|
46
61
|
}
|
|
47
62
|
//# sourceMappingURL=axonflow-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axonflow-client.d.ts","sourceRoot":"","sources":["../src/axonflow-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAyBD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;
|
|
1
|
+
{"version":3,"file":"axonflow-client.d.ts","sourceRoot":"","sources":["../src/axonflow-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAyBD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBACxB,MAAM,EAAE,oBAAoB;IAWxC,OAAO,CAAC,WAAW;IASb,aAAa,CACjB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAkB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA2C3B,cAAc,CAClB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,sBAAsB,CAAC;IA2ClC;;;OAGG;IACG,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,CAAC,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAqBhB;;;;;;;OAOG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EACtF,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAoBhB;;;;;OAKG;IACG,iBAAiB,CAAC,OAAO,CAAC,EAAE;QAChC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA2B5D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAQtC"}
|
package/dist/axonflow-client.js
CHANGED
|
@@ -29,21 +29,21 @@ function extractPoliciesEvaluated(data) {
|
|
|
29
29
|
export class AxonFlowClient {
|
|
30
30
|
endpoint;
|
|
31
31
|
authHeader;
|
|
32
|
-
tenantId;
|
|
33
32
|
constructor(config) {
|
|
34
|
-
|
|
33
|
+
// Strip trailing slashes without regex (avoids ReDoS on polynomial patterns)
|
|
34
|
+
let ep = config.endpoint;
|
|
35
|
+
while (ep.endsWith("/"))
|
|
36
|
+
ep = ep.slice(0, -1);
|
|
37
|
+
this.endpoint = ep;
|
|
35
38
|
const credentials = Buffer.from(`${config.clientId}:${config.clientSecret}`).toString("base64");
|
|
36
39
|
this.authHeader = `Basic ${credentials}`;
|
|
37
|
-
// clientId serves as tenantId for single-tenant setups.
|
|
38
|
-
// The Agent proxy normally injects X-Tenant-ID after auth, but
|
|
39
|
-
// direct Orchestrator calls (audit/tool-call) require it explicitly.
|
|
40
|
-
this.tenantId = config.clientId;
|
|
41
40
|
}
|
|
42
41
|
baseHeaders() {
|
|
42
|
+
// Tenant is derived from Basic auth credentials on the server side (RFC 6749).
|
|
43
|
+
// X-Tenant-ID header is no longer sent — server knows tenant from auth.
|
|
43
44
|
return {
|
|
44
45
|
"Content-Type": "application/json",
|
|
45
46
|
Authorization: this.authHeader,
|
|
46
|
-
"X-Tenant-ID": this.tenantId,
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
async mcpCheckInput(connectorType, statement, operation = "execute") {
|
|
@@ -116,7 +116,7 @@ export class AxonFlowClient {
|
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* Log a tool execution to the audit trail.
|
|
119
|
-
* Uses POST /api/v1/audit/tool-call (
|
|
119
|
+
* Uses POST /api/v1/audit/tool-call (tenant derived from Basic auth).
|
|
120
120
|
*/
|
|
121
121
|
async auditToolCall(toolName, params, result, error, durationMs) {
|
|
122
122
|
const url = `${this.endpoint}/api/v1/audit/tool-call`;
|
|
@@ -167,6 +167,37 @@ export class AxonFlowClient {
|
|
|
167
167
|
// Audit failures are non-fatal
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Search individual audit event records.
|
|
172
|
+
*
|
|
173
|
+
* Returns tool call details, policy evaluations, and timestamps
|
|
174
|
+
* for compliance evidence and debugging.
|
|
175
|
+
*/
|
|
176
|
+
async searchAuditEvents(options) {
|
|
177
|
+
const url = `${this.endpoint}/api/v1/audit/search`;
|
|
178
|
+
const now = new Date();
|
|
179
|
+
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
|
|
180
|
+
const body = {
|
|
181
|
+
start_time: options?.startTime ?? oneHourAgo.toISOString(),
|
|
182
|
+
end_time: options?.endTime ?? now.toISOString(),
|
|
183
|
+
limit: Math.min(options?.limit ?? 20, 100),
|
|
184
|
+
...(options?.requestType && { request_type: options.requestType }),
|
|
185
|
+
};
|
|
186
|
+
try {
|
|
187
|
+
const response = await fetch(url, {
|
|
188
|
+
method: "POST",
|
|
189
|
+
headers: this.baseHeaders(),
|
|
190
|
+
body: JSON.stringify(body),
|
|
191
|
+
});
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
return { entries: [], total: 0, error: `HTTP ${response.status}` };
|
|
194
|
+
}
|
|
195
|
+
return (await response.json());
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
return { entries: [], total: 0, error: e instanceof Error ? e.message : "Unknown error" };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
170
201
|
async healthCheck() {
|
|
171
202
|
try {
|
|
172
203
|
const response = await fetch(`${this.endpoint}/health`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axonflow-client.js","sourceRoot":"","sources":["../src/axonflow-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,IAA6B;IAC7D,IAAI,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,QAAQ,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;IACvC,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAC1D,MAAM,EAAE,GAAG,UAAqC,CAAC;QACjD,IAAI,OAAO,EAAE,CAAC,oBAAoB,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjD,OAAO,EAAE,CAAC,oBAAoB,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC;YAC5C,OAAO,EAAE,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC;QACzC,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,OAAO,cAAc;IACR,QAAQ,CAAS;IACjB,UAAU,CAAS;
|
|
1
|
+
{"version":3,"file":"axonflow-client.js","sourceRoot":"","sources":["../src/axonflow-client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
export interface AxonFlowPluginConfig {
|
|
8
8
|
/** AxonFlow agent gateway endpoint (e.g., "http://localhost:8080"). */
|
|
9
9
|
endpoint: string;
|
|
10
|
-
/**
|
|
10
|
+
/** Tenant identity for data isolation. Defaults to "community" for community mode. */
|
|
11
11
|
clientId: string;
|
|
12
|
-
/**
|
|
12
|
+
/** License key for evaluation/enterprise features. Empty for community mode. */
|
|
13
13
|
clientSecret: string;
|
|
14
14
|
/**
|
|
15
15
|
* Tools that require human approval even when AxonFlow allows them.
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,oBAAoB;IACnC,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IAEjB,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,oBAAoB;IACnC,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IAEjB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;IAEjB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B;AAED,kDAAkD;AAClD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACvC,oBAAoB,CAgDtB;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAWT"}
|
package/dist/config.js
CHANGED
|
@@ -13,14 +13,17 @@ export function resolveConfig(raw) {
|
|
|
13
13
|
if (typeof endpoint !== "string" || !endpoint) {
|
|
14
14
|
throw new Error("AxonFlow plugin: 'endpoint' is required (e.g., 'http://localhost:8080')");
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
throw new Error("AxonFlow plugin: 'clientSecret' is
|
|
16
|
+
// Defaults match SDK behavior: community mode works out of the box.
|
|
17
|
+
// Override with your evaluation/enterprise license credentials.
|
|
18
|
+
const rawClientId = typeof raw["clientId"] === "string" ? raw["clientId"] : "";
|
|
19
|
+
const rawClientSecret = typeof raw["clientSecret"] === "string" ? raw["clientSecret"] : "";
|
|
20
|
+
// Reject clientSecret without clientId — licensed mode must specify the tenant
|
|
21
|
+
if (!rawClientId && rawClientSecret) {
|
|
22
|
+
throw new Error("AxonFlow plugin: 'clientId' is required when 'clientSecret' is set. " +
|
|
23
|
+
"Set clientId to your tenant identity (e.g., your deployment's AXONFLOW_CLIENT_ID).");
|
|
23
24
|
}
|
|
25
|
+
const clientId = rawClientId || "community";
|
|
26
|
+
const clientSecret = rawClientSecret;
|
|
24
27
|
return {
|
|
25
28
|
endpoint,
|
|
26
29
|
clientId,
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8CH,kDAAkD;AAClD,MAAM,UAAU,aAAa,CAC3B,GAAwC;IAExC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IACjC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8CH,kDAAkD;AAClD,MAAM,UAAU,aAAa,CAC3B,GAAwC;IAExC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IACjC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IAED,oEAAoE;IACpE,gEAAgE;IAChE,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,MAAM,eAAe,GAAG,OAAO,GAAG,CAAC,cAAc,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3F,+EAA+E;IAC/E,IAAI,CAAC,WAAW,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,sEAAsE;YACtE,oFAAoF,CACrF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,IAAI,WAAW,CAAC;IAC5C,MAAM,YAAY,GAAG,eAAe,CAAC;IAErC,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,YAAY;QACZ,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAChD,CAAC,CAAE,GAAG,CAAC,eAAe,CAAc;YACpC,CAAC,CAAC,EAAE;QACN,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAChD,CAAC,CAAE,GAAG,CAAC,eAAe,CAAc;YACpC,CAAC,CAAC,EAAE;QACN,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAChD,CAAC,CAAE,GAAG,CAAC,eAAe,CAAc;YACpC,CAAC,CAAC,EAAE;QACN,gBAAgB,EACd,OAAO,GAAG,CAAC,kBAAkB,CAAC,KAAK,QAAQ;YACzC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACzB,CAAC,CAAC,SAAS;QACf,OAAO,EACL,GAAG,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;KACjD,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,MAA4B;IAE5B,iCAAiC;IACjC,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,yDAAyD;IACzD,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,OAAO,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IACD,4BAA4B;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* for async hook support.
|
|
32
32
|
*/
|
|
33
33
|
/** Plugin version — update before each release. */
|
|
34
|
-
export declare const VERSION = "0.
|
|
34
|
+
export declare const VERSION = "1.0.0";
|
|
35
35
|
export { AxonFlowClient } from "./axonflow-client.js";
|
|
36
36
|
export type { AxonFlowPluginConfig } from "./config.js";
|
|
37
37
|
export { resolveConfig, shouldGovernTool } from "./config.js";
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ import { createLlmInputHandler, createLlmOutputHandler } from "./llm-audit.js";
|
|
|
39
39
|
import { sendTelemetryPing } from "./telemetry.js";
|
|
40
40
|
import { resetMetrics } from "./metrics.js";
|
|
41
41
|
/** Plugin version — update before each release. */
|
|
42
|
-
export const VERSION = "0.
|
|
42
|
+
export const VERSION = "1.0.0";
|
|
43
43
|
// Re-export for external consumers
|
|
44
44
|
export { AxonFlowClient } from "./axonflow-client.js";
|
|
45
45
|
export { resolveConfig, shouldGovernTool } from "./config.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axonflow/openclaw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
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
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
"compat": {
|
|
90
90
|
"pluginApi": ">=2026.3.22",
|
|
91
91
|
"minGatewayVersion": "2026.3.22"
|
|
92
|
+
},
|
|
93
|
+
"build": {
|
|
94
|
+
"openclawVersion": "2026.3.22",
|
|
95
|
+
"pluginSdkVersion": "2026.3.22"
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
}
|
package/policies/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Default policy configurations for protecting OpenClaw deployments with AxonFlow.
|
|
|
4
4
|
|
|
5
5
|
## Why These Policies Matter
|
|
6
6
|
|
|
7
|
-
As of March 2026, OpenClaw has 135,000+
|
|
7
|
+
As of March 2026, OpenClaw has 500K+ deployed instances (135,000+ publicly exposed), 13+ CVEs disclosed (including CVE-2026-32922 and CVE-2026-32973 at CVSS 9.8), and the ClawHavoc supply chain attack poisoned 1,184 skills in ClawHub. Microsoft recommends: "It is not appropriate to run on a standard personal or enterprise workstation."
|
|
8
8
|
|
|
9
9
|
AxonFlow adds centralized governance at key data boundaries: tool inputs (before execution), outbound messages (before delivery), and LLM calls (audit). Tool result transcript scanning is pending async hook support in OpenClaw.
|
|
10
10
|
|