openclaw-air-trust 0.2.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/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # openclaw-air-trust
2
+
3
+ **The EU AI Act compliance plugin for OpenClaw** — tamper-evident audit trails, consent gating, data tokenization, and prompt injection detection for autonomous AI agents.
4
+
5
+ [![npm](https://img.shields.io/npm/v/openclaw-air-trust)](https://www.npmjs.com/package/openclaw-air-trust)
6
+ [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
+
8
+ ## Why This Exists
9
+
10
+ OpenClaw agents can read your email, execute shell commands, send messages, and manage files — autonomously. When something goes wrong, there's no tamper-evident record of what happened, no approval gate for destructive actions, and no protection against prompt injection attacks.
11
+
12
+ This plugin fixes that. EU AI Act enforcement begins **August 2026**. This is the compliance layer.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install openclaw-air-trust
18
+ ```
19
+
20
+ Then add to your OpenClaw config:
21
+
22
+ ```json
23
+ {
24
+ "plugins": ["openclaw-air-trust"]
25
+ }
26
+ ```
27
+
28
+ ## What It Does
29
+
30
+ | Capability | What It Does | EU AI Act Article |
31
+ |---|---|---|
32
+ | **Audit Ledger** | HMAC-SHA256 tamper-evident chain of every action | Article 12 (Record-Keeping) |
33
+ | **Consent Gate** | Blocks destructive tools until user approves | Article 14 (Human Oversight) |
34
+ | **Data Vault** | Tokenizes API keys, PII, credentials before they reach the LLM | Article 10 (Data Governance) |
35
+ | **Injection Detector** | Scores inbound messages for 15+ prompt injection patterns | Article 15 (Cybersecurity) |
36
+ | **Risk Classifier** | Classifies every tool by risk level (CRITICAL/HIGH/MEDIUM/LOW) | Article 9 (Risk Management) |
37
+ | **Compliance Scanner** | Checks agent code against all 6 EU AI Act articles | Articles 9-15 |
38
+
39
+ ## Plugin Tools
40
+
41
+ Once installed, these tools are available to your OpenClaw agent:
42
+
43
+ | Tool | Description |
44
+ |---|---|
45
+ | `air_audit_status` | Get audit chain length, validity, and time range |
46
+ | `air_verify_chain` | Verify tamper-evident chain integrity |
47
+ | `air_scan_injection` | Scan text for prompt injection patterns |
48
+ | `air_classify_risk` | Classify a tool by EU AI Act risk level |
49
+ | `air_export_audit` | Export the full audit chain as JSON |
50
+ | `air_compliance_check` | Run EU AI Act compliance check on code |
51
+
52
+ ## How It Works
53
+
54
+ ### Audit Ledger (Article 12)
55
+
56
+ Every tool call, LLM interaction, consent decision, and injection detection gets appended to a tamper-evident chain:
57
+
58
+ ```
59
+ Entry 1 → hash₁ ──┐
60
+ Entry 2 → hash₂ (prevHash = hash₁) ──┐
61
+ Entry 3 → hash₃ (prevHash = hash₂) ──┐
62
+ ```
63
+
64
+ Each entry is signed with HMAC-SHA256. Modifying any record breaks the entire chain downstream.
65
+
66
+ ### Consent Gate (Article 14)
67
+
68
+ When the agent tries to call a destructive tool, the consent gate intercepts and sends an approval request. Risk classification is built-in: critical (code execution), high (file writes, deploys), medium (network/email), low (reads).
69
+
70
+ ### Data Vault (Article 10)
71
+
72
+ Before tool arguments or context reaches the LLM, the vault scans for sensitive patterns and replaces them with opaque tokens. 14 built-in patterns: OpenAI/Anthropic/AWS/GitHub/Stripe keys, emails, phone numbers, SSNs, credit cards, connection strings, bearer tokens, private keys, and password assignments.
73
+
74
+ ### Injection Detector (Article 15)
75
+
76
+ Scans inbound messages for 15+ prompt injection patterns: role override, identity hijacking, privilege escalation, safety bypass, jailbreak, data exfiltration, encoding evasion, and more. Three sensitivity levels (low/medium/high) control which patterns are active.
77
+
78
+ ## Configuration
79
+
80
+ ```json
81
+ {
82
+ "plugins": {
83
+ "openclaw-air-trust": {
84
+ "enabled": true,
85
+ "gatewayUrl": "https://your-air-gateway.example.com",
86
+ "gatewayKey": "your-api-key",
87
+ "consentGateEnabled": true,
88
+ "consentAlwaysRequire": "exec,spawn,shell,deploy",
89
+ "consentRiskThreshold": "high",
90
+ "consentTimeoutMs": 30000,
91
+ "injectionEnabled": true,
92
+ "injectionSensitivity": "medium",
93
+ "injectionBlockThreshold": 0.8,
94
+ "vaultEnabled": true
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## Standalone Usage
101
+
102
+ You can also use the components directly without OpenClaw:
103
+
104
+ ```typescript
105
+ import { createAirTrustPlugin } from 'openclaw-air-trust/standalone';
106
+
107
+ const trust = createAirTrustPlugin({
108
+ enabled: true,
109
+ consentGate: { enabled: true, alwaysRequire: ['exec', 'deploy'] },
110
+ injectionDetection: { enabled: true, sensitivity: 'medium', blockThreshold: 0.8 },
111
+ });
112
+ ```
113
+
114
+ ## Part of the AIR Blackbox Ecosystem
115
+
116
+ | Package | What It Does |
117
+ |---|---|
118
+ | [air-blackbox-mcp](https://github.com/airblackbox/air-blackbox-mcp) | MCP server for Claude Desktop — 10 compliance tools |
119
+ | [air-langchain-trust](https://pypi.org/project/air-langchain-trust/) | Python trust layer for LangChain agents |
120
+ | [air-crewai-trust](https://pypi.org/project/air-crewai-trust/) | Python trust layer for CrewAI agents |
121
+ | [air-autogen-trust](https://pypi.org/project/air-autogen-trust/) | Python trust layer for AutoGen agents |
122
+ | **openclaw-air-trust** | ← You are here |
123
+
124
+ Learn more at [airblackbox.ai](https://airblackbox.ai)
125
+
126
+ ## Development
127
+
128
+ ```bash
129
+ git clone https://github.com/airblackbox/openclaw-air-trust.git
130
+ cd openclaw-air-trust
131
+ npm install
132
+ npm run build
133
+ npm test
134
+ ```
135
+
136
+ ## License
137
+
138
+ Apache 2.0
@@ -0,0 +1,56 @@
1
+ /**
2
+ * openclaw-air-trust — Audit Ledger
3
+ *
4
+ * Tamper-evident action log using HMAC-SHA256 chaining.
5
+ * Each entry includes the hash of the previous entry, creating
6
+ * a blockchain-style chain. Modifying any entry breaks the chain.
7
+ *
8
+ * Supports local persistence and non-blocking forwarding to
9
+ * the AIR Blackbox gateway.
10
+ */
11
+ import { AuditEntry, AuditLedgerConfig, ChainVerification, RiskLevel } from './types';
12
+ export declare class AuditLedger {
13
+ private entries;
14
+ private secret;
15
+ private lastHash;
16
+ private sequence;
17
+ private config;
18
+ private gatewayUrl?;
19
+ private gatewayKey?;
20
+ constructor(config: AuditLedgerConfig, gatewayUrl?: string, gatewayKey?: string);
21
+ /**
22
+ * Append an action to the audit chain.
23
+ * Returns the signed entry.
24
+ */
25
+ append(params: {
26
+ action: string;
27
+ toolName?: string;
28
+ riskLevel: RiskLevel;
29
+ consentRequired: boolean;
30
+ consentGranted?: boolean;
31
+ dataTokenized: boolean;
32
+ injectionDetected: boolean;
33
+ metadata?: Record<string, unknown>;
34
+ }): AuditEntry;
35
+ /**
36
+ * Verify the integrity of the entire chain.
37
+ * Walks entries in order, checking prevHash linkage and HMAC signatures.
38
+ */
39
+ verify(): ChainVerification;
40
+ /** Get the N most recent entries */
41
+ getRecent(n?: number): AuditEntry[];
42
+ /** Export all entries */
43
+ export(): AuditEntry[];
44
+ /** Chain stats */
45
+ stats(): {
46
+ totalEntries: number;
47
+ chainValid: boolean;
48
+ earliest?: string;
49
+ latest?: string;
50
+ };
51
+ private loadChain;
52
+ private saveChain;
53
+ private forwardEntry;
54
+ private ensureDir;
55
+ }
56
+ //# sourceMappingURL=audit-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-ledger.d.ts","sourceRoot":"","sources":["../src/audit-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACV,MAAM,SAAS,CAAC;AAIjB,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAS;gBAG1B,MAAM,EAAE,iBAAiB,EACzB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM;IAoBrB;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,SAAS,CAAC;QACrB,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,aAAa,EAAE,OAAO,CAAC;QACvB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GAAG,UAAU;IA+Dd;;;OAGG;IACH,MAAM,IAAI,iBAAiB;IAmE3B,oCAAoC;IACpC,SAAS,CAAC,CAAC,GAAE,MAAW,GAAG,UAAU,EAAE;IAIvC,yBAAyB;IACzB,MAAM,IAAI,UAAU,EAAE;IAItB,kBAAkB;IAClB,KAAK,IAAI;QACP,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,OAAO,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAYD,OAAO,CAAC,SAAS;IAiBjB,OAAO,CAAC,SAAS;YAWH,YAAY;IAa1B,OAAO,CAAC,SAAS;CAMlB"}
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ /**
3
+ * openclaw-air-trust — Audit Ledger
4
+ *
5
+ * Tamper-evident action log using HMAC-SHA256 chaining.
6
+ * Each entry includes the hash of the previous entry, creating
7
+ * a blockchain-style chain. Modifying any entry breaks the chain.
8
+ *
9
+ * Supports local persistence and non-blocking forwarding to
10
+ * the AIR Blackbox gateway.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.AuditLedger = void 0;
14
+ const crypto_1 = require("crypto");
15
+ const fs_1 = require("fs");
16
+ const path_1 = require("path");
17
+ const GENESIS_HASH = '0000000000000000000000000000000000000000000000000000000000000000';
18
+ class AuditLedger {
19
+ entries = [];
20
+ secret;
21
+ lastHash = GENESIS_HASH;
22
+ sequence = 0;
23
+ config;
24
+ gatewayUrl;
25
+ gatewayKey;
26
+ constructor(config, gatewayUrl, gatewayKey) {
27
+ this.config = config;
28
+ this.gatewayUrl = gatewayUrl;
29
+ this.gatewayKey = gatewayKey;
30
+ // Load or generate HMAC key
31
+ const keyPath = config.localPath.replace(/\.json$/, '') + '.key';
32
+ if ((0, fs_1.existsSync)(keyPath)) {
33
+ this.secret = Buffer.from((0, fs_1.readFileSync)(keyPath, 'utf-8').trim(), 'hex');
34
+ }
35
+ else {
36
+ this.secret = (0, crypto_1.randomBytes)(32);
37
+ this.ensureDir(keyPath);
38
+ (0, fs_1.writeFileSync)(keyPath, this.secret.toString('hex'), { mode: 0o600 });
39
+ }
40
+ // Load existing chain
41
+ this.loadChain();
42
+ }
43
+ /**
44
+ * Append an action to the audit chain.
45
+ * Returns the signed entry.
46
+ */
47
+ append(params) {
48
+ this.sequence++;
49
+ const entry = {
50
+ id: (0, crypto_1.randomUUID)(),
51
+ sequence: this.sequence,
52
+ hash: '', // computed below
53
+ prevHash: this.lastHash,
54
+ signature: '', // computed below
55
+ timestamp: new Date().toISOString(),
56
+ action: params.action,
57
+ toolName: params.toolName,
58
+ riskLevel: params.riskLevel,
59
+ consentRequired: params.consentRequired,
60
+ consentGranted: params.consentGranted,
61
+ dataTokenized: params.dataTokenized,
62
+ injectionDetected: params.injectionDetected,
63
+ metadata: params.metadata ?? {},
64
+ };
65
+ // Compute content hash (everything except hash, signature, prevHash)
66
+ const contentForHash = JSON.stringify({
67
+ id: entry.id,
68
+ sequence: entry.sequence,
69
+ timestamp: entry.timestamp,
70
+ action: entry.action,
71
+ toolName: entry.toolName,
72
+ riskLevel: entry.riskLevel,
73
+ consentRequired: entry.consentRequired,
74
+ consentGranted: entry.consentGranted,
75
+ dataTokenized: entry.dataTokenized,
76
+ injectionDetected: entry.injectionDetected,
77
+ metadata: entry.metadata,
78
+ });
79
+ entry.hash = (0, crypto_1.createHash)('sha256').update(contentForHash).digest('hex');
80
+ // HMAC signature chains this entry to the previous one
81
+ const sigPayload = `${entry.sequence}|${entry.id}|${entry.hash}|${entry.prevHash}`;
82
+ entry.signature = (0, crypto_1.createHmac)('sha256', this.secret)
83
+ .update(sigPayload)
84
+ .digest('hex');
85
+ this.lastHash = entry.hash;
86
+ this.entries.push(entry);
87
+ // Trim if over max
88
+ if (this.config.maxEntries > 0 && this.entries.length > this.config.maxEntries) {
89
+ this.entries = this.entries.slice(-this.config.maxEntries);
90
+ }
91
+ // Persist locally
92
+ this.saveChain();
93
+ // Non-blocking forward to gateway
94
+ if (this.config.forwardToGateway && this.gatewayUrl) {
95
+ this.forwardEntry(entry).catch(() => {
96
+ // Silent fail — gateway forwarding is best-effort
97
+ });
98
+ }
99
+ return entry;
100
+ }
101
+ /**
102
+ * Verify the integrity of the entire chain.
103
+ * Walks entries in order, checking prevHash linkage and HMAC signatures.
104
+ */
105
+ verify() {
106
+ if (this.entries.length === 0) {
107
+ return { valid: true, totalEntries: 0 };
108
+ }
109
+ let expectedPrevHash = GENESIS_HASH;
110
+ for (const entry of this.entries) {
111
+ // Check prevHash linkage
112
+ if (entry.prevHash !== expectedPrevHash) {
113
+ return {
114
+ valid: false,
115
+ totalEntries: this.entries.length,
116
+ brokenAtSequence: entry.sequence,
117
+ brokenAtId: entry.id,
118
+ reason: `prevHash mismatch at sequence ${entry.sequence}`,
119
+ };
120
+ }
121
+ // Recompute content hash
122
+ const contentForHash = JSON.stringify({
123
+ id: entry.id,
124
+ sequence: entry.sequence,
125
+ timestamp: entry.timestamp,
126
+ action: entry.action,
127
+ toolName: entry.toolName,
128
+ riskLevel: entry.riskLevel,
129
+ consentRequired: entry.consentRequired,
130
+ consentGranted: entry.consentGranted,
131
+ dataTokenized: entry.dataTokenized,
132
+ injectionDetected: entry.injectionDetected,
133
+ metadata: entry.metadata,
134
+ });
135
+ const computedHash = (0, crypto_1.createHash)('sha256').update(contentForHash).digest('hex');
136
+ if (entry.hash !== computedHash) {
137
+ return {
138
+ valid: false,
139
+ totalEntries: this.entries.length,
140
+ brokenAtSequence: entry.sequence,
141
+ brokenAtId: entry.id,
142
+ reason: `Content hash mismatch at sequence ${entry.sequence}`,
143
+ };
144
+ }
145
+ // Verify HMAC signature
146
+ const sigPayload = `${entry.sequence}|${entry.id}|${entry.hash}|${entry.prevHash}`;
147
+ const expectedSig = (0, crypto_1.createHmac)('sha256', this.secret)
148
+ .update(sigPayload)
149
+ .digest('hex');
150
+ if (entry.signature !== expectedSig) {
151
+ return {
152
+ valid: false,
153
+ totalEntries: this.entries.length,
154
+ brokenAtSequence: entry.sequence,
155
+ brokenAtId: entry.id,
156
+ reason: `Signature mismatch at sequence ${entry.sequence}`,
157
+ };
158
+ }
159
+ expectedPrevHash = entry.hash;
160
+ }
161
+ return { valid: true, totalEntries: this.entries.length };
162
+ }
163
+ /** Get the N most recent entries */
164
+ getRecent(n = 50) {
165
+ return this.entries.slice(-n);
166
+ }
167
+ /** Export all entries */
168
+ export() {
169
+ return [...this.entries];
170
+ }
171
+ /** Chain stats */
172
+ stats() {
173
+ const verification = this.verify();
174
+ return {
175
+ totalEntries: this.entries.length,
176
+ chainValid: verification.valid,
177
+ earliest: this.entries[0]?.timestamp,
178
+ latest: this.entries[this.entries.length - 1]?.timestamp,
179
+ };
180
+ }
181
+ // ─── Private Methods ────────────────────────────────────────
182
+ loadChain() {
183
+ if ((0, fs_1.existsSync)(this.config.localPath)) {
184
+ try {
185
+ const raw = (0, fs_1.readFileSync)(this.config.localPath, 'utf-8');
186
+ const data = JSON.parse(raw);
187
+ this.entries = data.entries ?? [];
188
+ this.sequence = data.sequence ?? 0;
189
+ this.lastHash = data.lastHash ?? GENESIS_HASH;
190
+ }
191
+ catch {
192
+ // Corrupted file — start fresh
193
+ this.entries = [];
194
+ this.sequence = 0;
195
+ this.lastHash = GENESIS_HASH;
196
+ }
197
+ }
198
+ }
199
+ saveChain() {
200
+ this.ensureDir(this.config.localPath);
201
+ const data = {
202
+ entries: this.entries,
203
+ sequence: this.sequence,
204
+ lastHash: this.lastHash,
205
+ savedAt: new Date().toISOString(),
206
+ };
207
+ (0, fs_1.writeFileSync)(this.config.localPath, JSON.stringify(data, null, 2));
208
+ }
209
+ async forwardEntry(entry) {
210
+ if (!this.gatewayUrl)
211
+ return;
212
+ const url = `${this.gatewayUrl}/v1/audit`;
213
+ await fetch(url, {
214
+ method: 'POST',
215
+ headers: {
216
+ 'Content-Type': 'application/json',
217
+ ...(this.gatewayKey ? { Authorization: `Bearer ${this.gatewayKey}` } : {}),
218
+ },
219
+ body: JSON.stringify(entry),
220
+ });
221
+ }
222
+ ensureDir(filePath) {
223
+ const dir = (0, path_1.dirname)(filePath);
224
+ if (!(0, fs_1.existsSync)(dir)) {
225
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
226
+ }
227
+ }
228
+ }
229
+ exports.AuditLedger = AuditLedger;
230
+ //# sourceMappingURL=audit-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-ledger.js","sourceRoot":"","sources":["../src/audit-ledger.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,mCAAyE;AACzE,2BAAwE;AACxE,+BAA+B;AAQ/B,MAAM,YAAY,GAAG,kEAAkE,CAAC;AAExF,MAAa,WAAW;IACd,OAAO,GAAiB,EAAE,CAAC;IAC3B,MAAM,CAAS;IACf,QAAQ,GAAW,YAAY,CAAC;IAChC,QAAQ,GAAW,CAAC,CAAC;IACrB,MAAM,CAAoB;IAC1B,UAAU,CAAU;IACpB,UAAU,CAAU;IAE5B,YACE,MAAyB,EACzB,UAAmB,EACnB,UAAmB;QAEnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7B,4BAA4B;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC;QACjE,IAAI,IAAA,eAAU,EAAC,OAAO,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAA,iBAAY,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,GAAG,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACxB,IAAA,kBAAa,EAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,MASN;QACC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAEhB,MAAM,KAAK,GAAe;YACxB,EAAE,EAAE,IAAA,mBAAU,GAAE;YAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,EAAE,EAAE,iBAAiB;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,EAAE,EAAE,iBAAiB;YAChC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;YAC3C,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;SAChC,CAAC;QAEF,qEAAqE;QACrE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;YACpC,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEvE,uDAAuD;QACvD,MAAM,UAAU,GAAG,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnF,KAAK,CAAC,SAAS,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;aAChD,MAAM,CAAC,UAAU,CAAC;aAClB,MAAM,CAAC,KAAK,CAAC,CAAC;QAEjB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEzB,mBAAmB;QACnB,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC/E,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7D,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC,SAAS,EAAE,CAAC;QAEjB,kCAAkC;QAClC,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBAClC,kDAAkD;YACpD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;QAC1C,CAAC;QAED,IAAI,gBAAgB,GAAG,YAAY,CAAC;QAEpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,yBAAyB;YACzB,IAAI,KAAK,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAC;gBACxC,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;oBACjC,gBAAgB,EAAE,KAAK,CAAC,QAAQ;oBAChC,UAAU,EAAE,KAAK,CAAC,EAAE;oBACpB,MAAM,EAAE,iCAAiC,KAAK,CAAC,QAAQ,EAAE;iBAC1D,CAAC;YACJ,CAAC;YAED,yBAAyB;YACzB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;gBACpC,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,eAAe,EAAE,KAAK,CAAC,eAAe;gBACtC,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;gBAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAE/E,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;oBACjC,gBAAgB,EAAE,KAAK,CAAC,QAAQ;oBAChC,UAAU,EAAE,KAAK,CAAC,EAAE;oBACpB,MAAM,EAAE,qCAAqC,KAAK,CAAC,QAAQ,EAAE;iBAC9D,CAAC;YACJ,CAAC;YAED,wBAAwB;YACxB,MAAM,UAAU,GAAG,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnF,MAAM,WAAW,GAAG,IAAA,mBAAU,EAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;iBAClD,MAAM,CAAC,UAAU,CAAC;iBAClB,MAAM,CAAC,KAAK,CAAC,CAAC;YAEjB,IAAI,KAAK,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;gBACpC,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;oBACjC,gBAAgB,EAAE,KAAK,CAAC,QAAQ;oBAChC,UAAU,EAAE,KAAK,CAAC,EAAE;oBACpB,MAAM,EAAE,kCAAkC,KAAK,CAAC,QAAQ,EAAE;iBAC3D,CAAC;YACJ,CAAC;YAED,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC;QAChC,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;IAC5D,CAAC;IAED,oCAAoC;IACpC,SAAS,CAAC,IAAY,EAAE;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,yBAAyB;IACzB,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,kBAAkB;IAClB,KAAK;QAMH,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;YACjC,UAAU,EAAE,YAAY,CAAC,KAAK;YAC9B,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS;YACpC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,SAAS;SACzD,CAAC;IACJ,CAAC;IAED,+DAA+D;IAEvD,SAAS;QACf,IAAI,IAAA,eAAU,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBACzD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC7B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;gBAClC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;gBACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;gBAC/B,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;gBAClB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAClB,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG;YACX,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAClC,CAAC;QACF,IAAA,kBAAa,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,KAAiB;QAC1C,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAC7B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,WAAW,CAAC;QAC1C,MAAM,KAAK,CAAC,GAAG,EAAE;YACf,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3E;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC5B,CAAC,CAAC;IACL,CAAC;IAEO,SAAS,CAAC,QAAgB;QAChC,MAAM,GAAG,GAAG,IAAA,cAAO,EAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;YACrB,IAAA,cAAS,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;CACF;AA9PD,kCA8PC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * openclaw-air-trust — Consent Gate
3
+ *
4
+ * Intercepts destructive or sensitive tool calls and holds them
5
+ * pending user approval. Classifies tools by risk level and
6
+ * sends approval requests through OpenClaw's messaging channel.
7
+ *
8
+ * Flow:
9
+ * 1. before_tool_call fires
10
+ * 2. ConsentGate checks if tool requires consent
11
+ * 3. If yes: sends approval message, waits for response
12
+ * 4. If approved: tool executes normally
13
+ * 5. If rejected/timeout: tool call is blocked
14
+ * 6. All decisions are logged to the audit ledger
15
+ */
16
+ import { ConsentGateConfig, ConsentRequest, RiskLevel, ToolCallEvent, ToolCallResult, PluginContext } from './types';
17
+ import { AuditLedger } from './audit-ledger';
18
+ export declare class ConsentGate {
19
+ private config;
20
+ private ledger;
21
+ private pendingRequests;
22
+ constructor(config: ConsentGateConfig, ledger: AuditLedger);
23
+ /**
24
+ * Classify risk level for a tool.
25
+ */
26
+ classifyRisk(toolName: string): RiskLevel;
27
+ /**
28
+ * Check if a tool call requires consent.
29
+ */
30
+ requiresConsent(toolName: string): boolean;
31
+ /**
32
+ * Intercept a tool call. If consent is needed, block until approved.
33
+ * Returns a ToolCallResult indicating whether the call should proceed.
34
+ */
35
+ intercept(event: ToolCallEvent, ctx: PluginContext): Promise<ToolCallResult>;
36
+ /**
37
+ * Handle a user response to a consent request.
38
+ * Call this when the user sends "approve <id>" or "reject <id>".
39
+ */
40
+ handleResponse(consentId: string, approved: boolean): boolean;
41
+ /**
42
+ * Format a human-readable consent message.
43
+ */
44
+ formatConsentMessage(request: ConsentRequest): string;
45
+ private waitForApproval;
46
+ }
47
+ //# sourceMappingURL=consent-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-gate.d.ts","sourceRoot":"","sources":["../src/consent-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,SAAS,EAET,aAAa,EACb,cAAc,EACd,aAAa,EACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAqC7C,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,eAAe,CAGR;gBAEH,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW;IAK1D;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAazC;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAY1C;;;OAGG;IACG,SAAS,CACb,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,cAAc,CAAC;IAwD1B;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO;IAS7D;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM;IAgCrD,OAAO,CAAC,eAAe;CAexB"}