shieldcortex 2.2.0 → 2.4.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/README.md +20 -5
- package/dist/api/events.d.ts +11 -1
- package/dist/api/events.d.ts.map +1 -1
- package/dist/api/events.js +3 -0
- package/dist/api/events.js.map +1 -1
- package/dist/api/visualization-server.d.ts.map +1 -1
- package/dist/api/visualization-server.js +60 -4
- package/dist/api/visualization-server.js.map +1 -1
- package/dist/database/init.d.ts.map +1 -1
- package/dist/database/init.js +44 -0
- package/dist/database/init.js.map +1 -1
- package/dist/defence/__tests__/access-control.test.d.ts +5 -0
- package/dist/defence/__tests__/access-control.test.d.ts.map +1 -0
- package/dist/defence/__tests__/access-control.test.js +89 -0
- package/dist/defence/__tests__/access-control.test.js.map +1 -0
- package/dist/defence/__tests__/agent-scorer.test.d.ts +5 -0
- package/dist/defence/__tests__/agent-scorer.test.d.ts.map +1 -0
- package/dist/defence/__tests__/agent-scorer.test.js +75 -0
- package/dist/defence/__tests__/agent-scorer.test.js.map +1 -0
- package/dist/defence/__tests__/env-detector.test.d.ts +5 -0
- package/dist/defence/__tests__/env-detector.test.d.ts.map +1 -0
- package/dist/defence/__tests__/env-detector.test.js +99 -0
- package/dist/defence/__tests__/env-detector.test.js.map +1 -0
- package/dist/defence/__tests__/pipeline.test.js +1 -0
- package/dist/defence/__tests__/pipeline.test.js.map +1 -1
- package/dist/defence/__tests__/trust.test.js +3 -2
- package/dist/defence/__tests__/trust.test.js.map +1 -1
- package/dist/defence/audit/index.d.ts +2 -2
- package/dist/defence/audit/index.d.ts.map +1 -1
- package/dist/defence/audit/index.js +1 -1
- package/dist/defence/audit/index.js.map +1 -1
- package/dist/defence/audit/logger.d.ts.map +1 -1
- package/dist/defence/audit/logger.js +3 -2
- package/dist/defence/audit/logger.js.map +1 -1
- package/dist/defence/audit/queries.d.ts +35 -1
- package/dist/defence/audit/queries.d.ts.map +1 -1
- package/dist/defence/audit/queries.js +93 -21
- package/dist/defence/audit/queries.js.map +1 -1
- package/dist/defence/pipeline.d.ts +1 -1
- package/dist/defence/pipeline.d.ts.map +1 -1
- package/dist/defence/pipeline.js +22 -1
- package/dist/defence/pipeline.js.map +1 -1
- package/dist/defence/quarantine/auto-expire.d.ts +15 -0
- package/dist/defence/quarantine/auto-expire.d.ts.map +1 -0
- package/dist/defence/quarantine/auto-expire.js +38 -0
- package/dist/defence/quarantine/auto-expire.js.map +1 -0
- package/dist/defence/trust/access-control.d.ts +29 -0
- package/dist/defence/trust/access-control.d.ts.map +1 -0
- package/dist/defence/trust/access-control.js +64 -0
- package/dist/defence/trust/access-control.js.map +1 -0
- package/dist/defence/trust/agent-scorer.d.ts +33 -0
- package/dist/defence/trust/agent-scorer.d.ts.map +1 -0
- package/dist/defence/trust/agent-scorer.js +55 -0
- package/dist/defence/trust/agent-scorer.js.map +1 -0
- package/dist/defence/trust/env-detector.d.ts +43 -0
- package/dist/defence/trust/env-detector.d.ts.map +1 -0
- package/dist/defence/trust/env-detector.js +99 -0
- package/dist/defence/trust/env-detector.js.map +1 -0
- package/dist/defence/trust/index.d.ts +6 -0
- package/dist/defence/trust/index.d.ts.map +1 -1
- package/dist/defence/trust/index.js +3 -0
- package/dist/defence/trust/index.js.map +1 -1
- package/dist/defence/trust/source-scorer.d.ts.map +1 -1
- package/dist/defence/trust/source-scorer.js +33 -15
- package/dist/defence/trust/source-scorer.js.map +1 -1
- package/dist/defence/types.d.ts +3 -0
- package/dist/defence/types.d.ts.map +1 -1
- package/dist/defence/types.js +1 -0
- package/dist/defence/types.js.map +1 -1
- package/dist/memory/consolidate.d.ts +1 -0
- package/dist/memory/consolidate.d.ts.map +1 -1
- package/dist/memory/consolidate.js +8 -1
- package/dist/memory/consolidate.js.map +1 -1
- package/dist/memory/store.d.ts +6 -6
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +139 -16
- package/dist/memory/store.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +82 -11
- package/dist/server.js.map +1 -1
- package/dist/setup/claude-md.d.ts +3 -1
- package/dist/setup/claude-md.d.ts.map +1 -1
- package/dist/setup/claude-md.js +47 -3
- package/dist/setup/claude-md.js.map +1 -1
- package/dist/setup/doctor.d.ts.map +1 -1
- package/dist/setup/doctor.js +7 -4
- package/dist/setup/doctor.js.map +1 -1
- package/dist/setup/uninstall.d.ts.map +1 -1
- package/dist/setup/uninstall.js +27 -0
- package/dist/setup/uninstall.js.map +1 -1
- package/dist/tools/context.d.ts +18 -0
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +4 -0
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/forget.d.ts +18 -0
- package/dist/tools/forget.d.ts.map +1 -1
- package/dist/tools/forget.js +12 -1
- package/dist/tools/forget.js.map +1 -1
- package/dist/tools/recall.d.ts +38 -0
- package/dist/tools/recall.d.ts.map +1 -1
- package/dist/tools/recall.js +12 -5
- package/dist/tools/recall.js.map +1 -1
- package/dist/tools/remember.d.ts +2 -2
- package/package.json +1 -1
|
@@ -11,46 +11,52 @@ export function queryAuditLogs(options = {}) {
|
|
|
11
11
|
const conditions = [];
|
|
12
12
|
const params = {};
|
|
13
13
|
if (options.startTime) {
|
|
14
|
-
conditions.push('timestamp >= @startTime');
|
|
14
|
+
conditions.push('da.timestamp >= @startTime');
|
|
15
15
|
params.startTime = options.startTime;
|
|
16
16
|
}
|
|
17
17
|
if (options.endTime) {
|
|
18
|
-
conditions.push('timestamp <= @endTime');
|
|
18
|
+
conditions.push('da.timestamp <= @endTime');
|
|
19
19
|
params.endTime = options.endTime;
|
|
20
20
|
}
|
|
21
21
|
if (options.firewallResult) {
|
|
22
|
-
conditions.push('firewall_result = @firewallResult');
|
|
22
|
+
conditions.push('da.firewall_result = @firewallResult');
|
|
23
23
|
params.firewallResult = options.firewallResult;
|
|
24
24
|
}
|
|
25
25
|
if (options.source) {
|
|
26
|
-
conditions.push('source_type = @source');
|
|
26
|
+
conditions.push('da.source_type = @source');
|
|
27
27
|
params.source = options.source;
|
|
28
28
|
}
|
|
29
29
|
if (options.memoryId !== undefined) {
|
|
30
|
-
conditions.push('memory_id = @memoryId');
|
|
30
|
+
conditions.push('da.memory_id = @memoryId');
|
|
31
31
|
params.memoryId = options.memoryId;
|
|
32
32
|
}
|
|
33
|
+
if (options.project) {
|
|
34
|
+
conditions.push('da.project = @project');
|
|
35
|
+
params.project = options.project;
|
|
36
|
+
}
|
|
33
37
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
34
38
|
const limit = options.limit ?? 50;
|
|
35
|
-
const sql = `SELECT
|
|
39
|
+
const sql = `SELECT da.* FROM defence_audit da ${where} ORDER BY da.timestamp DESC LIMIT @limit`;
|
|
36
40
|
params.limit = limit;
|
|
37
41
|
return db.prepare(sql).all(params);
|
|
38
42
|
}
|
|
39
43
|
/**
|
|
40
44
|
* Get aggregate audit statistics for a time range.
|
|
41
45
|
*/
|
|
42
|
-
export function getAuditStats(timeRange) {
|
|
46
|
+
export function getAuditStats(timeRange, project) {
|
|
43
47
|
const db = getDatabase();
|
|
44
48
|
const hoursMap = { '24h': 24, '7d': 168, '30d': 720 };
|
|
45
49
|
const hours = hoursMap[timeRange];
|
|
46
50
|
const since = new Date(Date.now() - hours * 3600_000).toISOString();
|
|
51
|
+
const projectCond = project ? 'AND da.project = ?' : '';
|
|
52
|
+
const baseParams = project ? [since, project] : [since];
|
|
47
53
|
// Counts by firewall result
|
|
48
54
|
const counts = db.prepare(`
|
|
49
|
-
SELECT firewall_result, COUNT(*) as cnt
|
|
50
|
-
FROM defence_audit
|
|
51
|
-
WHERE timestamp >= ?
|
|
52
|
-
GROUP BY firewall_result
|
|
53
|
-
`).all(
|
|
55
|
+
SELECT da.firewall_result, COUNT(*) as cnt
|
|
56
|
+
FROM defence_audit da
|
|
57
|
+
WHERE da.timestamp >= ? ${projectCond}
|
|
58
|
+
GROUP BY da.firewall_result
|
|
59
|
+
`).all(...baseParams);
|
|
54
60
|
let totalOperations = 0;
|
|
55
61
|
let allowedCount = 0;
|
|
56
62
|
let blockedCount = 0;
|
|
@@ -66,19 +72,19 @@ export function getAuditStats(timeRange) {
|
|
|
66
72
|
}
|
|
67
73
|
// Top sources
|
|
68
74
|
const topSources = db.prepare(`
|
|
69
|
-
SELECT source_type as source, COUNT(*) as count
|
|
70
|
-
FROM defence_audit
|
|
71
|
-
WHERE timestamp >= ?
|
|
72
|
-
GROUP BY source_type
|
|
75
|
+
SELECT da.source_type as source, COUNT(*) as count
|
|
76
|
+
FROM defence_audit da
|
|
77
|
+
WHERE da.timestamp >= ? ${projectCond}
|
|
78
|
+
GROUP BY da.source_type
|
|
73
79
|
ORDER BY count DESC
|
|
74
80
|
LIMIT 10
|
|
75
|
-
`).all(
|
|
81
|
+
`).all(...baseParams);
|
|
76
82
|
// Threat indicator breakdown
|
|
77
83
|
const rows = db.prepare(`
|
|
78
|
-
SELECT threat_indicators
|
|
79
|
-
FROM defence_audit
|
|
80
|
-
WHERE timestamp >= ? AND threat_indicators != '[]'
|
|
81
|
-
`).all(
|
|
84
|
+
SELECT da.threat_indicators
|
|
85
|
+
FROM defence_audit da
|
|
86
|
+
WHERE da.timestamp >= ? ${projectCond} AND da.threat_indicators != '[]'
|
|
87
|
+
`).all(...baseParams);
|
|
82
88
|
const threatBreakdown = {};
|
|
83
89
|
for (const row of rows) {
|
|
84
90
|
try {
|
|
@@ -100,4 +106,70 @@ export function getAuditStats(timeRange) {
|
|
|
100
106
|
threatBreakdown,
|
|
101
107
|
};
|
|
102
108
|
}
|
|
109
|
+
// ── Agent Query Functions ──
|
|
110
|
+
/**
|
|
111
|
+
* Get distinct agents aggregated from audit logs.
|
|
112
|
+
*/
|
|
113
|
+
export function queryAgentRegistry(timeRange = '24h', project) {
|
|
114
|
+
const db = getDatabase();
|
|
115
|
+
const hoursMap = { '24h': 24, '7d': 168, '30d': 720 };
|
|
116
|
+
const since = new Date(Date.now() - hoursMap[timeRange] * 3600_000).toISOString();
|
|
117
|
+
const projectCond = project ? 'AND project = ?' : '';
|
|
118
|
+
const params = project ? [since, project] : [since];
|
|
119
|
+
return db.prepare(`
|
|
120
|
+
SELECT source_type, source_identifier,
|
|
121
|
+
COUNT(*) as operation_count,
|
|
122
|
+
MAX(timestamp) as last_seen,
|
|
123
|
+
AVG(trust_score) as avg_trust_score,
|
|
124
|
+
MIN(trust_score) as min_trust_score,
|
|
125
|
+
MAX(trust_score) as max_trust_score,
|
|
126
|
+
SUM(CASE WHEN firewall_result != 'ALLOW' THEN 1 ELSE 0 END) as flagged_count
|
|
127
|
+
FROM defence_audit
|
|
128
|
+
WHERE timestamp >= ? ${projectCond}
|
|
129
|
+
GROUP BY source_type, source_identifier
|
|
130
|
+
ORDER BY operation_count DESC
|
|
131
|
+
`).all(...params);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get trust score timeline for a specific agent.
|
|
135
|
+
*/
|
|
136
|
+
export function queryAgentTimeline(identifier, timeRange = '24h', project) {
|
|
137
|
+
const db = getDatabase();
|
|
138
|
+
const hoursMap = { '24h': 24, '7d': 168, '30d': 720 };
|
|
139
|
+
const since = new Date(Date.now() - hoursMap[timeRange] * 3600_000).toISOString();
|
|
140
|
+
const projectCond = project ? 'AND project = ?' : '';
|
|
141
|
+
const params = project ? [identifier, since, project] : [identifier, since];
|
|
142
|
+
return db.prepare(`
|
|
143
|
+
SELECT timestamp, trust_score, firewall_result, anomaly_score
|
|
144
|
+
FROM defence_audit
|
|
145
|
+
WHERE source_identifier = ? AND timestamp >= ? ${projectCond}
|
|
146
|
+
ORDER BY timestamp ASC
|
|
147
|
+
`).all(...params);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get paginated audit entries for a specific agent.
|
|
151
|
+
*/
|
|
152
|
+
export function queryAgentOperations(identifier, options = {}) {
|
|
153
|
+
const db = getDatabase();
|
|
154
|
+
const conditions = ['source_identifier = @identifier'];
|
|
155
|
+
const params = { identifier };
|
|
156
|
+
if (options.firewallResult) {
|
|
157
|
+
conditions.push('firewall_result = @firewallResult');
|
|
158
|
+
params.firewallResult = options.firewallResult;
|
|
159
|
+
}
|
|
160
|
+
if (options.project) {
|
|
161
|
+
conditions.push('project = @project');
|
|
162
|
+
params.project = options.project;
|
|
163
|
+
}
|
|
164
|
+
const limit = options.limit ?? 50;
|
|
165
|
+
const offset = options.offset ?? 0;
|
|
166
|
+
params.limit = limit;
|
|
167
|
+
params.offset = offset;
|
|
168
|
+
return db.prepare(`
|
|
169
|
+
SELECT * FROM defence_audit
|
|
170
|
+
WHERE ${conditions.join(' AND ')}
|
|
171
|
+
ORDER BY timestamp DESC
|
|
172
|
+
LIMIT @limit OFFSET @offset
|
|
173
|
+
`).all(params);
|
|
174
|
+
}
|
|
103
175
|
//# sourceMappingURL=queries.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/defence/audit/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/defence/audit/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* Fail-open: if any layer throws, the pipeline defaults to ALLOW with a warning.
|
|
6
6
|
*/
|
|
7
7
|
import type { DefenceConfig, DefencePipelineResult, DefenceSource } from './types.js';
|
|
8
|
-
export declare function runDefencePipeline(content: string, title: string, source: DefenceSource, config?: DefenceConfig): DefencePipelineResult;
|
|
8
|
+
export declare function runDefencePipeline(content: string, title: string, source: DefenceSource, config?: DefenceConfig, project?: string): DefencePipelineResult;
|
|
9
9
|
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/defence/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,aAAa,EAKd,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/defence/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,aAAa,EAKd,MAAM,YAAY,CAAC;AAUpB,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,aAAa,EACrB,MAAM,CAAC,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,qBAAqB,CA+IvB"}
|
package/dist/defence/pipeline.js
CHANGED
|
@@ -10,7 +10,8 @@ import { analyzeFirewall } from './firewall/index.js';
|
|
|
10
10
|
import { classifySensitivity } from './sensitivity/index.js';
|
|
11
11
|
import { analyzeFragmentation } from './fragmentation/index.js';
|
|
12
12
|
import { logAudit, createContentHash } from './audit/index.js';
|
|
13
|
-
|
|
13
|
+
import { persistEvent } from '../api/events.js';
|
|
14
|
+
export function runDefencePipeline(content, title, source, config, project) {
|
|
14
15
|
const cfg = config ?? DEFAULT_DEFENCE_CONFIG;
|
|
15
16
|
const startTime = performance.now();
|
|
16
17
|
try {
|
|
@@ -54,6 +55,7 @@ export function runDefencePipeline(content, title, source, config) {
|
|
|
54
55
|
const _contentHash = createContentHash(content);
|
|
55
56
|
const auditId = logAudit({
|
|
56
57
|
memory_id: null,
|
|
58
|
+
project: project ?? null,
|
|
57
59
|
timestamp: new Date().toISOString(),
|
|
58
60
|
source_type: source.type,
|
|
59
61
|
source_identifier: source.identifier,
|
|
@@ -67,6 +69,24 @@ export function runDefencePipeline(content, title, source, config) {
|
|
|
67
69
|
fragmentation_score: fragmentation?.score ?? null,
|
|
68
70
|
pipeline_duration_ms: durationMs,
|
|
69
71
|
});
|
|
72
|
+
// 7. Emit defence event for real-time dashboard alerts (BLOCK/QUARANTINE only)
|
|
73
|
+
if (firewall.result !== 'ALLOW') {
|
|
74
|
+
try {
|
|
75
|
+
persistEvent('defence_event', {
|
|
76
|
+
source_type: source.type,
|
|
77
|
+
source_identifier: source.identifier,
|
|
78
|
+
firewall_result: firewall.result,
|
|
79
|
+
trust_score: trust.score,
|
|
80
|
+
anomaly_score: firewall.anomalyScore,
|
|
81
|
+
reason,
|
|
82
|
+
threat_indicators: JSON.stringify(firewall.threatIndicators),
|
|
83
|
+
timestamp: new Date().toISOString(),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Event persistence is best-effort
|
|
88
|
+
}
|
|
89
|
+
}
|
|
70
90
|
return {
|
|
71
91
|
allowed,
|
|
72
92
|
firewall,
|
|
@@ -82,6 +102,7 @@ export function runDefencePipeline(content, title, source, config) {
|
|
|
82
102
|
console.error('[defence] Pipeline error, failing open:', err);
|
|
83
103
|
const auditId = logAudit({
|
|
84
104
|
memory_id: null,
|
|
105
|
+
project: project ?? null,
|
|
85
106
|
timestamp: new Date().toISOString(),
|
|
86
107
|
source_type: source.type,
|
|
87
108
|
source_identifier: source.identifier,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/defence/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/defence/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quarantine auto-expiry — rejects unreviewed items after a TTL.
|
|
3
|
+
*
|
|
4
|
+
* Safer default: expired items are rejected (discarded), not promoted.
|
|
5
|
+
* A memory that sat in quarantine for 7 days with nobody reviewing it
|
|
6
|
+
* shouldn't be promoted to the memory store.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Set expires_at on quarantine items that don't have one,
|
|
10
|
+
* then reject any expired items.
|
|
11
|
+
*
|
|
12
|
+
* @returns Number of items expired (rejected)
|
|
13
|
+
*/
|
|
14
|
+
export declare function expireQuarantineItems(ttlDays?: number): number;
|
|
15
|
+
//# sourceMappingURL=auto-expire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-expire.d.ts","sourceRoot":"","sources":["../../../src/defence/quarantine/auto-expire.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,MAAU,GAAG,MAAM,CA0BjE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quarantine auto-expiry — rejects unreviewed items after a TTL.
|
|
3
|
+
*
|
|
4
|
+
* Safer default: expired items are rejected (discarded), not promoted.
|
|
5
|
+
* A memory that sat in quarantine for 7 days with nobody reviewing it
|
|
6
|
+
* shouldn't be promoted to the memory store.
|
|
7
|
+
*/
|
|
8
|
+
import { getDatabase } from '../../database/init.js';
|
|
9
|
+
/**
|
|
10
|
+
* Set expires_at on quarantine items that don't have one,
|
|
11
|
+
* then reject any expired items.
|
|
12
|
+
*
|
|
13
|
+
* @returns Number of items expired (rejected)
|
|
14
|
+
*/
|
|
15
|
+
export function expireQuarantineItems(ttlDays = 7) {
|
|
16
|
+
const db = getDatabase();
|
|
17
|
+
// Set expires_at on new items that don't have one
|
|
18
|
+
db.prepare(`
|
|
19
|
+
UPDATE quarantine
|
|
20
|
+
SET expires_at = datetime(created_at, '+' || ? || ' days')
|
|
21
|
+
WHERE expires_at IS NULL AND status = 'pending'
|
|
22
|
+
`).run(ttlDays);
|
|
23
|
+
// Reject expired items
|
|
24
|
+
const result = db.prepare(`
|
|
25
|
+
UPDATE quarantine
|
|
26
|
+
SET status = 'expired',
|
|
27
|
+
reviewed_by = 'auto-expire',
|
|
28
|
+
reviewed_at = CURRENT_TIMESTAMP
|
|
29
|
+
WHERE status = 'pending'
|
|
30
|
+
AND expires_at IS NOT NULL
|
|
31
|
+
AND expires_at < datetime('now')
|
|
32
|
+
`).run();
|
|
33
|
+
if (result.changes > 0) {
|
|
34
|
+
console.error(`[quarantine] Auto-expired ${result.changes} item(s) after ${ttlDays} days`);
|
|
35
|
+
}
|
|
36
|
+
return result.changes;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=auto-expire.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-expire.js","sourceRoot":"","sources":["../../../src/defence/quarantine/auto-expire.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,UAAkB,CAAC;IACvD,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IAEzB,kDAAkD;IAClD,EAAE,CAAC,OAAO,CAAC;;;;GAIV,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAEhB,uBAAuB;IACvB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;GAQzB,CAAC,CAAC,GAAG,EAAE,CAAC;IAET,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,6BAA6B,MAAM,CAAC,OAAO,kBAAkB,OAAO,OAAO,CAAC,CAAC;IAC7F,CAAC;IAED,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory access control — enforces read/write/delete policies based on trust.
|
|
3
|
+
*
|
|
4
|
+
* Access rules:
|
|
5
|
+
* Trust ≥ 0.7 → Read all, write direct, delete own
|
|
6
|
+
* Trust 0.5–0.7 → Read own + non-restricted, write quarantine, delete own
|
|
7
|
+
* Trust < 0.5 → Read own only, write quarantine, delete none
|
|
8
|
+
*
|
|
9
|
+
* RESTRICTED memories are always blocked below trust 0.7 (credential isolation).
|
|
10
|
+
*/
|
|
11
|
+
import type { DefenceSource } from '../types.js';
|
|
12
|
+
export interface AccessPolicy {
|
|
13
|
+
canRead: boolean;
|
|
14
|
+
canWrite: boolean;
|
|
15
|
+
canDelete: boolean;
|
|
16
|
+
writeRequiresQuarantine: boolean;
|
|
17
|
+
reason: string;
|
|
18
|
+
}
|
|
19
|
+
/** Minimal memory shape needed for access checks */
|
|
20
|
+
export interface AccessCheckMemory {
|
|
21
|
+
id: number;
|
|
22
|
+
source?: string | null;
|
|
23
|
+
sensitivity_level?: string | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check whether a source has access to a memory for a given operation.
|
|
27
|
+
*/
|
|
28
|
+
export declare function checkAccess(memory: AccessCheckMemory, source: DefenceSource, operation: 'read' | 'write' | 'delete'): AccessPolicy;
|
|
29
|
+
//# sourceMappingURL=access-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-control.d.ts","sourceRoot":"","sources":["../../../src/defence/trust/access-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,uBAAuB,EAAE,OAAO,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GACrC,YAAY,CA+Cd"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory access control — enforces read/write/delete policies based on trust.
|
|
3
|
+
*
|
|
4
|
+
* Access rules:
|
|
5
|
+
* Trust ≥ 0.7 → Read all, write direct, delete own
|
|
6
|
+
* Trust 0.5–0.7 → Read own + non-restricted, write quarantine, delete own
|
|
7
|
+
* Trust < 0.5 → Read own only, write quarantine, delete none
|
|
8
|
+
*
|
|
9
|
+
* RESTRICTED memories are always blocked below trust 0.7 (credential isolation).
|
|
10
|
+
*/
|
|
11
|
+
import { scoreSource } from './source-scorer.js';
|
|
12
|
+
/**
|
|
13
|
+
* Check whether a source has access to a memory for a given operation.
|
|
14
|
+
*/
|
|
15
|
+
export function checkAccess(memory, source, operation) {
|
|
16
|
+
const trust = scoreSource(source).score;
|
|
17
|
+
const memorySource = memory.source || 'user:direct';
|
|
18
|
+
const callerKey = `${source.type}:${source.identifier}`;
|
|
19
|
+
const isOwner = memorySource === callerKey;
|
|
20
|
+
const isRestricted = memory.sensitivity_level === 'RESTRICTED';
|
|
21
|
+
if (operation === 'read') {
|
|
22
|
+
// RESTRICTED memories: credential isolation
|
|
23
|
+
if (isRestricted && trust < 0.7) {
|
|
24
|
+
return deny('Credential isolation: insufficient trust for RESTRICTED data');
|
|
25
|
+
}
|
|
26
|
+
// Owner always reads own
|
|
27
|
+
if (isOwner) {
|
|
28
|
+
return allow('Owner access');
|
|
29
|
+
}
|
|
30
|
+
// High trust: read all
|
|
31
|
+
if (trust >= 0.7) {
|
|
32
|
+
return allow('High-trust read access');
|
|
33
|
+
}
|
|
34
|
+
// Medium trust: read non-restricted
|
|
35
|
+
if (trust >= 0.5) {
|
|
36
|
+
return allow('Shared read access');
|
|
37
|
+
}
|
|
38
|
+
// Low trust: own only (already checked above)
|
|
39
|
+
return deny('Insufficient trust for shared memories (need ≥0.5)');
|
|
40
|
+
}
|
|
41
|
+
if (operation === 'write') {
|
|
42
|
+
if (trust >= 0.7) {
|
|
43
|
+
return allow('Direct write allowed (high trust)');
|
|
44
|
+
}
|
|
45
|
+
return quarantine(`Sub-agent write requires quarantine (trust=${trust.toFixed(3)})`);
|
|
46
|
+
}
|
|
47
|
+
if (operation === 'delete') {
|
|
48
|
+
if (isOwner && trust >= 0.5) {
|
|
49
|
+
return { canRead: true, canWrite: false, canDelete: true, writeRequiresQuarantine: false, reason: 'Owner deletion' };
|
|
50
|
+
}
|
|
51
|
+
return deny('Can only delete own memories (trust ≥0.5)');
|
|
52
|
+
}
|
|
53
|
+
return deny('Unknown operation');
|
|
54
|
+
}
|
|
55
|
+
function allow(reason) {
|
|
56
|
+
return { canRead: true, canWrite: true, canDelete: false, writeRequiresQuarantine: false, reason };
|
|
57
|
+
}
|
|
58
|
+
function deny(reason) {
|
|
59
|
+
return { canRead: false, canWrite: false, canDelete: false, writeRequiresQuarantine: false, reason };
|
|
60
|
+
}
|
|
61
|
+
function quarantine(reason) {
|
|
62
|
+
return { canRead: true, canWrite: false, canDelete: false, writeRequiresQuarantine: true, reason };
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=access-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-control.js","sourceRoot":"","sources":["../../../src/defence/trust/access-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAiBjD;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,MAAyB,EACzB,MAAqB,EACrB,SAAsC;IAEtC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;IACxC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC;IACpD,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,YAAY,KAAK,SAAS,CAAC;IAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,iBAAiB,KAAK,YAAY,CAAC;IAE/D,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,4CAA4C;QAC5C,IAAI,YAAY,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAC9E,CAAC;QAED,yBAAyB;QACzB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,cAAc,CAAC,CAAC;QAC/B,CAAC;QAED,uBAAuB;QACvB,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACzC,CAAC;QAED,oCAAoC;QACpC,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACrC,CAAC;QAED,8CAA8C;QAC9C,OAAO,IAAI,CAAC,oDAAoD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QAC1B,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,UAAU,CAAC,8CAA8C,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,IAAI,OAAO,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;QACvH,CAAC;QACD,OAAO,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,KAAK,CAAC,MAAc;IAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACrG,CAAC;AAED,SAAS,IAAI,CAAC,MAAc;IAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACvG,CAAC;AAED,SAAS,UAAU,CAAC,MAAc;IAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACrG,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent trust scorer — hierarchical trust decay for sub-agents.
|
|
3
|
+
*
|
|
4
|
+
* Agents encode their lineage in the identifier using '>' separators:
|
|
5
|
+
* "user-spawned" → base trust 0.9
|
|
6
|
+
* "user-spawned>task-1" → 0.9 × 0.7 = 0.63
|
|
7
|
+
* "user-spawned>task-1>subtask-2" → 0.9 × 0.7² = 0.44
|
|
8
|
+
* "cron" → base trust 0.5
|
|
9
|
+
* "agent-spawned" → base trust 0.3
|
|
10
|
+
*/
|
|
11
|
+
export interface AgentTrustConfig {
|
|
12
|
+
/** Base trust scores by spawn origin (first segment of identifier) */
|
|
13
|
+
originScores: Record<string, number>;
|
|
14
|
+
/** Multiplier applied per hierarchy depth level */
|
|
15
|
+
decayFactor: number;
|
|
16
|
+
/** Maximum allowed depth — agents beyond this get score 0 */
|
|
17
|
+
maxDepth: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_AGENT_CONFIG: AgentTrustConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Score an agent based on its hierarchy identifier.
|
|
22
|
+
* Returns a trust score between 0.0 and 1.0.
|
|
23
|
+
*/
|
|
24
|
+
export declare function scoreAgent(identifier: string, config?: AgentTrustConfig): number;
|
|
25
|
+
/**
|
|
26
|
+
* Get the depth of an agent in its hierarchy (0 = parent).
|
|
27
|
+
*/
|
|
28
|
+
export declare function getAgentDepth(identifier: string): number;
|
|
29
|
+
/**
|
|
30
|
+
* Build a human-readable hierarchy showing trust at each level.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildAgentHierarchy(identifier: string, config?: AgentTrustConfig): string[];
|
|
33
|
+
//# sourceMappingURL=agent-scorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-scorer.d.ts","sourceRoot":"","sources":["../../../src/defence/trust/agent-scorer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,oBAAoB,EAAE,gBAUlC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,gBAAuC,GAC9C,MAAM,CAUR;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,gBAAuC,GAC9C,MAAM,EAAE,CAWV"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent trust scorer — hierarchical trust decay for sub-agents.
|
|
3
|
+
*
|
|
4
|
+
* Agents encode their lineage in the identifier using '>' separators:
|
|
5
|
+
* "user-spawned" → base trust 0.9
|
|
6
|
+
* "user-spawned>task-1" → 0.9 × 0.7 = 0.63
|
|
7
|
+
* "user-spawned>task-1>subtask-2" → 0.9 × 0.7² = 0.44
|
|
8
|
+
* "cron" → base trust 0.5
|
|
9
|
+
* "agent-spawned" → base trust 0.3
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_AGENT_CONFIG = {
|
|
12
|
+
originScores: {
|
|
13
|
+
'user-spawned': 0.9,
|
|
14
|
+
'user-approved': 0.85,
|
|
15
|
+
'cron': 0.5,
|
|
16
|
+
'agent-spawned': 0.3,
|
|
17
|
+
'web': 0.2,
|
|
18
|
+
},
|
|
19
|
+
decayFactor: 0.7,
|
|
20
|
+
maxDepth: 5,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Score an agent based on its hierarchy identifier.
|
|
24
|
+
* Returns a trust score between 0.0 and 1.0.
|
|
25
|
+
*/
|
|
26
|
+
export function scoreAgent(identifier, config = DEFAULT_AGENT_CONFIG) {
|
|
27
|
+
const parts = identifier.split('>');
|
|
28
|
+
const origin = parts[0];
|
|
29
|
+
const depth = parts.length - 1;
|
|
30
|
+
// Circuit breaker: block agents beyond max depth
|
|
31
|
+
if (depth > config.maxDepth)
|
|
32
|
+
return 0;
|
|
33
|
+
const baseScore = config.originScores[origin] ?? 0.3;
|
|
34
|
+
return Math.round(baseScore * Math.pow(config.decayFactor, depth) * 1000) / 1000;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the depth of an agent in its hierarchy (0 = parent).
|
|
38
|
+
*/
|
|
39
|
+
export function getAgentDepth(identifier) {
|
|
40
|
+
return identifier.split('>').length - 1;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build a human-readable hierarchy showing trust at each level.
|
|
44
|
+
*/
|
|
45
|
+
export function buildAgentHierarchy(identifier, config = DEFAULT_AGENT_CONFIG) {
|
|
46
|
+
const parts = identifier.split('>');
|
|
47
|
+
const hierarchy = [];
|
|
48
|
+
for (let i = 0; i < parts.length; i++) {
|
|
49
|
+
const path = parts.slice(0, i + 1).join('>');
|
|
50
|
+
const score = scoreAgent(path, config);
|
|
51
|
+
hierarchy.push(`${' '.repeat(i)}${parts[i]} (trust=${score.toFixed(3)})`);
|
|
52
|
+
}
|
|
53
|
+
return hierarchy;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=agent-scorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-scorer.js","sourceRoot":"","sources":["../../../src/defence/trust/agent-scorer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,MAAM,CAAC,MAAM,oBAAoB,GAAqB;IACpD,YAAY,EAAE;QACZ,cAAc,EAAE,GAAG;QACnB,eAAe,EAAE,IAAI;QACrB,MAAM,EAAE,GAAG;QACX,eAAe,EAAE,GAAG;QACpB,KAAK,EAAE,GAAG;KACX;IACD,WAAW,EAAE,GAAG;IAChB,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,UAAkB,EAClB,SAA2B,oBAAoB;IAE/C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAE/B,iDAAiD;IACjD,IAAI,KAAK,GAAG,MAAM,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAC;IAEtC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IACrD,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACnF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,SAA2B,oBAAoB;IAE/C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment-Based Source Inference
|
|
3
|
+
*
|
|
4
|
+
* Detects caller identity from process environment variables instead of
|
|
5
|
+
* relying on the MCP client to self-declare. The MCP server process inherits
|
|
6
|
+
* the parent's environment, which isn't forgeable via MCP tool parameters.
|
|
7
|
+
*
|
|
8
|
+
* This addresses Phase 1 limitation: "security is opt-in" — with env detection,
|
|
9
|
+
* Claude Code agents get correct trust automatically with zero configuration.
|
|
10
|
+
*/
|
|
11
|
+
import type { DefenceSource } from '../types.js';
|
|
12
|
+
export interface EnvDetectionResult {
|
|
13
|
+
source: DefenceSource;
|
|
14
|
+
method: 'env:CLAUDE_CODE_ENTRYPOINT' | 'env:CLAUDE_AGENT_CONTEXT' | 'env:SHIELDCORTEX_AGENT_SOURCE' | 'default';
|
|
15
|
+
confidence: 'high' | 'medium' | 'low';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Infer caller source from process environment variables.
|
|
19
|
+
*
|
|
20
|
+
* Priority order:
|
|
21
|
+
* 1. SHIELDCORTEX_AGENT_SOURCE — explicit override (e.g. "agent:user-spawned>task-1")
|
|
22
|
+
* 2. CLAUDE_CODE_ENTRYPOINT=subagent — Claude Code sub-agent
|
|
23
|
+
* 3. CLAUDE_AGENT_CONTEXT — generic agent context marker
|
|
24
|
+
* 4. CLAUDE_CODE_ENTRYPOINT present (any value) — direct Claude Code CLI
|
|
25
|
+
* 5. No recognised env vars → unknown:default (trust 0.5, or 0.3 in strict mode)
|
|
26
|
+
*/
|
|
27
|
+
export declare function inferSourceFromEnvironment(): EnvDetectionResult;
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the effective source for an MCP tool call.
|
|
30
|
+
*
|
|
31
|
+
* If the caller explicitly passes a source, use it.
|
|
32
|
+
* Otherwise, infer from environment.
|
|
33
|
+
*
|
|
34
|
+
* @param declaredSource - Source passed by the MCP client (may be undefined)
|
|
35
|
+
* @param strictMode - If true, unknown sources get lower trust
|
|
36
|
+
* @returns The resolved source and whether it was inferred
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveSource(declaredSource?: DefenceSource, strictMode?: boolean): {
|
|
39
|
+
source: DefenceSource;
|
|
40
|
+
inferred: boolean;
|
|
41
|
+
detection?: EnvDetectionResult;
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=env-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-detector.d.ts","sourceRoot":"","sources":["../../../src/defence/trust/env-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,4BAA4B,GAAG,0BAA0B,GAAG,+BAA+B,GAAG,SAAS,CAAC;IAChH,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CACvC;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,IAAI,kBAAkB,CAoD/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,cAAc,CAAC,EAAE,aAAa,EAC9B,UAAU,GAAE,OAAe,GAC1B;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,kBAAkB,CAAA;CAAE,CAqB9E"}
|