Skip to content

Commit 4347fa2

Browse files
author
jovanSAPFIONEER
committed
Fix Snyk CVE-547: replace hardcoded salt with random salt, add agent tokens to internal writes
1 parent 2f50cf4 commit 4347fa2

File tree

3 files changed

+161
-49
lines changed

3 files changed

+161
-49
lines changed

index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ class TaskDecomposer {
931931
// Cache successful results
932932
if (result.success) {
933933
const cacheKey = `task:${task.agentType}:${this.hashPayload(task.taskPayload)}`;
934-
this.blackboard.write(cacheKey, result.result, context.agentId, 3600); // 1 hour TTL
934+
this.blackboard.write(cacheKey, result.result, context.agentId, 3600, 'system-orchestrator-token'); // 1 hour TTL
935935
}
936936
}
937937
}
@@ -1204,7 +1204,7 @@ export class SwarmOrchestrator implements OpenClawSkill {
12041204
this.blackboard.write(`trace:${traceId}`, {
12051205
action,
12061206
startTime: new Date().toISOString(),
1207-
}, context.agentId);
1207+
}, context.agentId, undefined, 'system-orchestrator-token');
12081208
} catch {
12091209
// Non-fatal -- tracing failure shouldn't block execution
12101210
}
@@ -1425,7 +1425,7 @@ export class SwarmOrchestrator implements OpenClawSkill {
14251425
}
14261426

14271427
// Approved -- cache result
1428-
this.blackboard.write(cacheKey, sanitizedResult, context.agentId, 1800); // 30 min TTL
1428+
this.blackboard.write(cacheKey, sanitizedResult, context.agentId, 1800, 'system-orchestrator-token'); // 30 min TTL
14291429

14301430
return {
14311431
success: true,
@@ -1633,7 +1633,7 @@ export class SwarmOrchestrator implements OpenClawSkill {
16331633
};
16341634
}
16351635

1636-
this.blackboard.write(key, value, context.agentId, ttl);
1636+
this.blackboard.write(key, value, context.agentId, ttl, 'system-orchestrator-token');
16371637

