@zanii/sentinel 0.1.0 → 0.3.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/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +131 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +145 -34
package/dist/index.d.ts
CHANGED
|
@@ -134,6 +134,23 @@ export interface Watcher {
|
|
|
134
134
|
* `scan` from `receipt.recorded` webhooks (`@zanii/webhooks`) instead of polling.
|
|
135
135
|
*/
|
|
136
136
|
export declare function createWatcher(opts: WatcherOptions): Watcher;
|
|
137
|
+
export interface BlastRadius {
|
|
138
|
+
/** What the delegation allows — the could-reach surface. */
|
|
139
|
+
declared_scopes: string[];
|
|
140
|
+
/** Target prefixes actually observed in history — the did-reach surface. */
|
|
141
|
+
used_prefixes: string[];
|
|
142
|
+
/** Declared scopes with NO observed activity underneath — standing, unused authority. */
|
|
143
|
+
unused_scopes: string[];
|
|
144
|
+
/** Observed prefixes not covered by any declared scope (should be impossible on-ledger). */
|
|
145
|
+
undeclared_prefixes: string[];
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Could-reach vs did-reach. Standing authority an agent never uses is pure risk —
|
|
149
|
+
* the first thing to cut after an incident, and the first thing an underwriter asks
|
|
150
|
+
* about (`insurance` flags WILDCARD_AUTHORITY; this shows the whole surface). Facts,
|
|
151
|
+
* not a score — a `*` scope is reported as one unused scope, not silently expanded.
|
|
152
|
+
*/
|
|
153
|
+
export declare function blastRadius(baseline: Baseline): BlastRadius;
|
|
137
154
|
/**
|
|
138
155
|
* The default response: a `@zanii/policy` rule turning the flagged prefixes into a
|
|
139
156
|
* `require_approval` speed bump.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -20,28 +20,44 @@
|
|
|
20
20
|
* bump, never auto-revoke; in-scope compromise is the hard case — sequences and rates
|
|
21
21
|
* narrow the window, never to zero.
|
|
22
22
|
*/
|
|
23
|
-
import { jcsHash, scopesAllow, verifyChain } from '@zanii/core';
|
|
23
|
+
import { jcsHash, receiptHash, scopesAllow, verifyChain } from '@zanii/core';
|
|
24
24
|
export function targetPrefix(target) {
|
|
25
25
|
return target.split('.').slice(0, 2).join('.');
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
/** Epoch ms; a naive ts (no offset) is treated as UTC — never local. `null` = unparseable. */
|
|
28
|
+
function tsMs(ts) {
|
|
29
|
+
if (typeof ts !== 'string' || !/^\d{4}-\d{2}-\d{2}T/.test(ts))
|
|
30
|
+
return null;
|
|
31
|
+
const ms = Date.parse(/[zZ]$|[+-]\d{2}:?\d{2}$/.test(ts) ? ts : `${ts}Z`);
|
|
32
|
+
return Number.isNaN(ms) ? null : ms;
|
|
29
33
|
}
|
|
34
|
+
const hourOfMs = (ms) => new Date(ms).getUTCHours();
|
|
35
|
+
/** Hour bucket as `YYYY-MM-DDTHH` in UTC — offset timestamps land in the right bucket. */
|
|
36
|
+
const hourBucket = (ms) => new Date(Math.floor(ms / 3_600_000) * 3_600_000).toISOString().slice(0, 13);
|
|
30
37
|
/** Build the drift baseline for one agent from its delegation (declared) + history (learned). */
|
|
31
38
|
export function buildBaseline(agentId, opts = {}) {
|
|
32
39
|
const history = (opts.receipts ?? []).filter((r) => r.agent_id === agentId);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
let scopes = [];
|
|
41
|
+
if (opts.delegation) {
|
|
42
|
+
const chain = verifyChain(opts.delegation, { agentId });
|
|
43
|
+
// A failed chain must NOT silently degrade to scopes:[] — scan treats empty scopes as
|
|
44
|
+
// "everything in scope", so detection severity would quietly drop.
|
|
45
|
+
if (!chain.ok)
|
|
46
|
+
throw new Error(`delegation chain failed verification (${chain.error}) — refusing to build a baseline on it`);
|
|
47
|
+
scopes = chain.effectiveScopes ?? [];
|
|
48
|
+
}
|
|
36
49
|
const prefixes = new Set();
|
|
37
50
|
const hours = new Array(24).fill(0);
|
|
38
51
|
const perHourCounts = new Map();
|
|
39
52
|
let intents = 0;
|
|
40
53
|
let actions = 0;
|
|
41
54
|
for (const r of history) {
|
|
55
|
+
const ms = tsMs(r.ts);
|
|
56
|
+
if (ms === null)
|
|
57
|
+
throw new Error(`receipt has an unparseable ts: ${String(r.ts)}`);
|
|
42
58
|
prefixes.add(targetPrefix(r.target));
|
|
43
|
-
hours[
|
|
44
|
-
const bucket =
|
|
59
|
+
hours[hourOfMs(ms)] = (hours[hourOfMs(ms)] ?? 0) + 1;
|
|
60
|
+
const bucket = hourBucket(ms);
|
|
45
61
|
perHourCounts.set(bucket, (perHourCounts.get(bucket) ?? 0) + 1);
|
|
46
62
|
if (r.action === 'action_intent')
|
|
47
63
|
intents += 1;
|
|
@@ -81,17 +97,39 @@ function finding(rule, severity, agentId, evidence, observed, expected) {
|
|
|
81
97
|
targets: [...new Set(evidence.map((r) => r.target))],
|
|
82
98
|
observed,
|
|
83
99
|
expected,
|
|
84
|
-
ts: evidence[evidence.length - 1]?.ts ??
|
|
100
|
+
ts: evidence[evidence.length - 1]?.ts ?? '1970-01-01T00:00:00.000Z',
|
|
85
101
|
};
|
|
86
102
|
}
|
|
87
103
|
/** Scan a window of an agent's receipts against its baseline. Pure — no I/O. */
|
|
88
104
|
export function scan(receipts, baseline, opts = {}) {
|
|
89
105
|
const findings = [];
|
|
90
|
-
const mine =
|
|
91
|
-
|
|
92
|
-
|
|
106
|
+
const mine = [];
|
|
107
|
+
const malformed = [];
|
|
108
|
+
for (const r of receipts) {
|
|
109
|
+
if (r.agent_id !== baseline.agent_id)
|
|
110
|
+
continue;
|
|
111
|
+
(tsMs(r.ts) === null ? malformed : mine).push(r);
|
|
112
|
+
}
|
|
113
|
+
mine.sort((a, b) => tsMs(a.ts) - tsMs(b.ts));
|
|
114
|
+
// A receipt we cannot place in time is excluded from every windowed detector — that
|
|
115
|
+
// exclusion must never be silent.
|
|
116
|
+
if (malformed.length > 0) {
|
|
117
|
+
findings.push(finding('malformed-timestamp', 'medium', baseline.agent_id, malformed, `${malformed.length} receipt(s) with unparseable ts — excluded from windowed detectors`, 'parseable ISO timestamps'));
|
|
118
|
+
}
|
|
93
119
|
const minSample = opts.minSample ?? 20;
|
|
94
120
|
const known = new Set(baseline.target_prefixes);
|
|
121
|
+
// 0. chain-gap — receipts carry `prev`; a broken link inside the window means a receipt
|
|
122
|
+
// between the two is missing or was suppressed. A gap is NEVER clean.
|
|
123
|
+
for (let i = 1; i < mine.length; i++) {
|
|
124
|
+
const before = mine[i - 1];
|
|
125
|
+
const cur = mine[i];
|
|
126
|
+
if (typeof cur.prev !== 'string')
|
|
127
|
+
continue; // chain start / foreign data — unverifiable, not a gap
|
|
128
|
+
const { hash: _h, ...bare } = before;
|
|
129
|
+
if (cur.prev !== receiptHash(bare)) {
|
|
130
|
+
findings.push(finding('chain-gap', 'high', baseline.agent_id, [before, cur], `receipt chain broken between ${before.ts} and ${cur.ts} — a receipt in between is missing or was suppressed`, 'contiguous prev linkage — a gap is UNKNOWN, not clean'));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
95
133
|
// 1. novel-target — prefix outside the learned set; high severity if also outside declared scopes
|
|
96
134
|
const novel = new Map();
|
|
97
135
|
for (const r of mine) {
|
|
@@ -111,14 +149,16 @@ export function scan(receipts, baseline, opts = {}) {
|
|
|
111
149
|
rule: 'scope-edge', severity: probes.length > 2 ? 'high' : 'medium', agent_id: baseline.agent_id,
|
|
112
150
|
receipt_hashes: [], targets: [],
|
|
113
151
|
observed: `${probes.length} rejected write(s): ${probes.map((p) => p.error).filter(Boolean).slice(0, 3).join('; ')}`,
|
|
114
|
-
expected: 'no rejected writes', ts: probes[probes.length - 1]?.ts ??
|
|
152
|
+
expected: 'no rejected writes', ts: probes[probes.length - 1]?.ts ?? '1970-01-01T00:00:00.000Z',
|
|
115
153
|
});
|
|
116
154
|
}
|
|
117
155
|
// 3. rate-spike — actions per hour vs baseline (milli-units; +1000 keeps std=0 from firing on +1)
|
|
118
156
|
if (baseline.sample_size >= minSample) {
|
|
119
157
|
const buckets = new Map();
|
|
120
|
-
for (const r of mine)
|
|
121
|
-
|
|
158
|
+
for (const r of mine) {
|
|
159
|
+
const b = hourBucket(tsMs(r.ts));
|
|
160
|
+
buckets.set(b, [...(buckets.get(b) ?? []), r]);
|
|
161
|
+
}
|
|
122
162
|
const z = opts.rateZ ?? 3;
|
|
123
163
|
for (const [hour, rs] of buckets) {
|
|
124
164
|
if (rs.length * 1000 > baseline.rate.mean_milli + z * (baseline.rate.std_milli + 1000)) {
|
|
@@ -139,32 +179,39 @@ export function scan(receipts, baseline, opts = {}) {
|
|
|
139
179
|
for (const rule of opts.sequences ?? [EXFIL_SEQUENCE]) {
|
|
140
180
|
let step = 0;
|
|
141
181
|
let startMs = 0;
|
|
142
|
-
|
|
182
|
+
let evidence = [];
|
|
143
183
|
for (const r of mine) {
|
|
184
|
+
const ms = tsMs(r.ts);
|
|
185
|
+
// stale window: reset FIRST, then re-test this receipt — it may open a new sequence
|
|
186
|
+
if (step > 0 && ms - startMs > rule.windowMs) {
|
|
187
|
+
step = 0;
|
|
188
|
+
evidence = [];
|
|
189
|
+
}
|
|
144
190
|
if (rule.steps[step].test(r.target)) {
|
|
145
191
|
if (step === 0)
|
|
146
|
-
startMs =
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
findings.push(finding(`sequence:${rule.name}`, 'high', baseline.agent_id, [...evidence], evidence.map((e) => e.target).join(' → '), `no ${rule.name} sequence`));
|
|
152
|
-
step = 0;
|
|
153
|
-
evidence.length = 0;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
192
|
+
startMs = ms;
|
|
193
|
+
evidence.push(r);
|
|
194
|
+
step += 1;
|
|
195
|
+
if (step === rule.steps.length) {
|
|
196
|
+
findings.push(finding(`sequence:${rule.name}`, 'high', baseline.agent_id, [...evidence], evidence.map((e) => e.target).join(' → '), `no ${rule.name} sequence`));
|
|
157
197
|
step = 0;
|
|
158
|
-
evidence
|
|
198
|
+
evidence = [];
|
|
159
199
|
}
|
|
160
200
|
}
|
|
201
|
+
else if (step > 0 && rule.steps[0].test(r.target)) {
|
|
202
|
+
// a fresh step-0 match mid-sequence restarts the window from HERE — otherwise an
|
|
203
|
+
// early step-0 pins a stale start and a later, real sequence is never seen
|
|
204
|
+
startMs = ms;
|
|
205
|
+
evidence = [r];
|
|
206
|
+
step = 1;
|
|
207
|
+
}
|
|
161
208
|
}
|
|
162
209
|
}
|
|
163
210
|
// 6. off-hours — activity in hours the baseline says are silent
|
|
164
211
|
if (baseline.sample_size >= minSample) {
|
|
165
|
-
const silent = mine.filter((r) => (baseline.active_hours[
|
|
212
|
+
const silent = mine.filter((r) => (baseline.active_hours[hourOfMs(tsMs(r.ts))] ?? 0) === 0);
|
|
166
213
|
if (silent.length > 0) {
|
|
167
|
-
findings.push(finding('off-hours', 'medium', baseline.agent_id, silent, `${silent.length} action(s) at UTC hour(s) [${[...new Set(silent.map((r) =>
|
|
214
|
+
findings.push(finding('off-hours', 'medium', baseline.agent_id, silent, `${silent.length} action(s) at UTC hour(s) [${[...new Set(silent.map((r) => hourOfMs(tsMs(r.ts))))].join(',')}]`, 'activity only in learned active hours'));
|
|
168
215
|
}
|
|
169
216
|
}
|
|
170
217
|
// 7. wall-crossing — operator mode only (raw payloads pre-hash)
|
|
@@ -210,17 +257,44 @@ export function createWatcher(opts) {
|
|
|
210
257
|
throw new Error(`recent fetch failed: HTTP ${res.status}`);
|
|
211
258
|
const body = (await res.json());
|
|
212
259
|
const fresh = body.receipts.filter((r) => r.index > cursor);
|
|
260
|
+
const all = [];
|
|
261
|
+
// "We were not looking" must NEVER render as "nothing happened": /v1/recent is a
|
|
262
|
+
// capped global feed, so if the oldest fresh index doesn't connect to the cursor,
|
|
263
|
+
// receipts were missed between polls. Report the blind spot as a finding — a
|
|
264
|
+
// confident silence is the most dangerous output a monitor can produce.
|
|
265
|
+
if (cursor >= 0 && fresh.length > 0) {
|
|
266
|
+
const oldest = Math.min(...fresh.map((r) => r.index));
|
|
267
|
+
if (oldest > cursor + 1) {
|
|
268
|
+
const gap = {
|
|
269
|
+
rule: 'unknown-window',
|
|
270
|
+
severity: 'medium',
|
|
271
|
+
agent_id: '*',
|
|
272
|
+
receipt_hashes: [],
|
|
273
|
+
targets: [],
|
|
274
|
+
observed: `ledger indices ${cursor + 1}..${oldest - 1} were never scanned (feed outpaced the poll)`,
|
|
275
|
+
expected: 'contiguous coverage — treat the gap as UNKNOWN, not clean; backfill via /v1/recent?offset=',
|
|
276
|
+
ts: fresh.find((r) => r.index === oldest).receipt.ts,
|
|
277
|
+
};
|
|
278
|
+
const fp = fingerprint(gap);
|
|
279
|
+
if (!seen.has(fp)) {
|
|
280
|
+
seen.add(fp);
|
|
281
|
+
all.push(gap);
|
|
282
|
+
await opts.onFinding(gap);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
213
286
|
for (const r of fresh)
|
|
214
287
|
cursor = Math.max(cursor, r.index);
|
|
215
|
-
const all = [];
|
|
216
288
|
for (const [did, baseline] of Object.entries(opts.baselines)) {
|
|
217
289
|
const mine = fresh.filter((r) => r.receipt.agent_id === did).map((r) => ({ ...r.receipt, hash: r.hash }));
|
|
218
290
|
if (mine.length === 0)
|
|
219
291
|
continue;
|
|
220
292
|
// Rolling window: append, then trim to `windowMs` behind the newest receipt.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
buffers[did]
|
|
293
|
+
// Parsed-UTC ordering (offset timestamps sort correctly); unparseable ts are kept
|
|
294
|
+
// so scan() can report them rather than silently dropping them here.
|
|
295
|
+
const buf = [...(buffers[did] ?? []), ...mine].sort((a, b) => (tsMs(a.ts) ?? 0) - (tsMs(b.ts) ?? 0));
|
|
296
|
+
const newest = tsMs(buf[buf.length - 1].ts) ?? 0;
|
|
297
|
+
buffers[did] = buf.filter((r) => newest - (tsMs(r.ts) ?? newest) <= windowMs);
|
|
224
298
|
for (const f of scan(buffers[did], baseline, opts.scan)) {
|
|
225
299
|
const fp = fingerprint(f);
|
|
226
300
|
if (seen.has(fp))
|
|
@@ -236,6 +310,28 @@ export function createWatcher(opts) {
|
|
|
236
310
|
},
|
|
237
311
|
};
|
|
238
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Could-reach vs did-reach. Standing authority an agent never uses is pure risk —
|
|
315
|
+
* the first thing to cut after an incident, and the first thing an underwriter asks
|
|
316
|
+
* about (`insurance` flags WILDCARD_AUTHORITY; this shows the whole surface). Facts,
|
|
317
|
+
* not a score — a `*` scope is reported as one unused scope, not silently expanded.
|
|
318
|
+
*/
|
|
319
|
+
export function blastRadius(baseline) {
|
|
320
|
+
// used_prefixes are TRUNCATED to two segments, so a concrete deeper scope like
|
|
321
|
+
// `crm.contacts.read` must relate to the prefix `crm.contacts` in EITHER direction —
|
|
322
|
+
// otherwise a fully compliant agent reads as both unused-authority and undeclared.
|
|
323
|
+
const related = (scope, p) => {
|
|
324
|
+
if (scope === '*')
|
|
325
|
+
return true;
|
|
326
|
+
const s = scope.endsWith('.*') ? scope.slice(0, -2) : scope;
|
|
327
|
+
return s === p || s.startsWith(`${p}.`) || p.startsWith(`${s}.`);
|
|
328
|
+
};
|
|
329
|
+
const declared = [...baseline.scopes].sort();
|
|
330
|
+
const used = [...baseline.target_prefixes].sort();
|
|
331
|
+
const unused = declared.filter((s) => !used.some((p) => related(s, p)));
|
|
332
|
+
const undeclared = used.filter((p) => !declared.some((s) => related(s, p)));
|
|
333
|
+
return { declared_scopes: declared, used_prefixes: used, unused_scopes: unused, undeclared_prefixes: undeclared };
|
|
334
|
+
}
|
|
239
335
|
/**
|
|
240
336
|
* The default response: a `@zanii/policy` rule turning the flagged prefixes into a
|
|
241
337
|
* `require_approval` speed bump.
|
|
@@ -245,7 +341,7 @@ export function createWatcher(opts) {
|
|
|
245
341
|
* gates the agent's entire surface. That call belongs to a human.
|
|
246
342
|
*/
|
|
247
343
|
export function escalationRule(f) {
|
|
248
|
-
const prefixes = [...new Set(f.targets.map((t) => `${targetPrefix(t)}.*`))];
|
|
344
|
+
const prefixes = [...new Set(f.targets.map((t) => `${targetPrefix(t)}.*`))].sort();
|
|
249
345
|
if (prefixes.length === 0)
|
|
250
346
|
return null;
|
|
251
347
|
return {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zanii/sentinel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Runtime behavioral monitoring for agents ('antivirus for agents'): score drift between what an agent actually does and what it was made to do, from the receipt stream — and the alerts themselves are tamper-evident receipts.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ledger.zanii.agency",
|
package/src/index.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* bump, never auto-revoke; in-scope compromise is the hard case — sequences and rates
|
|
21
21
|
* narrow the window, never to zero.
|
|
22
22
|
*/
|
|
23
|
-
import { jcsHash, scopesAllow, verifyChain, type DelegationCert, type Receipt } from '@zanii/core';
|
|
23
|
+
import { jcsHash, receiptHash, scopesAllow, verifyChain, type DelegationCert, type Receipt } from '@zanii/core';
|
|
24
24
|
|
|
25
25
|
export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
26
26
|
|
|
@@ -52,28 +52,42 @@ export function targetPrefix(target: string): string {
|
|
|
52
52
|
return target.split('.').slice(0, 2).join('.');
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
/** Epoch ms; a naive ts (no offset) is treated as UTC — never local. `null` = unparseable. */
|
|
56
|
+
function tsMs(ts: unknown): number | null {
|
|
57
|
+
if (typeof ts !== 'string' || !/^\d{4}-\d{2}-\d{2}T/.test(ts)) return null;
|
|
58
|
+
const ms = Date.parse(/[zZ]$|[+-]\d{2}:?\d{2}$/.test(ts) ? ts : `${ts}Z`);
|
|
59
|
+
return Number.isNaN(ms) ? null : ms;
|
|
57
60
|
}
|
|
58
61
|
|
|
62
|
+
const hourOfMs = (ms: number): number => new Date(ms).getUTCHours();
|
|
63
|
+
/** Hour bucket as `YYYY-MM-DDTHH` in UTC — offset timestamps land in the right bucket. */
|
|
64
|
+
const hourBucket = (ms: number): string => new Date(Math.floor(ms / 3_600_000) * 3_600_000).toISOString().slice(0, 13);
|
|
65
|
+
|
|
59
66
|
/** Build the drift baseline for one agent from its delegation (declared) + history (learned). */
|
|
60
67
|
export function buildBaseline(
|
|
61
68
|
agentId: string,
|
|
62
69
|
opts: { receipts?: Receipt[]; delegation?: DelegationCert[] } = {},
|
|
63
70
|
): Baseline {
|
|
64
71
|
const history = (opts.receipts ?? []).filter((r) => r.agent_id === agentId);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
let scopes: string[] = [];
|
|
73
|
+
if (opts.delegation) {
|
|
74
|
+
const chain = verifyChain(opts.delegation, { agentId });
|
|
75
|
+
// A failed chain must NOT silently degrade to scopes:[] — scan treats empty scopes as
|
|
76
|
+
// "everything in scope", so detection severity would quietly drop.
|
|
77
|
+
if (!chain.ok) throw new Error(`delegation chain failed verification (${chain.error}) — refusing to build a baseline on it`);
|
|
78
|
+
scopes = chain.effectiveScopes ?? [];
|
|
79
|
+
}
|
|
68
80
|
const prefixes = new Set<string>();
|
|
69
81
|
const hours = new Array<number>(24).fill(0);
|
|
70
82
|
const perHourCounts = new Map<string, number>();
|
|
71
83
|
let intents = 0;
|
|
72
84
|
let actions = 0;
|
|
73
85
|
for (const r of history) {
|
|
86
|
+
const ms = tsMs(r.ts);
|
|
87
|
+
if (ms === null) throw new Error(`receipt has an unparseable ts: ${String(r.ts)}`);
|
|
74
88
|
prefixes.add(targetPrefix(r.target));
|
|
75
|
-
hours[
|
|
76
|
-
const bucket =
|
|
89
|
+
hours[hourOfMs(ms)] = (hours[hourOfMs(ms)] ?? 0) + 1;
|
|
90
|
+
const bucket = hourBucket(ms);
|
|
77
91
|
perHourCounts.set(bucket, (perHourCounts.get(bucket) ?? 0) + 1);
|
|
78
92
|
if (r.action === 'action_intent') intents += 1;
|
|
79
93
|
else actions += 1;
|
|
@@ -157,19 +171,44 @@ function finding(rule: string, severity: Severity, agentId: string, evidence: Sc
|
|
|
157
171
|
targets: [...new Set(evidence.map((r) => r.target))],
|
|
158
172
|
observed,
|
|
159
173
|
expected,
|
|
160
|
-
ts: evidence[evidence.length - 1]?.ts ??
|
|
174
|
+
ts: evidence[evidence.length - 1]?.ts ?? '1970-01-01T00:00:00.000Z',
|
|
161
175
|
};
|
|
162
176
|
}
|
|
163
177
|
|
|
164
178
|
/** Scan a window of an agent's receipts against its baseline. Pure — no I/O. */
|
|
165
179
|
export function scan(receipts: Scanned[], baseline: Baseline, opts: ScanOptions = {}): Finding[] {
|
|
166
180
|
const findings: Finding[] = [];
|
|
167
|
-
const mine =
|
|
168
|
-
|
|
169
|
-
|
|
181
|
+
const mine: Scanned[] = [];
|
|
182
|
+
const malformed: Scanned[] = [];
|
|
183
|
+
for (const r of receipts) {
|
|
184
|
+
if (r.agent_id !== baseline.agent_id) continue;
|
|
185
|
+
(tsMs(r.ts) === null ? malformed : mine).push(r);
|
|
186
|
+
}
|
|
187
|
+
mine.sort((a, b) => tsMs(a.ts)! - tsMs(b.ts)!);
|
|
188
|
+
// A receipt we cannot place in time is excluded from every windowed detector — that
|
|
189
|
+
// exclusion must never be silent.
|
|
190
|
+
if (malformed.length > 0) {
|
|
191
|
+
findings.push(finding('malformed-timestamp', 'medium', baseline.agent_id, malformed,
|
|
192
|
+
`${malformed.length} receipt(s) with unparseable ts — excluded from windowed detectors`,
|
|
193
|
+
'parseable ISO timestamps'));
|
|
194
|
+
}
|
|
170
195
|
const minSample = opts.minSample ?? 20;
|
|
171
196
|
const known = new Set(baseline.target_prefixes);
|
|
172
197
|
|
|
198
|
+
// 0. chain-gap — receipts carry `prev`; a broken link inside the window means a receipt
|
|
199
|
+
// between the two is missing or was suppressed. A gap is NEVER clean.
|
|
200
|
+
for (let i = 1; i < mine.length; i++) {
|
|
201
|
+
const before = mine[i - 1]!;
|
|
202
|
+
const cur = mine[i]!;
|
|
203
|
+
if (typeof cur.prev !== 'string') continue; // chain start / foreign data — unverifiable, not a gap
|
|
204
|
+
const { hash: _h, ...bare } = before;
|
|
205
|
+
if (cur.prev !== receiptHash(bare as Receipt)) {
|
|
206
|
+
findings.push(finding('chain-gap', 'high', baseline.agent_id, [before, cur],
|
|
207
|
+
`receipt chain broken between ${before.ts} and ${cur.ts} — a receipt in between is missing or was suppressed`,
|
|
208
|
+
'contiguous prev linkage — a gap is UNKNOWN, not clean'));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
173
212
|
// 1. novel-target — prefix outside the learned set; high severity if also outside declared scopes
|
|
174
213
|
const novel = new Map<string, Scanned[]>();
|
|
175
214
|
for (const r of mine) {
|
|
@@ -191,14 +230,17 @@ export function scan(receipts: Scanned[], baseline: Baseline, opts: ScanOptions
|
|
|
191
230
|
rule: 'scope-edge', severity: probes.length > 2 ? 'high' : 'medium', agent_id: baseline.agent_id,
|
|
192
231
|
receipt_hashes: [], targets: [],
|
|
193
232
|
observed: `${probes.length} rejected write(s): ${probes.map((p) => p.error).filter(Boolean).slice(0, 3).join('; ')}`,
|
|
194
|
-
expected: 'no rejected writes', ts: probes[probes.length - 1]?.ts ??
|
|
233
|
+
expected: 'no rejected writes', ts: probes[probes.length - 1]?.ts ?? '1970-01-01T00:00:00.000Z',
|
|
195
234
|
});
|
|
196
235
|
}
|
|
197
236
|
|
|
198
237
|
// 3. rate-spike — actions per hour vs baseline (milli-units; +1000 keeps std=0 from firing on +1)
|
|
199
238
|
if (baseline.sample_size >= minSample) {
|
|
200
239
|
const buckets = new Map<string, Scanned[]>();
|
|
201
|
-
for (const r of mine)
|
|
240
|
+
for (const r of mine) {
|
|
241
|
+
const b = hourBucket(tsMs(r.ts)!);
|
|
242
|
+
buckets.set(b, [...(buckets.get(b) ?? []), r]);
|
|
243
|
+
}
|
|
202
244
|
const z = opts.rateZ ?? 3;
|
|
203
245
|
for (const [hour, rs] of buckets) {
|
|
204
246
|
if (rs.length * 1000 > baseline.rate.mean_milli + z * (baseline.rate.std_milli + 1000)) {
|
|
@@ -225,33 +267,40 @@ export function scan(receipts: Scanned[], baseline: Baseline, opts: ScanOptions
|
|
|
225
267
|
for (const rule of opts.sequences ?? [EXFIL_SEQUENCE]) {
|
|
226
268
|
let step = 0;
|
|
227
269
|
let startMs = 0;
|
|
228
|
-
|
|
270
|
+
let evidence: Scanned[] = [];
|
|
229
271
|
for (const r of mine) {
|
|
272
|
+
const ms = tsMs(r.ts)!;
|
|
273
|
+
// stale window: reset FIRST, then re-test this receipt — it may open a new sequence
|
|
274
|
+
if (step > 0 && ms - startMs > rule.windowMs) {
|
|
275
|
+
step = 0;
|
|
276
|
+
evidence = [];
|
|
277
|
+
}
|
|
230
278
|
if (rule.steps[step]!.test(r.target)) {
|
|
231
|
-
if (step === 0) startMs =
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
evidence.map((e) => e.target).join(' → '), `no ${rule.name} sequence`));
|
|
238
|
-
step = 0;
|
|
239
|
-
evidence.length = 0;
|
|
240
|
-
}
|
|
241
|
-
} else {
|
|
279
|
+
if (step === 0) startMs = ms;
|
|
280
|
+
evidence.push(r);
|
|
281
|
+
step += 1;
|
|
282
|
+
if (step === rule.steps.length) {
|
|
283
|
+
findings.push(finding(`sequence:${rule.name}`, 'high', baseline.agent_id, [...evidence],
|
|
284
|
+
evidence.map((e) => e.target).join(' → '), `no ${rule.name} sequence`));
|
|
242
285
|
step = 0;
|
|
243
|
-
evidence
|
|
286
|
+
evidence = [];
|
|
244
287
|
}
|
|
288
|
+
} else if (step > 0 && rule.steps[0]!.test(r.target)) {
|
|
289
|
+
// a fresh step-0 match mid-sequence restarts the window from HERE — otherwise an
|
|
290
|
+
// early step-0 pins a stale start and a later, real sequence is never seen
|
|
291
|
+
startMs = ms;
|
|
292
|
+
evidence = [r];
|
|
293
|
+
step = 1;
|
|
245
294
|
}
|
|
246
295
|
}
|
|
247
296
|
}
|
|
248
297
|
|
|
249
298
|
// 6. off-hours — activity in hours the baseline says are silent
|
|
250
299
|
if (baseline.sample_size >= minSample) {
|
|
251
|
-
const silent = mine.filter((r) => (baseline.active_hours[
|
|
300
|
+
const silent = mine.filter((r) => (baseline.active_hours[hourOfMs(tsMs(r.ts)!)] ?? 0) === 0);
|
|
252
301
|
if (silent.length > 0) {
|
|
253
302
|
findings.push(finding('off-hours', 'medium', baseline.agent_id, silent,
|
|
254
|
-
`${silent.length} action(s) at UTC hour(s) [${[...new Set(silent.map((r) =>
|
|
303
|
+
`${silent.length} action(s) at UTC hour(s) [${[...new Set(silent.map((r) => hourOfMs(tsMs(r.ts)!)))].join(',')}]`,
|
|
255
304
|
'activity only in learned active hours'));
|
|
256
305
|
}
|
|
257
306
|
}
|
|
@@ -333,17 +382,44 @@ export function createWatcher(opts: WatcherOptions): Watcher {
|
|
|
333
382
|
if (!res.ok) throw new Error(`recent fetch failed: HTTP ${res.status}`);
|
|
334
383
|
const body = (await res.json()) as { receipts: Array<{ receipt: Receipt; hash: string; index: number }> };
|
|
335
384
|
const fresh = body.receipts.filter((r) => r.index > cursor);
|
|
336
|
-
for (const r of fresh) cursor = Math.max(cursor, r.index);
|
|
337
385
|
|
|
338
386
|
const all: Finding[] = [];
|
|
387
|
+
// "We were not looking" must NEVER render as "nothing happened": /v1/recent is a
|
|
388
|
+
// capped global feed, so if the oldest fresh index doesn't connect to the cursor,
|
|
389
|
+
// receipts were missed between polls. Report the blind spot as a finding — a
|
|
390
|
+
// confident silence is the most dangerous output a monitor can produce.
|
|
391
|
+
if (cursor >= 0 && fresh.length > 0) {
|
|
392
|
+
const oldest = Math.min(...fresh.map((r) => r.index));
|
|
393
|
+
if (oldest > cursor + 1) {
|
|
394
|
+
const gap: Finding = {
|
|
395
|
+
rule: 'unknown-window',
|
|
396
|
+
severity: 'medium',
|
|
397
|
+
agent_id: '*',
|
|
398
|
+
receipt_hashes: [],
|
|
399
|
+
targets: [],
|
|
400
|
+
observed: `ledger indices ${cursor + 1}..${oldest - 1} were never scanned (feed outpaced the poll)`,
|
|
401
|
+
expected: 'contiguous coverage — treat the gap as UNKNOWN, not clean; backfill via /v1/recent?offset=',
|
|
402
|
+
ts: fresh.find((r) => r.index === oldest)!.receipt.ts,
|
|
403
|
+
};
|
|
404
|
+
const fp = fingerprint(gap);
|
|
405
|
+
if (!seen.has(fp)) {
|
|
406
|
+
seen.add(fp);
|
|
407
|
+
all.push(gap);
|
|
408
|
+
await opts.onFinding(gap);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
for (const r of fresh) cursor = Math.max(cursor, r.index);
|
|
339
413
|
for (const [did, baseline] of Object.entries(opts.baselines)) {
|
|
340
414
|
const mine = fresh.filter((r) => r.receipt.agent_id === did).map((r) => ({ ...r.receipt, hash: r.hash }));
|
|
341
415
|
if (mine.length === 0) continue;
|
|
342
416
|
|
|
343
417
|
// Rolling window: append, then trim to `windowMs` behind the newest receipt.
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
buffers[did]
|
|
418
|
+
// Parsed-UTC ordering (offset timestamps sort correctly); unparseable ts are kept
|
|
419
|
+
// so scan() can report them rather than silently dropping them here.
|
|
420
|
+
const buf = [...(buffers[did] ?? []), ...mine].sort((a, b) => (tsMs(a.ts) ?? 0) - (tsMs(b.ts) ?? 0));
|
|
421
|
+
const newest = tsMs(buf[buf.length - 1]!.ts) ?? 0;
|
|
422
|
+
buffers[did] = buf.filter((r) => newest - (tsMs(r.ts) ?? newest) <= windowMs);
|
|
347
423
|
|
|
348
424
|
for (const f of scan(buffers[did]!, baseline, opts.scan)) {
|
|
349
425
|
const fp = fingerprint(f);
|
|
@@ -359,6 +435,41 @@ export function createWatcher(opts: WatcherOptions): Watcher {
|
|
|
359
435
|
};
|
|
360
436
|
}
|
|
361
437
|
|
|
438
|
+
export interface BlastRadius {
|
|
439
|
+
/** What the delegation allows — the could-reach surface. */
|
|
440
|
+
declared_scopes: string[];
|
|
441
|
+
/** Target prefixes actually observed in history — the did-reach surface. */
|
|
442
|
+
used_prefixes: string[];
|
|
443
|
+
/** Declared scopes with NO observed activity underneath — standing, unused authority. */
|
|
444
|
+
unused_scopes: string[];
|
|
445
|
+
/** Observed prefixes not covered by any declared scope (should be impossible on-ledger). */
|
|
446
|
+
undeclared_prefixes: string[];
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Could-reach vs did-reach. Standing authority an agent never uses is pure risk —
|
|
451
|
+
* the first thing to cut after an incident, and the first thing an underwriter asks
|
|
452
|
+
* about (`insurance` flags WILDCARD_AUTHORITY; this shows the whole surface). Facts,
|
|
453
|
+
* not a score — a `*` scope is reported as one unused scope, not silently expanded.
|
|
454
|
+
*/
|
|
455
|
+
export function blastRadius(baseline: Baseline): BlastRadius {
|
|
456
|
+
// used_prefixes are TRUNCATED to two segments, so a concrete deeper scope like
|
|
457
|
+
// `crm.contacts.read` must relate to the prefix `crm.contacts` in EITHER direction —
|
|
458
|
+
// otherwise a fully compliant agent reads as both unused-authority and undeclared.
|
|
459
|
+
const related = (scope: string, p: string): boolean => {
|
|
460
|
+
if (scope === '*') return true;
|
|
461
|
+
const s = scope.endsWith('.*') ? scope.slice(0, -2) : scope;
|
|
462
|
+
return s === p || s.startsWith(`${p}.`) || p.startsWith(`${s}.`);
|
|
463
|
+
};
|
|
464
|
+
const declared = [...baseline.scopes].sort();
|
|
465
|
+
const used = [...baseline.target_prefixes].sort();
|
|
466
|
+
const unused = declared.filter((s) => !used.some((p) => related(s, p)));
|
|
467
|
+
const undeclared = used.filter(
|
|
468
|
+
(p) => !declared.some((s) => related(s, p)),
|
|
469
|
+
);
|
|
470
|
+
return { declared_scopes: declared, used_prefixes: used, unused_scopes: unused, undeclared_prefixes: undeclared };
|
|
471
|
+
}
|
|
472
|
+
|
|
362
473
|
/**
|
|
363
474
|
* The default response: a `@zanii/policy` rule turning the flagged prefixes into a
|
|
364
475
|
* `require_approval` speed bump.
|
|
@@ -368,7 +479,7 @@ export function createWatcher(opts: WatcherOptions): Watcher {
|
|
|
368
479
|
* gates the agent's entire surface. That call belongs to a human.
|
|
369
480
|
*/
|
|
370
481
|
export function escalationRule(f: Finding): { id: string; effect: 'require_approval'; targets: string[] } | null {
|
|
371
|
-
const prefixes = [...new Set(f.targets.map((t) => `${targetPrefix(t)}.*`))];
|
|
482
|
+
const prefixes = [...new Set(f.targets.map((t) => `${targetPrefix(t)}.*`))].sort();
|
|
372
483
|
if (prefixes.length === 0) return null;
|
|
373
484
|
return {
|
|
374
485
|
id: `sentinel-${f.rule.replace(/[^a-z0-9-]/gi, '-')}-${f.agent_id.slice(-8)}`,
|