16381638
return {
16391639
success: true,
@@ -1681,7 +1681,7 @@ export class SwarmOrchestrator implements OpenClawSkill {
16811681
entry = this.qualityGate.approveQuarantined(quarantineId);
16821682
if (entry) {
16831683
// Write the approved entry to the blackboard
1684-
this.blackboard.write(`approved:${quarantineId}`, entry, 'orchestrator');
1684+
this.blackboard.write(`approved:${quarantineId}`, entry, 'orchestrator', undefined, 'system-orchestrator-token');
16851685
}
16861686
} else {
16871687
entry = this.qualityGate.rejectQuarantined(quarantineId);

swarm-blackboard.md

Lines changed: 147 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,175 @@
11
# Swarm Blackboard
2-
Last Updated: 2026-02-15T14:46:17.062Z
2+
Last Updated: 2026-02-15T15:13:53.693Z
3+
Content Hash: 944bf251df8b253d
34

45
## Active Tasks
56
| TaskID | Agent | Status | Started | Description |
67
|--------|-------|--------|---------|-------------|
78

89
## Knowledge Cache
9-
### code:auth:implementation
10+
### test:key1
11+
```json
1012
{
11-
"key": "code:auth:implementation",
13+
"key": "test:key1",
1214
"value": {
13-
"files": [
14-
"src/auth/login.ts",
15-
"src/auth/middleware.ts"
16-
],
17-
"linesChanged": 245,
18-
"status": "complete"
15+
"data": "hello world"
1916
},
20-
"sourceAgent": "code_writer",
21-
"timestamp": "2026-02-15T14:46:17.046Z",
22-
"ttl": null
17+
"source_agent": "test-agent",
18+
"timestamp": "2026-02-15T15:13:52.019Z",
19+
"ttl": null,
20+
"version": 2
2321
}
22+
```
2423

25-
### review:auth:feedback
24+
### test:snap1
25+
```json
2626
{
27-
"key": "review:auth:feedback",
27+
"key": "test:snap1",
2828
"value": {
29-
"approved": true,
30-
"comments": [
31-
"Good separation of concerns",
32-
"Add input validation"
33-
],
34-
"reviewer": "code_reviewer"
29+
"a": 1
3530
},
36-
"sourceAgent": "code_reviewer",
37-
"timestamp": "2026-02-15T14:46:17.051Z",
38-
"ttl": null
31+
"source_agent": "agent1",
32+
"timestamp": "2026-02-15T15:13:53.543Z",
33+
"ttl": null,
34+
"version": 2
3935
}
36+
```
4037

41-
### test:auth:results
38+
### test:snap2
39+
```json
4240
{
43-
"key": "test:auth:results",
41+
"key": "test:snap2",
4442
"value": {
45-
"passed": 42,
46-
"failed": 0,
47-
"skipped": 2,
48-
"coverage": 87.3,
49-
"duration": 3200
43+
"b": 2
5044
},
51-
"sourceAgent": "test_runner",
52-
"timestamp": "2026-02-15T14:46:17.057Z",
53-
"ttl": null
45+
"source_agent": "agent2",
46+
"timestamp": "2026-02-15T15:13:53.548Z",
47+
"ttl": null,
48+
"version": 2
5449
}
50+
```
5551

56-
### infra:k8s:config
52+
### trace:b1ac6a75-a74f-4100-b8da-ec565d24453c
53+
```json
5754
{
58-
"key": "infra:k8s:config",
55+
"key": "trace:b1ac6a75-a74f-4100-b8da-ec565d24453c",
5956
"value": {
60-
"replicas": 3
57+
"action": "update_blackboard",
58+
"startTime": "2026-02-15T15:13:53.602Z"
6159
},
62-
"sourceAgent": "devops_agent",
63-
"timestamp": "2026-02-15T14:46:17.062Z",
64-
"ttl": null
60+
"source_agent": "orchestrator",
61+
"timestamp": "2026-02-15T15:13:53.603Z",
62+
"ttl": null,
63+
"version": 1
6564
}
65+
```
66+
67+
### test:orchestrator:data
68+
```json
69+
{
70+
"key": "test:orchestrator:data",
71+
"value": {
72+
"message": "Hello from orchestrator test"
73+
},
74+
"source_agent": "orchestrator",
75+
"timestamp": "2026-02-15T15:13:53.612Z",
76+
"ttl": 3600,
77+
"version": 1
78+
}
79+
```
80+
81+
### trace:2e2475b2-b904-4519-abe4-06fc48e44a77
82+
```json
83+
{
84+
"key": "trace:2e2475b2-b904-4519-abe4-06fc48e44a77",
85+
"value": {
86+
"action": "query_swarm_state",
87+
"startTime": "2026-02-15T15:13:53.619Z"
88+
},
89+
"source_agent": "orchestrator",
90+
"timestamp": "2026-02-15T15:13:53.619Z",
91+
"ttl": null,
92+
"version": 1
93+
}
94+
```
95+
96+
### trace:73acc5d9-7101-40b8-832b-a9923858df7a
97+
```json
98+
{
99+
"key": "trace:73acc5d9-7101-40b8-832b-a9923858df7a",
100+
"value": {
101+
"action": "request_permission",
102+
"startTime": "2026-02-15T15:13:53.626Z"
103+
},
104+
"source_agent": "orchestrator",
105+
"timestamp": "2026-02-15T15:13:53.626Z",
106+
"ttl": null,
107+
"version": 1
108+
}
109+
```
110+
111+
### trace:66532ae4-6c53-4841-b7d2-2bfe28d876da
112+
```json
113+
{
114+
"key": "trace:66532ae4-6c53-4841-b7d2-2bfe28d876da",
115+
"value": {
116+
"action": "query_swarm_state",
117+
"startTime": "2026-02-15T15:13:53.635Z"
118+
},
119+
"source_agent": "orchestrator",
120+
"timestamp": "2026-02-15T15:13:53.635Z",
121+
"ttl": null,
122+
"version": 1
123+
}
124+
```
125+
126+
### trace:6c4b907c-b9de-4d07-ae7a-6cc95f7b74fd
127+
```json
128+
{
129+
"key": "trace:6c4b907c-b9de-4d07-ae7a-6cc95f7b74fd",
130+
"value": {
131+
"action": "unknown_action",
132+
"startTime": "2026-02-15T15:13:53.643Z"
133+
},
134+
"source_agent": "orchestrator",
135+
"timestamp": "2026-02-15T15:13:53.644Z",
136+
"ttl": null,
137+
"version": 1
138+
}
139+
```
140+
141+
### trace:9cee7dba-eccf-41b0-bf9f-52e2ae5d4057
142+
```json
143+
{
144+
"key": "trace:9cee7dba-eccf-41b0-bf9f-52e2ae5d4057",
145+
"value": {
146+
"action": "update_blackboard",
147+
"startTime": "2026-02-15T15:13:53.685Z"
148+
},
149+
"source_agent": "orchestrator",
150+
"timestamp": "2026-02-15T15:13:53.685Z",
151+
"ttl": null,
152+
"version": 1
153+
}
154+
```
155+
156+
### trace:291a7063-7491-4dc1-9dd9-eb4f01a24422
157+
```json
158+
{
159+
"key": "trace:291a7063-7491-4dc1-9dd9-eb4f01a24422",
160+
"value": {
161+
"action": "query_swarm_state",
162+
"startTime": "2026-02-15T15:13:53.693Z"
163+
},
164+
"source_agent": "orchestrator",
165+
"timestamp": "2026-02-15T15:13:53.693Z",
166+
"ttl": null,
167+
"version": 1
168+
}
169+
```
66170

67171
## Coordination Signals
68-
## Execution History
172+
<!-- Agent availability status -->
173+
174+
## Execution History
175+
<!-- Chronological log of completed tasks -->

test.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ async function testBlackboard() {
8383

8484
const blackboard = new SharedBlackboard(process.cwd());
8585

86+
// Register test agent with wildcard namespace access
87+
blackboard.registerAgent('test-agent', 'test-token', ['*']);
88+
blackboard.registerAgent('agent1', 'token1', ['*']);
89+
blackboard.registerAgent('agent2', 'token2', ['*']);
90+
8691
// Test write
87-
const entry = blackboard.write('test:key1', { data: 'hello world' }, 'test-agent');
92+
const entry = blackboard.write('test:key1', { data: 'hello world' }, 'test-agent', undefined, 'test-token');
8893
if (entry.key === 'test:key1' && (entry.value as any).data === 'hello world') {
8994
pass('Write to blackboard');
9095
} else {
@@ -107,7 +112,7 @@ async function testBlackboard() {
107112
}
108113

109114
// Test TTL expiration
110-
blackboard.write('test:expiring', { temp: true }, 'test-agent', 1); // 1 second TTL
115+
blackboard.write('test:expiring', { temp: true }, 'test-agent', 1, 'test-token'); // 1 second TTL
111116
if (blackboard.read('test:expiring')) {
112117
pass('TTL entry created');
113118
} else {
@@ -123,8 +128,8 @@ async function testBlackboard() {
123128
}
124129

125130
// Test snapshot
126-
blackboard.write('test:snap1', { a: 1 }, 'agent1');
127-
blackboard.write('test:snap2', { b: 2 }, 'agent2');
131+
blackboard.write('test:snap1', { a: 1 }, 'agent1', undefined, 'token1');
132+
blackboard.write('test:snap2', { b: 2 }, 'agent2', undefined, 'token2');
128133
const snapshot = blackboard.getSnapshot();
129134
if (Object.keys(snapshot).length >= 2) {
130135
pass('Snapshot retrieval');

0 commit comments

Comments
 (0)