@zanii/status-feed 0.3.0 → 0.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 +1 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +410 -403
package/README.md
CHANGED
|
@@ -98,6 +98,7 @@ if (verifyFeed(entries, { signers: [regulatorDid] }).ok) {
|
|
|
98
98
|
|
|
99
99
|
## Changelog
|
|
100
100
|
|
|
101
|
+
- **0.4.0**: `appendEventAsync(feed, event, signer)` takes a raw key or a remote signer (HSM, KMS). Entries are byte-identical to `appendEvent`. Requires `@zanii/core` 0.5.7. Additive.
|
|
101
102
|
- **0.3.0** (unreleased): supervision events. New kinds `supervision.suspended` and
|
|
102
103
|
`supervision.lifted`, with `supervisionEvent`, `supervisionScopeReasons`, `activeSuspensions` and
|
|
103
104
|
`suspensionFor`. Two distinct approval hashes and a reason are required. Additive: entries of the
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
|
|
11
11
|
* the operator cannot rewrite it unseen.
|
|
12
12
|
*/
|
|
13
|
-
import { type RevocationRecord, type SignedObject } from '@zanii/core';
|
|
13
|
+
import { type RemoteSigner, type RevocationRecord, type SignedObject } from '@zanii/core';
|
|
14
14
|
export declare const FEED_TYPE: "zanii.status_feed";
|
|
15
15
|
export declare const EVENT_KINDS: readonly ["delegation.revoked", "certificate.suspended", "certificate.revoked", "certificate.reinstated", "incident.opened", "incident.closed", "jurisdiction.issued", "jurisdiction.expired", "threat.signature", "threat.retracted", "supervision.suspended", "supervision.lifted"];
|
|
16
16
|
export type EventKind = (typeof EVENT_KINDS)[number];
|
|
@@ -131,14 +131,15 @@ export declare function matchThreat(signatures: ThreatSignature[], action: {
|
|
|
131
131
|
}): ThreatSignature | null;
|
|
132
132
|
/** The last entry's position, or null for an empty feed. */
|
|
133
133
|
export declare function feedHead(entries: FeedEntry[]): FeedHead | null;
|
|
134
|
-
/**
|
|
135
|
-
* Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
|
|
136
|
-
* `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
|
|
137
|
-
*/
|
|
138
134
|
export declare function appendEvent(feed: Feed, event: StatusEvent, signerKey: Uint8Array): {
|
|
139
135
|
entry: FeedEntry;
|
|
140
136
|
head: FeedHead;
|
|
141
137
|
};
|
|
138
|
+
/** `appendEvent` with a raw key or a remote signer (HSM, KMS): the key need not enter this process. */
|
|
139
|
+
export declare function appendEventAsync(feed: Feed, event: StatusEvent, signer: Uint8Array | RemoteSigner): Promise<{
|
|
140
|
+
entry: FeedEntry;
|
|
141
|
+
head: FeedHead;
|
|
142
|
+
}>;
|
|
142
143
|
export interface VerifyFeedOptions {
|
|
143
144
|
/** The DIDs allowed to sign entries (key rotation: list old and new). */
|
|
144
145
|
signers: string[];
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;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
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
|
|
11
11
|
* the operator cannot rewrite it unseen.
|
|
12
12
|
*/
|
|
13
|
-
import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, verifySignedObject } from '@zanii/core';
|
|
13
|
+
import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, signObjectAsync, verifySignedObject } from '@zanii/core';
|
|
14
14
|
export const FEED_TYPE = 'zanii.status_feed';
|
|
15
15
|
export const EVENT_KINDS = [
|
|
16
16
|
'delegation.revoked',
|
|
@@ -219,7 +219,7 @@ export function feedHead(entries) {
|
|
|
219
219
|
* Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
|
|
220
220
|
* `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
|
|
221
221
|
*/
|
|
222
|
-
|
|
222
|
+
function unsignedEntry(feed, event) {
|
|
223
223
|
if (typeof feed?.jurisdiction !== 'string' || !feed.jurisdiction)
|
|
224
224
|
throw new Error('status-feed: feed.jurisdiction is required');
|
|
225
225
|
const ev = normalize(event);
|
|
@@ -231,10 +231,15 @@ export function appendEvent(feed, event, signerKey) {
|
|
|
231
231
|
throw new Error('status-feed: the feed holds another jurisdiction');
|
|
232
232
|
if (last && ms(ev.ts) < ms(last.event.ts))
|
|
233
233
|
throw new Error('status-feed: event is dated before the feed head');
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
return { v: 1, type: FEED_TYPE, jurisdiction: feed.jurisdiction, seq: last ? last.seq + 1 : 1, prev: last ? entryHash(last) : null, event: ev };
|
|
235
|
+
}
|
|
236
|
+
export function appendEvent(feed, event, signerKey) {
|
|
237
|
+
const entry = signObject(unsignedEntry(feed, event), signerKey);
|
|
238
|
+
return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
|
|
239
|
+
}
|
|
240
|
+
/** `appendEvent` with a raw key or a remote signer (HSM, KMS): the key need not enter this process. */
|
|
241
|
+
export async function appendEventAsync(feed, event, signer) {
|
|
242
|
+
const entry = await signObjectAsync(unsignedEntry(feed, event), signer);
|
|
238
243
|
return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
|
|
239
244
|
}
|
|
240
245
|
/** Chain continuity, sequence without gaps, signatures by allowed signers, non-decreasing time, well-formed events. */
|
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/status-feed",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "One signed, append-only, hash-chained status feed per jurisdiction: delegation revocations, Certify certificate suspensions, revocations and reinstatements, incident references and jurisdiction bindings, each with evidence hashes. Append, verify (chain, signatures, time, gaps), read since a sequence number, render as Atom or JSON Feed, and anchor the head as a Ledger receipt payload.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ledger.zanii.agency",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"node": ">=18"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@zanii/core": "^0.5.
|
|
29
|
+
"@zanii/core": "^0.5.7"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@noble/curves": "^1.8.1",
|
package/src/index.ts
CHANGED
|
@@ -1,403 +1,410 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @zanii/status-feed: one signed, append-only, hash-chained feed of status events per
|
|
3
|
-
* jurisdiction. Each entry names the previous entry's hash and its sequence number, is
|
|
4
|
-
* signed by the feed operator (a regulator or the Ledger operator) and carries the hashes
|
|
5
|
-
* of the evidence behind the event: a delegation revocation, a Certify status document,
|
|
6
|
-
* an incident report, a jurisdiction binding.
|
|
7
|
-
*
|
|
8
|
-
* The feed says that its signer published these events in this order. It does not make
|
|
9
|
-
* the events true: a verifier checks the evidence the hashes name. Anchoring the head as
|
|
10
|
-
* a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
|
|
11
|
-
* the operator cannot rewrite it unseen.
|
|
12
|
-
*/
|
|
13
|
-
import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, verifySignedObject, type RevocationRecord, type SignedObject } from '@zanii/core';
|
|
14
|
-
|
|
15
|
-
export const FEED_TYPE = 'zanii.status_feed' as const;
|
|
16
|
-
|
|
17
|
-
export const EVENT_KINDS = [
|
|
18
|
-
'delegation.revoked',
|
|
19
|
-
'certificate.suspended',
|
|
20
|
-
'certificate.revoked',
|
|
21
|
-
'certificate.reinstated',
|
|
22
|
-
'incident.opened',
|
|
23
|
-
'incident.closed',
|
|
24
|
-
'jurisdiction.issued',
|
|
25
|
-
'jurisdiction.expired',
|
|
26
|
-
'threat.signature',
|
|
27
|
-
'threat.retracted',
|
|
28
|
-
'supervision.suspended',
|
|
29
|
-
'supervision.lifted',
|
|
30
|
-
] as const;
|
|
31
|
-
export type EventKind = (typeof EVENT_KINDS)[number];
|
|
32
|
-
|
|
33
|
-
/** Certify status reason codes, versions 1 to 3 (Certify spec/status.md sections 2, 6, 7). */
|
|
34
|
-
export const CERTIFY_REASONS = [
|
|
35
|
-
'FINGERPRINT_MISMATCH', 'RETEST_OVERDUE', 'RETEST_FAILED', 'INCIDENT', 'APPLICANT_REQUEST',
|
|
36
|
-
'ISSUER_ERROR', 'LICENCE_WITHDRAWN', 'AUDIT_EXPIRED', 'MARK_MISUSE', 'FALSE_DECLARATION', 'EVIDENCE_LAPSED',
|
|
37
|
-
] as const;
|
|
38
|
-
|
|
39
|
-
export interface StatusEvent {
|
|
40
|
-
kind: EventKind;
|
|
41
|
-
/** The did:key the event is about (usually the agent). */
|
|
42
|
-
subject: string;
|
|
43
|
-
/** What the event names: a delegation cert hash, a certificate hash, an incident id, a binding hash. */
|
|
44
|
-
ref: string;
|
|
45
|
-
ts: string;
|
|
46
|
-
/** Certify reason code for certificate suspend and revoke; null for reinstate; free text or null otherwise. */
|
|
47
|
-
reason: string | null;
|
|
48
|
-
/** `sha256:` hashes of the evidence; sorted and distinct in the entry. */
|
|
49
|
-
evidence: string[];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export type FeedEntry = SignedObject<{
|
|
53
|
-
v: 1;
|
|
54
|
-
type: typeof FEED_TYPE;
|
|
55
|
-
jurisdiction: string;
|
|
56
|
-
seq: number;
|
|
57
|
-
prev: string | null;
|
|
58
|
-
event: StatusEvent;
|
|
59
|
-
}>;
|
|
60
|
-
|
|
61
|
-
export interface FeedHead { seq: number; hash: string }
|
|
62
|
-
export interface Feed { jurisdiction: string; entries: FeedEntry[] }
|
|
63
|
-
|
|
64
|
-
const HASH = /^sha256:[0-9a-f]{64}$/;
|
|
65
|
-
const ISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/;
|
|
66
|
-
|
|
67
|
-
/** Epoch ms of a strict ISO 8601 UTC-or-offset timestamp, or NaN. */
|
|
68
|
-
function ms(ts: unknown): number {
|
|
69
|
-
return typeof ts === 'string' && ISO.test(ts) ? Date.parse(ts) : NaN;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const canonicalJson = (x: unknown): string => new TextDecoder().decode(canonicalBytes(x));
|
|
73
|
-
|
|
74
|
-
/** The hash later entries chain to: `jcsHash` of the whole signed entry. */
|
|
75
|
-
export function entryHash(entry: FeedEntry): string {
|
|
76
|
-
return jcsHash(entry);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** Why an event is malformed; empty when it is well formed. */
|
|
80
|
-
export function eventReasons(e: unknown): string[] {
|
|
81
|
-
if (!e || typeof e !== 'object' || Array.isArray(e)) return ['event is not an object'];
|
|
82
|
-
const ev = e as Record<string, unknown>;
|
|
83
|
-
const out: string[] = [];
|
|
84
|
-
const keys = Object.keys(ev).sort().join(',');
|
|
85
|
-
if (keys !== 'evidence,kind,reason,ref,subject,ts') out.push('event has unexpected or missing fields');
|
|
86
|
-
if (!(EVENT_KINDS as readonly unknown[]).includes(ev.kind)) out.push('unknown event kind');
|
|
87
|
-
if (typeof ev.subject !== 'string' || !ev.subject.startsWith('did:')) out.push('event subject is not a DID');
|
|
88
|
-
if (typeof ev.ref !== 'string' || !ev.ref) out.push('event ref is empty');
|
|
89
|
-
if (Number.isNaN(ms(ev.ts))) out.push('event ts is not an ISO timestamp');
|
|
90
|
-
const ok = Array.isArray(ev.evidence) && ev.evidence.length > 0 && ev.evidence.every((h) => typeof h === 'string' && HASH.test(h));
|
|
91
|
-
if (!ok) out.push('event evidence must be a non-empty list of sha256 hashes');
|
|
92
|
-
else if (new Set(ev.evidence as string[]).size !== (ev.evidence as string[]).length || [...(ev.evidence as string[])].sort().join() !== (ev.evidence as string[]).join()) out.push('event evidence is not sorted and distinct');
|
|
93
|
-
if (ev.kind === 'certificate.suspended' || ev.kind === 'certificate.revoked') {
|
|
94
|
-
if (!(CERTIFY_REASONS as readonly unknown[]).includes(ev.reason)) out.push('certificate suspend or revoke needs a Certify reason code');
|
|
95
|
-
} else if (ev.kind === 'certificate.reinstated') {
|
|
96
|
-
if (ev.reason !== null) out.push('certificate reinstatement carries no reason');
|
|
97
|
-
} else if (ev.reason !== null && (typeof ev.reason !== 'string' || !ev.reason)) out.push('event reason must be null or a non-empty string');
|
|
98
|
-
if (ev.kind === 'threat.signature' || ev.kind === 'threat.retracted') out.push(...threatRefReasons(ev.ref));
|
|
99
|
-
if (ev.kind === 'threat.signature' && (typeof ev.reason !== 'string' || !ev.reason)) out.push('a threat signature needs a label in reason');
|
|
100
|
-
if (ev.kind === 'supervision.suspended' || ev.kind === 'supervision.lifted') {
|
|
101
|
-
out.push(...supervisionScopeReasons(ev.ref));
|
|
102
|
-
if (typeof ev.reason !== 'string' || !ev.reason) out.push('a supervision event needs a reason');
|
|
103
|
-
if (Array.isArray(ev.evidence) && new Set(ev.evidence).size < 2) out.push('a supervision event needs at least two evidence hashes (the two approvals)');
|
|
104
|
-
}
|
|
105
|
-
return out;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// ---------------------------------------------------------------------------------- //
|
|
109
|
-
// Supervision: a regulator suspends or lifts an agent, every agent of an owner, or a system
|
|
110
|
-
// ---------------------------------------------------------------------------------- //
|
|
111
|
-
|
|
112
|
-
const SYSTEM_KEY = /^[A-Za-z0-9._-]{1,128}$/;
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Why a supervision `ref` (the scope) is malformed. `agent` covers the subject agent DID,
|
|
116
|
-
* `owner` covers every agent the subject owner DID delegated to, `system:<key>` covers the
|
|
117
|
-
* agents of that registered AI system of the subject owner.
|
|
118
|
-
*/
|
|
119
|
-
export function supervisionScopeReasons(ref: unknown): string[] {
|
|
120
|
-
if (ref === 'agent' || ref === 'owner') return [];
|
|
121
|
-
const m = typeof ref === 'string' ? /^system:(.*)$/s.exec(ref) : null;
|
|
122
|
-
if (!m) return ['supervision scope must be agent, owner or system:<key>'];
|
|
123
|
-
return SYSTEM_KEY.test(m[1]!) ? [] : ['supervision system key is invalid'];
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export type SupervisionScope = 'agent' | 'owner' | { system: string };
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Suspend or lift. `approvals` are the hashes of the two (or more) signed approval records, so
|
|
130
|
-
* the feed shows that more than one person decided. No personal data in `reason`: the feed is public.
|
|
131
|
-
*/
|
|
132
|
-
export function supervisionEvent(s: {
|
|
133
|
-
action: 'suspend' | 'lift'; subject: string; scope: SupervisionScope; reason: string; ts: string;
|
|
134
|
-
approvals: string[]; evidence?: string[];
|
|
135
|
-
}): StatusEvent {
|
|
136
|
-
if (s.action !== 'suspend' && s.action !== 'lift') throw new Error('status-feed: action must be suspend or lift');
|
|
137
|
-
if (!Array.isArray(s.approvals) || new Set(s.approvals).size < 2) throw new Error('status-feed: a supervision event needs two distinct approvals');
|
|
138
|
-
const ref = typeof s.scope === 'string' ? s.scope : `system:${s.scope?.system}`;
|
|
139
|
-
const kind = s.action === 'suspend' ? 'supervision.suspended' : 'supervision.lifted';
|
|
140
|
-
return normalize({ kind, subject: s.subject, ref, ts: s.ts, reason: s.reason, evidence: [...s.approvals, ...(s.evidence ?? [])] });
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export interface Suspension { subject: string; ref: string; reason: string; ts: string; seq: number }
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Suspensions in force after replaying the feed in order: the latest event per subject and
|
|
147
|
-
* scope wins. Verify the feed first (`verifyFeed`); this does not check signatures.
|
|
148
|
-
*/
|
|
149
|
-
export function activeSuspensions(entries: FeedEntry[]): Suspension[] {
|
|
150
|
-
const state = new Map<string, Suspension | null>();
|
|
151
|
-
for (const e of entries) {
|
|
152
|
-
const ev = e.event;
|
|
153
|
-
if (ev.kind !== 'supervision.suspended' && ev.kind !== 'supervision.lifted') continue;
|
|
154
|
-
if (supervisionScopeReasons(ev.ref).length) continue;
|
|
155
|
-
const key = `${ev.subject} ${ev.ref}`;
|
|
156
|
-
state.set(key, ev.kind === 'supervision.suspended' ? { subject: ev.subject, ref: ev.ref, reason: ev.reason ?? '', ts: ev.ts, seq: e.seq } : null);
|
|
157
|
-
}
|
|
158
|
-
return [...state.values()].filter((x): x is Suspension => x !== null).sort((a, b) => a.seq - b.seq);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/** The first suspension covering an agent (by its own DID, its owner, or its system), or null. */
|
|
162
|
-
export function suspensionFor(suspensions: Suspension[], who: { agent: string; owner?: string; system?: string }): Suspension | null {
|
|
163
|
-
for (const s of suspensions) {
|
|
164
|
-
if (s.ref === 'agent' && s.subject === who.agent) return s;
|
|
165
|
-
if (s.ref === 'owner' && who.owner && s.subject === who.owner) return s;
|
|
166
|
-
if (who.owner && who.system && s.subject === who.owner && s.ref === `system:${who.system}`) return s;
|
|
167
|
-
}
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// ---------------------------------------------------------------------------------- //
|
|
172
|
-
// Threat signatures: a threat one member blocked, shared so every member blocks it too
|
|
173
|
-
// ---------------------------------------------------------------------------------- //
|
|
174
|
-
|
|
175
|
-
const THREAT_TARGET = /^[A-Za-z0-9._:*-]{1,128}$/;
|
|
176
|
-
const THREAT_TEXT = /^[\x21-\x7e][\x20-\x7e]{2,198}[\x21-\x7e]$/;
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Why a threat `ref` is malformed. `target:<pattern>` blocks actions whose target the scope
|
|
180
|
-
* pattern covers; `contains:<text>` blocks actions whose arguments contain the text, ignoring
|
|
181
|
-
* ASCII case. The text is 4 to 200 printable ASCII characters with no surrounding spaces: plain
|
|
182
|
-
* text, never a regular expression, so a feed entry cannot make a member's matcher slow.
|
|
183
|
-
*/
|
|
184
|
-
export function threatRefReasons(ref: unknown): string[] {
|
|
185
|
-
const m = typeof ref === 'string' ? /^(target|contains):(.*)$/s.exec(ref) : null;
|
|
186
|
-
if (!m) return ['threat ref must be target:<pattern> or contains:<text>'];
|
|
187
|
-
if (m[1] === 'target' && !THREAT_TARGET.test(m[2]!)) return ['threat target pattern is invalid'];
|
|
188
|
-
if (m[1] === 'contains' && !THREAT_TEXT.test(m[2]!)) return ['threat text must be 4 to 200 printable ASCII characters without surrounding spaces'];
|
|
189
|
-
return [];
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/** A new threat signature, citing the evidence behind it (for example the blocking guard decision receipt). */
|
|
193
|
-
export function threatSignatureEvent(t: { match: 'target' | 'contains'; value: string; reporter: string; label: string; ts: string; evidence: string[] }): StatusEvent {
|
|
194
|
-
if (t.match !== 'target' && t.match !== 'contains') throw new Error('status-feed: match must be target or contains');
|
|
195
|
-
return normalize({ kind: 'threat.signature', subject: t.reporter, ref: `${t.match}:${t.value}`, ts: t.ts, reason: t.label, evidence: t.evidence });
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/** Withdraw a signature (for example a false positive). A later `threat.signature` with the same ref restores it. */
|
|
199
|
-
export function threatRetractionEvent(t: { ref: string; reporter: string; ts: string; evidence: string[]; reason?: string | null }): StatusEvent {
|
|
200
|
-
return normalize({ kind: 'threat.retracted', subject: t.reporter, ref: t.ref, ts: t.ts, reason: t.reason ?? null, evidence: t.evidence });
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export interface ThreatSignature { ref: string; match: 'target' | 'contains'; value: string; label: string; seq: number }
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* The signatures in force after replaying the feed in order: the latest event per ref wins.
|
|
207
|
-
* Verify the feed first (`verifyFeed`); this does not check signatures.
|
|
208
|
-
*/
|
|
209
|
-
export function activeThreatSignatures(entries: FeedEntry[]): ThreatSignature[] {
|
|
210
|
-
const state = new Map<string, ThreatSignature | null>();
|
|
211
|
-
for (const e of entries) {
|
|
212
|
-
const ev = e.event;
|
|
213
|
-
if (ev.kind === 'threat.signature' && threatRefReasons(ev.ref).length === 0) {
|
|
214
|
-
const i = ev.ref.indexOf(':');
|
|
215
|
-
state.set(ev.ref, { ref: ev.ref, match: ev.ref.slice(0, i) as 'target' | 'contains', value: ev.ref.slice(i + 1), label: ev.reason ?? '', seq: e.seq });
|
|
216
|
-
} else if (ev.kind === 'threat.retracted') state.set(ev.ref, null);
|
|
217
|
-
}
|
|
218
|
-
return [...state.values()].filter((x): x is ThreatSignature => x !== null).sort((a, b) => a.seq - b.seq);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const asciiLower = (s: string) => s.replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32));
|
|
222
|
-
|
|
223
|
-
/** The first signature that matches an action, or null. `text` is the action's arguments as text. */
|
|
224
|
-
export function matchThreat(signatures: ThreatSignature[], action: { target: string; text?: string }): ThreatSignature | null {
|
|
225
|
-
const text = asciiLower(action.text ?? '');
|
|
226
|
-
for (const sig of signatures) {
|
|
227
|
-
if (sig.match === 'target' ? scopeCovers(sig.value, action.target) : text.includes(asciiLower(sig.value))) return sig;
|
|
228
|
-
}
|
|
229
|
-
return null;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function normalize(e: StatusEvent): StatusEvent {
|
|
233
|
-
return {
|
|
234
|
-
kind: e.kind, subject: e.subject, ref: e.ref, ts: e.ts, reason: e.reason ?? null,
|
|
235
|
-
evidence: Array.isArray(e.evidence) ? [...new Set(e.evidence)].sort() : e.evidence,
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/** The last entry's position, or null for an empty feed. */
|
|
240
|
-
export function feedHead(entries: FeedEntry[]): FeedHead | null {
|
|
241
|
-
const last = entries[entries.length - 1];
|
|
242
|
-
return last ? { seq: last.seq, hash: entryHash(last) } : null;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
|
|
247
|
-
* `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
|
|
248
|
-
*/
|
|
249
|
-
|
|
250
|
-
if (typeof feed?.jurisdiction !== 'string' || !feed.jurisdiction) throw new Error('status-feed: feed.jurisdiction is required');
|
|
251
|
-
const ev = normalize(event);
|
|
252
|
-
const reasons = eventReasons(ev);
|
|
253
|
-
if (reasons.length) throw new Error(`status-feed: ${reasons.join('; ')}`);
|
|
254
|
-
const last = feed.entries[feed.entries.length - 1];
|
|
255
|
-
if (last && last.jurisdiction !== feed.jurisdiction) throw new Error('status-feed: the feed holds another jurisdiction');
|
|
256
|
-
if (last && ms(ev.ts) < ms(last.event.ts)) throw new Error('status-feed: event is dated before the feed head');
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if (e.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (
|
|
297
|
-
if (!
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
return normalize({ kind: `
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
export
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
];
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @zanii/status-feed: one signed, append-only, hash-chained feed of status events per
|
|
3
|
+
* jurisdiction. Each entry names the previous entry's hash and its sequence number, is
|
|
4
|
+
* signed by the feed operator (a regulator or the Ledger operator) and carries the hashes
|
|
5
|
+
* of the evidence behind the event: a delegation revocation, a Certify status document,
|
|
6
|
+
* an incident report, a jurisdiction binding.
|
|
7
|
+
*
|
|
8
|
+
* The feed says that its signer published these events in this order. It does not make
|
|
9
|
+
* the events true: a verifier checks the evidence the hashes name. Anchoring the head as
|
|
10
|
+
* a Ledger receipt (`anchorFeedHead`) fixes the feed's history in the transparency log so
|
|
11
|
+
* the operator cannot rewrite it unseen.
|
|
12
|
+
*/
|
|
13
|
+
import { canonicalBytes, certHash, jcsHash, scopeCovers, verifyRevocation, signObject, signObjectAsync, verifySignedObject, type RemoteSigner, type RevocationRecord, type SignedObject } from '@zanii/core';
|
|
14
|
+
|
|
15
|
+
export const FEED_TYPE = 'zanii.status_feed' as const;
|
|
16
|
+
|
|
17
|
+
export const EVENT_KINDS = [
|
|
18
|
+
'delegation.revoked',
|
|
19
|
+
'certificate.suspended',
|
|
20
|
+
'certificate.revoked',
|
|
21
|
+
'certificate.reinstated',
|
|
22
|
+
'incident.opened',
|
|
23
|
+
'incident.closed',
|
|
24
|
+
'jurisdiction.issued',
|
|
25
|
+
'jurisdiction.expired',
|
|
26
|
+
'threat.signature',
|
|
27
|
+
'threat.retracted',
|
|
28
|
+
'supervision.suspended',
|
|
29
|
+
'supervision.lifted',
|
|
30
|
+
] as const;
|
|
31
|
+
export type EventKind = (typeof EVENT_KINDS)[number];
|
|
32
|
+
|
|
33
|
+
/** Certify status reason codes, versions 1 to 3 (Certify spec/status.md sections 2, 6, 7). */
|
|
34
|
+
export const CERTIFY_REASONS = [
|
|
35
|
+
'FINGERPRINT_MISMATCH', 'RETEST_OVERDUE', 'RETEST_FAILED', 'INCIDENT', 'APPLICANT_REQUEST',
|
|
36
|
+
'ISSUER_ERROR', 'LICENCE_WITHDRAWN', 'AUDIT_EXPIRED', 'MARK_MISUSE', 'FALSE_DECLARATION', 'EVIDENCE_LAPSED',
|
|
37
|
+
] as const;
|
|
38
|
+
|
|
39
|
+
export interface StatusEvent {
|
|
40
|
+
kind: EventKind;
|
|
41
|
+
/** The did:key the event is about (usually the agent). */
|
|
42
|
+
subject: string;
|
|
43
|
+
/** What the event names: a delegation cert hash, a certificate hash, an incident id, a binding hash. */
|
|
44
|
+
ref: string;
|
|
45
|
+
ts: string;
|
|
46
|
+
/** Certify reason code for certificate suspend and revoke; null for reinstate; free text or null otherwise. */
|
|
47
|
+
reason: string | null;
|
|
48
|
+
/** `sha256:` hashes of the evidence; sorted and distinct in the entry. */
|
|
49
|
+
evidence: string[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type FeedEntry = SignedObject<{
|
|
53
|
+
v: 1;
|
|
54
|
+
type: typeof FEED_TYPE;
|
|
55
|
+
jurisdiction: string;
|
|
56
|
+
seq: number;
|
|
57
|
+
prev: string | null;
|
|
58
|
+
event: StatusEvent;
|
|
59
|
+
}>;
|
|
60
|
+
|
|
61
|
+
export interface FeedHead { seq: number; hash: string }
|
|
62
|
+
export interface Feed { jurisdiction: string; entries: FeedEntry[] }
|
|
63
|
+
|
|
64
|
+
const HASH = /^sha256:[0-9a-f]{64}$/;
|
|
65
|
+
const ISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/;
|
|
66
|
+
|
|
67
|
+
/** Epoch ms of a strict ISO 8601 UTC-or-offset timestamp, or NaN. */
|
|
68
|
+
function ms(ts: unknown): number {
|
|
69
|
+
return typeof ts === 'string' && ISO.test(ts) ? Date.parse(ts) : NaN;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const canonicalJson = (x: unknown): string => new TextDecoder().decode(canonicalBytes(x));
|
|
73
|
+
|
|
74
|
+
/** The hash later entries chain to: `jcsHash` of the whole signed entry. */
|
|
75
|
+
export function entryHash(entry: FeedEntry): string {
|
|
76
|
+
return jcsHash(entry);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Why an event is malformed; empty when it is well formed. */
|
|
80
|
+
export function eventReasons(e: unknown): string[] {
|
|
81
|
+
if (!e || typeof e !== 'object' || Array.isArray(e)) return ['event is not an object'];
|
|
82
|
+
const ev = e as Record<string, unknown>;
|
|
83
|
+
const out: string[] = [];
|
|
84
|
+
const keys = Object.keys(ev).sort().join(',');
|
|
85
|
+
if (keys !== 'evidence,kind,reason,ref,subject,ts') out.push('event has unexpected or missing fields');
|
|
86
|
+
if (!(EVENT_KINDS as readonly unknown[]).includes(ev.kind)) out.push('unknown event kind');
|
|
87
|
+
if (typeof ev.subject !== 'string' || !ev.subject.startsWith('did:')) out.push('event subject is not a DID');
|
|
88
|
+
if (typeof ev.ref !== 'string' || !ev.ref) out.push('event ref is empty');
|
|
89
|
+
if (Number.isNaN(ms(ev.ts))) out.push('event ts is not an ISO timestamp');
|
|
90
|
+
const ok = Array.isArray(ev.evidence) && ev.evidence.length > 0 && ev.evidence.every((h) => typeof h === 'string' && HASH.test(h));
|
|
91
|
+
if (!ok) out.push('event evidence must be a non-empty list of sha256 hashes');
|
|
92
|
+
else if (new Set(ev.evidence as string[]).size !== (ev.evidence as string[]).length || [...(ev.evidence as string[])].sort().join() !== (ev.evidence as string[]).join()) out.push('event evidence is not sorted and distinct');
|
|
93
|
+
if (ev.kind === 'certificate.suspended' || ev.kind === 'certificate.revoked') {
|
|
94
|
+
if (!(CERTIFY_REASONS as readonly unknown[]).includes(ev.reason)) out.push('certificate suspend or revoke needs a Certify reason code');
|
|
95
|
+
} else if (ev.kind === 'certificate.reinstated') {
|
|
96
|
+
if (ev.reason !== null) out.push('certificate reinstatement carries no reason');
|
|
97
|
+
} else if (ev.reason !== null && (typeof ev.reason !== 'string' || !ev.reason)) out.push('event reason must be null or a non-empty string');
|
|
98
|
+
if (ev.kind === 'threat.signature' || ev.kind === 'threat.retracted') out.push(...threatRefReasons(ev.ref));
|
|
99
|
+
if (ev.kind === 'threat.signature' && (typeof ev.reason !== 'string' || !ev.reason)) out.push('a threat signature needs a label in reason');
|
|
100
|
+
if (ev.kind === 'supervision.suspended' || ev.kind === 'supervision.lifted') {
|
|
101
|
+
out.push(...supervisionScopeReasons(ev.ref));
|
|
102
|
+
if (typeof ev.reason !== 'string' || !ev.reason) out.push('a supervision event needs a reason');
|
|
103
|
+
if (Array.isArray(ev.evidence) && new Set(ev.evidence).size < 2) out.push('a supervision event needs at least two evidence hashes (the two approvals)');
|
|
104
|
+
}
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ---------------------------------------------------------------------------------- //
|
|
109
|
+
// Supervision: a regulator suspends or lifts an agent, every agent of an owner, or a system
|
|
110
|
+
// ---------------------------------------------------------------------------------- //
|
|
111
|
+
|
|
112
|
+
const SYSTEM_KEY = /^[A-Za-z0-9._-]{1,128}$/;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Why a supervision `ref` (the scope) is malformed. `agent` covers the subject agent DID,
|
|
116
|
+
* `owner` covers every agent the subject owner DID delegated to, `system:<key>` covers the
|
|
117
|
+
* agents of that registered AI system of the subject owner.
|
|
118
|
+
*/
|
|
119
|
+
export function supervisionScopeReasons(ref: unknown): string[] {
|
|
120
|
+
if (ref === 'agent' || ref === 'owner') return [];
|
|
121
|
+
const m = typeof ref === 'string' ? /^system:(.*)$/s.exec(ref) : null;
|
|
122
|
+
if (!m) return ['supervision scope must be agent, owner or system:<key>'];
|
|
123
|
+
return SYSTEM_KEY.test(m[1]!) ? [] : ['supervision system key is invalid'];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export type SupervisionScope = 'agent' | 'owner' | { system: string };
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Suspend or lift. `approvals` are the hashes of the two (or more) signed approval records, so
|
|
130
|
+
* the feed shows that more than one person decided. No personal data in `reason`: the feed is public.
|
|
131
|
+
*/
|
|
132
|
+
export function supervisionEvent(s: {
|
|
133
|
+
action: 'suspend' | 'lift'; subject: string; scope: SupervisionScope; reason: string; ts: string;
|
|
134
|
+
approvals: string[]; evidence?: string[];
|
|
135
|
+
}): StatusEvent {
|
|
136
|
+
if (s.action !== 'suspend' && s.action !== 'lift') throw new Error('status-feed: action must be suspend or lift');
|
|
137
|
+
if (!Array.isArray(s.approvals) || new Set(s.approvals).size < 2) throw new Error('status-feed: a supervision event needs two distinct approvals');
|
|
138
|
+
const ref = typeof s.scope === 'string' ? s.scope : `system:${s.scope?.system}`;
|
|
139
|
+
const kind = s.action === 'suspend' ? 'supervision.suspended' : 'supervision.lifted';
|
|
140
|
+
return normalize({ kind, subject: s.subject, ref, ts: s.ts, reason: s.reason, evidence: [...s.approvals, ...(s.evidence ?? [])] });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface Suspension { subject: string; ref: string; reason: string; ts: string; seq: number }
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Suspensions in force after replaying the feed in order: the latest event per subject and
|
|
147
|
+
* scope wins. Verify the feed first (`verifyFeed`); this does not check signatures.
|
|
148
|
+
*/
|
|
149
|
+
export function activeSuspensions(entries: FeedEntry[]): Suspension[] {
|
|
150
|
+
const state = new Map<string, Suspension | null>();
|
|
151
|
+
for (const e of entries) {
|
|
152
|
+
const ev = e.event;
|
|
153
|
+
if (ev.kind !== 'supervision.suspended' && ev.kind !== 'supervision.lifted') continue;
|
|
154
|
+
if (supervisionScopeReasons(ev.ref).length) continue;
|
|
155
|
+
const key = `${ev.subject} ${ev.ref}`;
|
|
156
|
+
state.set(key, ev.kind === 'supervision.suspended' ? { subject: ev.subject, ref: ev.ref, reason: ev.reason ?? '', ts: ev.ts, seq: e.seq } : null);
|
|
157
|
+
}
|
|
158
|
+
return [...state.values()].filter((x): x is Suspension => x !== null).sort((a, b) => a.seq - b.seq);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** The first suspension covering an agent (by its own DID, its owner, or its system), or null. */
|
|
162
|
+
export function suspensionFor(suspensions: Suspension[], who: { agent: string; owner?: string; system?: string }): Suspension | null {
|
|
163
|
+
for (const s of suspensions) {
|
|
164
|
+
if (s.ref === 'agent' && s.subject === who.agent) return s;
|
|
165
|
+
if (s.ref === 'owner' && who.owner && s.subject === who.owner) return s;
|
|
166
|
+
if (who.owner && who.system && s.subject === who.owner && s.ref === `system:${who.system}`) return s;
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ---------------------------------------------------------------------------------- //
|
|
172
|
+
// Threat signatures: a threat one member blocked, shared so every member blocks it too
|
|
173
|
+
// ---------------------------------------------------------------------------------- //
|
|
174
|
+
|
|
175
|
+
const THREAT_TARGET = /^[A-Za-z0-9._:*-]{1,128}$/;
|
|
176
|
+
const THREAT_TEXT = /^[\x21-\x7e][\x20-\x7e]{2,198}[\x21-\x7e]$/;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Why a threat `ref` is malformed. `target:<pattern>` blocks actions whose target the scope
|
|
180
|
+
* pattern covers; `contains:<text>` blocks actions whose arguments contain the text, ignoring
|
|
181
|
+
* ASCII case. The text is 4 to 200 printable ASCII characters with no surrounding spaces: plain
|
|
182
|
+
* text, never a regular expression, so a feed entry cannot make a member's matcher slow.
|
|
183
|
+
*/
|
|
184
|
+
export function threatRefReasons(ref: unknown): string[] {
|
|
185
|
+
const m = typeof ref === 'string' ? /^(target|contains):(.*)$/s.exec(ref) : null;
|
|
186
|
+
if (!m) return ['threat ref must be target:<pattern> or contains:<text>'];
|
|
187
|
+
if (m[1] === 'target' && !THREAT_TARGET.test(m[2]!)) return ['threat target pattern is invalid'];
|
|
188
|
+
if (m[1] === 'contains' && !THREAT_TEXT.test(m[2]!)) return ['threat text must be 4 to 200 printable ASCII characters without surrounding spaces'];
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** A new threat signature, citing the evidence behind it (for example the blocking guard decision receipt). */
|
|
193
|
+
export function threatSignatureEvent(t: { match: 'target' | 'contains'; value: string; reporter: string; label: string; ts: string; evidence: string[] }): StatusEvent {
|
|
194
|
+
if (t.match !== 'target' && t.match !== 'contains') throw new Error('status-feed: match must be target or contains');
|
|
195
|
+
return normalize({ kind: 'threat.signature', subject: t.reporter, ref: `${t.match}:${t.value}`, ts: t.ts, reason: t.label, evidence: t.evidence });
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Withdraw a signature (for example a false positive). A later `threat.signature` with the same ref restores it. */
|
|
199
|
+
export function threatRetractionEvent(t: { ref: string; reporter: string; ts: string; evidence: string[]; reason?: string | null }): StatusEvent {
|
|
200
|
+
return normalize({ kind: 'threat.retracted', subject: t.reporter, ref: t.ref, ts: t.ts, reason: t.reason ?? null, evidence: t.evidence });
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export interface ThreatSignature { ref: string; match: 'target' | 'contains'; value: string; label: string; seq: number }
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* The signatures in force after replaying the feed in order: the latest event per ref wins.
|
|
207
|
+
* Verify the feed first (`verifyFeed`); this does not check signatures.
|
|
208
|
+
*/
|
|
209
|
+
export function activeThreatSignatures(entries: FeedEntry[]): ThreatSignature[] {
|
|
210
|
+
const state = new Map<string, ThreatSignature | null>();
|
|
211
|
+
for (const e of entries) {
|
|
212
|
+
const ev = e.event;
|
|
213
|
+
if (ev.kind === 'threat.signature' && threatRefReasons(ev.ref).length === 0) {
|
|
214
|
+
const i = ev.ref.indexOf(':');
|
|
215
|
+
state.set(ev.ref, { ref: ev.ref, match: ev.ref.slice(0, i) as 'target' | 'contains', value: ev.ref.slice(i + 1), label: ev.reason ?? '', seq: e.seq });
|
|
216
|
+
} else if (ev.kind === 'threat.retracted') state.set(ev.ref, null);
|
|
217
|
+
}
|
|
218
|
+
return [...state.values()].filter((x): x is ThreatSignature => x !== null).sort((a, b) => a.seq - b.seq);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const asciiLower = (s: string) => s.replace(/[A-Z]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 32));
|
|
222
|
+
|
|
223
|
+
/** The first signature that matches an action, or null. `text` is the action's arguments as text. */
|
|
224
|
+
export function matchThreat(signatures: ThreatSignature[], action: { target: string; text?: string }): ThreatSignature | null {
|
|
225
|
+
const text = asciiLower(action.text ?? '');
|
|
226
|
+
for (const sig of signatures) {
|
|
227
|
+
if (sig.match === 'target' ? scopeCovers(sig.value, action.target) : text.includes(asciiLower(sig.value))) return sig;
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function normalize(e: StatusEvent): StatusEvent {
|
|
233
|
+
return {
|
|
234
|
+
kind: e.kind, subject: e.subject, ref: e.ref, ts: e.ts, reason: e.reason ?? null,
|
|
235
|
+
evidence: Array.isArray(e.evidence) ? [...new Set(e.evidence)].sort() : e.evidence,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** The last entry's position, or null for an empty feed. */
|
|
240
|
+
export function feedHead(entries: FeedEntry[]): FeedHead | null {
|
|
241
|
+
const last = entries[entries.length - 1];
|
|
242
|
+
return last ? { seq: last.seq, hash: entryHash(last) } : null;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Sign the next entry of `feed` and return it with the new head. Pure: the caller appends
|
|
247
|
+
* `entry` to its stored feed. Refuses a malformed event and an event dated before the head.
|
|
248
|
+
*/
|
|
249
|
+
function unsignedEntry(feed: Feed, event: StatusEvent) {
|
|
250
|
+
if (typeof feed?.jurisdiction !== 'string' || !feed.jurisdiction) throw new Error('status-feed: feed.jurisdiction is required');
|
|
251
|
+
const ev = normalize(event);
|
|
252
|
+
const reasons = eventReasons(ev);
|
|
253
|
+
if (reasons.length) throw new Error(`status-feed: ${reasons.join('; ')}`);
|
|
254
|
+
const last = feed.entries[feed.entries.length - 1];
|
|
255
|
+
if (last && last.jurisdiction !== feed.jurisdiction) throw new Error('status-feed: the feed holds another jurisdiction');
|
|
256
|
+
if (last && ms(ev.ts) < ms(last.event.ts)) throw new Error('status-feed: event is dated before the feed head');
|
|
257
|
+
return { v: 1 as const, type: FEED_TYPE, jurisdiction: feed.jurisdiction, seq: last ? last.seq + 1 : 1, prev: last ? entryHash(last) : null, event: ev };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function appendEvent(feed: Feed, event: StatusEvent, signerKey: Uint8Array): { entry: FeedEntry; head: FeedHead } {
|
|
261
|
+
const entry = signObject(unsignedEntry(feed, event), signerKey);
|
|
262
|
+
return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** `appendEvent` with a raw key or a remote signer (HSM, KMS): the key need not enter this process. */
|
|
266
|
+
export async function appendEventAsync(feed: Feed, event: StatusEvent, signer: Uint8Array | RemoteSigner): Promise<{ entry: FeedEntry; head: FeedHead }> {
|
|
267
|
+
const entry = await signObjectAsync(unsignedEntry(feed, event), signer);
|
|
268
|
+
return { entry, head: { seq: entry.seq, hash: entryHash(entry) } };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface VerifyFeedOptions {
|
|
272
|
+
/** The DIDs allowed to sign entries (key rotation: list old and new). */
|
|
273
|
+
signers: string[];
|
|
274
|
+
/** Expected jurisdiction; defaults to the first entry's. */
|
|
275
|
+
jurisdiction?: string;
|
|
276
|
+
/** A trusted earlier head, to verify a suffix such as `feedSince(entries, after.seq)`. */
|
|
277
|
+
after?: FeedHead;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export interface VerifyFeedResult { ok: boolean; reasons: string[]; head: FeedHead | null }
|
|
281
|
+
|
|
282
|
+
/** Chain continuity, sequence without gaps, signatures by allowed signers, non-decreasing time, well-formed events. */
|
|
283
|
+
export function verifyFeed(entries: FeedEntry[], opts: VerifyFeedOptions): VerifyFeedResult {
|
|
284
|
+
const reasons: string[] = [];
|
|
285
|
+
if (!Array.isArray(entries)) return { ok: false, reasons: ['feed is not a list'], head: null };
|
|
286
|
+
if (!Array.isArray(opts?.signers) || !opts.signers.length) reasons.push('no signers supplied: signer NOT checked');
|
|
287
|
+
const jurisdiction = opts?.jurisdiction ?? (entries[0] as FeedEntry | undefined)?.jurisdiction;
|
|
288
|
+
let prevHash: string | null = opts?.after?.hash ?? null;
|
|
289
|
+
let prevSeq = opts?.after?.seq ?? 0;
|
|
290
|
+
let prevTs = NaN;
|
|
291
|
+
entries.forEach((e, i) => {
|
|
292
|
+
const r = (m: string) => reasons.push(`entry ${i}: ${m}`);
|
|
293
|
+
if (!e || typeof e !== 'object' || e.v !== 1 || e.type !== FEED_TYPE) { r('not a status feed entry (v1)'); prevHash = null; return; }
|
|
294
|
+
const keys = Object.keys(e).sort().join(',');
|
|
295
|
+
if (keys !== 'event,jurisdiction,prev,seq,sig,signer,type,v') r('entry has unexpected or missing fields');
|
|
296
|
+
if (!verifySignedObject(e)) r('bad signature');
|
|
297
|
+
else if (opts?.signers?.length && !opts.signers.includes(e.signer)) r('signed by a key that is not an allowed feed signer');
|
|
298
|
+
if (e.jurisdiction !== jurisdiction) r('entry is for another jurisdiction');
|
|
299
|
+
if (e.seq !== prevSeq + 1) r(`sequence gap: expected ${prevSeq + 1}, got ${String(e.seq)}`);
|
|
300
|
+
if (e.prev !== prevHash) r('chain break: prev does not match the previous entry');
|
|
301
|
+
for (const m of eventReasons(e.event)) r(m);
|
|
302
|
+
const t = ms(e.event?.ts);
|
|
303
|
+
if (t < prevTs) r('time goes backwards');
|
|
304
|
+
if (!Number.isNaN(t)) prevTs = t;
|
|
305
|
+
prevSeq = typeof e.seq === 'number' ? e.seq : prevSeq + 1;
|
|
306
|
+
prevHash = entryHash(e);
|
|
307
|
+
});
|
|
308
|
+
const head = entries.length ? feedHead(entries) : opts?.after ?? null;
|
|
309
|
+
return { ok: reasons.length === 0, reasons, head };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** Entries after sequence number `seq` (0 = all), for a reader catching up. */
|
|
313
|
+
export function feedSince(entries: FeedEntry[], seq: number): FeedEntry[] {
|
|
314
|
+
return entries.filter((e) => e.seq > seq);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ---------------------------------------------------------------------------------- //
|
|
318
|
+
// Event builders: each derives `ref` and `evidence` from the record it reports
|
|
319
|
+
// ---------------------------------------------------------------------------------- //
|
|
320
|
+
|
|
321
|
+
/** A Ledger delegation revocation (`createRevocation` / `submitRevocation`). The record must verify. */
|
|
322
|
+
export function revocationEvent(record: RevocationRecord, opts: { reason?: string | null } = {}): StatusEvent {
|
|
323
|
+
if (!verifyRevocation(record)) throw new Error('status-feed: the revocation record does not verify');
|
|
324
|
+
return normalize({ kind: 'delegation.revoked', subject: record.cert.subject, ref: certHash(record.cert), ts: record.ts, reason: opts.reason ?? null, evidence: [jcsHash(record)] });
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const hashOf = (x: string | object): string => (typeof x === 'string' ? x : jcsHash(x));
|
|
328
|
+
|
|
329
|
+
/** A Certify status change. `statusDocument` is the signed `certify.status` document (or its hash) that carries it. */
|
|
330
|
+
export function certificateStatusEvent(c: {
|
|
331
|
+
certificate: string; holder: string; action: 'suspend' | 'revoke' | 'reinstate';
|
|
332
|
+
reason: string | null; since: string; statusDocument: string | object;
|
|
333
|
+
}): StatusEvent {
|
|
334
|
+
const kind = ({ suspend: 'certificate.suspended', revoke: 'certificate.revoked', reinstate: 'certificate.reinstated' } as const)[c.action];
|
|
335
|
+
if (!kind) throw new Error('status-feed: action must be suspend, revoke or reinstate');
|
|
336
|
+
return normalize({ kind, subject: c.holder, ref: c.certificate, ts: c.since, reason: c.reason, evidence: [hashOf(c.statusDocument)] });
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** An incident opened or closed, citing the incident report (or its hash). */
|
|
340
|
+
export function incidentEvent(i: { action: 'opened' | 'closed'; incident: string; subject: string; report: string | object; ts: string; reason?: string | null }): StatusEvent {
|
|
341
|
+
if (i.action !== 'opened' && i.action !== 'closed') throw new Error('status-feed: action must be opened or closed');
|
|
342
|
+
return normalize({ kind: `incident.${i.action}`, subject: i.subject, ref: i.incident, ts: i.ts, reason: i.reason ?? null, evidence: [hashOf(i.report)] });
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** A `zanii.jurisdiction` binding issued or expired; `ts` defaults to its `issued_at` / `expires_at`. */
|
|
346
|
+
export function jurisdictionEvent(binding: { subject: string; issued_at: string; expires_at: string }, action: 'issued' | 'expired', ts?: string): StatusEvent {
|
|
347
|
+
if (action !== 'issued' && action !== 'expired') throw new Error('status-feed: action must be issued or expired');
|
|
348
|
+
const h = jcsHash(binding);
|
|
349
|
+
return normalize({ kind: `jurisdiction.${action}`, subject: binding.subject, ref: h, ts: ts ?? (action === 'issued' ? binding.issued_at : binding.expires_at), reason: null, evidence: [h] });
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ---------------------------------------------------------------------------------- //
|
|
353
|
+
// Publishing
|
|
354
|
+
// ---------------------------------------------------------------------------------- //
|
|
355
|
+
|
|
356
|
+
export interface RenderOptions { title?: string; id?: string; link?: string; updated?: string }
|
|
357
|
+
|
|
358
|
+
const xml = (s: string) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
359
|
+
const feedId = (j: string) => `urn:zanii:status-feed:${encodeURIComponent(j)}`;
|
|
360
|
+
const titleOf = (e: FeedEntry) => `${e.event.kind} ${e.event.subject}`;
|
|
361
|
+
|
|
362
|
+
/** Atom 1.0 (RFC 4287). Each entry's content is its canonical JSON, so a reader can verify it. */
|
|
363
|
+
export function toAtom(entries: FeedEntry[], opts: RenderOptions = {}): string {
|
|
364
|
+
const j = entries[0]?.jurisdiction ?? '';
|
|
365
|
+
const id = opts.id ?? feedId(j);
|
|
366
|
+
const updated = opts.updated ?? entries[entries.length - 1]?.event.ts ?? '1970-01-01T00:00:00Z';
|
|
367
|
+
const lines = [
|
|
368
|
+
'<?xml version="1.0" encoding="utf-8"?>',
|
|
369
|
+
'<feed xmlns="http://www.w3.org/2005/Atom">',
|
|
370
|
+
` <id>${xml(id)}</id>`,
|
|
371
|
+
` <title>${xml(opts.title ?? `Zanii status feed ${j}`)}</title>`,
|
|
372
|
+
` <updated>${xml(updated)}</updated>`,
|
|
373
|
+
];
|
|
374
|
+
if (opts.link) lines.push(` <link rel="self" href="${xml(opts.link)}"/>`);
|
|
375
|
+
for (const e of entries) {
|
|
376
|
+
lines.push(
|
|
377
|
+
' <entry>',
|
|
378
|
+
` <id>${xml(`${feedId(e.jurisdiction)}:${e.seq}`)}</id>`,
|
|
379
|
+
` <title>${xml(titleOf(e))}</title>`,
|
|
380
|
+
` <updated>${xml(e.event.ts)}</updated>`,
|
|
381
|
+
` <author><name>${xml(e.signer)}</name></author>`,
|
|
382
|
+
` <content type="application/json">${xml(canonicalJson(e))}</content>`,
|
|
383
|
+
' </entry>',
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
lines.push('</feed>', '');
|
|
387
|
+
return lines.join('\n');
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/** JSON Feed 1.1. `_zanii_status_feed` carries the signed entry unchanged. */
|
|
391
|
+
export function toJsonFeed(entries: FeedEntry[], opts: RenderOptions = {}): Record<string, unknown> {
|
|
392
|
+
const j = entries[0]?.jurisdiction ?? '';
|
|
393
|
+
const out: Record<string, unknown> = { version: 'https://jsonfeed.org/version/1.1', title: opts.title ?? `Zanii status feed ${j}` };
|
|
394
|
+
if (opts.link) out.feed_url = opts.link;
|
|
395
|
+
out.items = entries.map((e) => ({
|
|
396
|
+
id: `${feedId(e.jurisdiction)}:${e.seq}`, title: titleOf(e), date_published: e.event.ts,
|
|
397
|
+
content_text: canonicalJson(e), _zanii_status_feed: e,
|
|
398
|
+
}));
|
|
399
|
+
return out;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* The feed head as a Ledger receipt: pass to `agent.record({ target, payload })` (`@zanii/sdk`).
|
|
404
|
+
* The receipt's payload hash then commits to the head, and the log's inclusion proof dates it.
|
|
405
|
+
*/
|
|
406
|
+
export function anchorFeedHead(entries: FeedEntry[]): { target: string; payload: Record<string, unknown> } {
|
|
407
|
+
const head = feedHead(entries);
|
|
408
|
+
if (!head) throw new Error('status-feed: an empty feed has no head to anchor');
|
|
409
|
+
return { target: 'regulator.status_feed.head', payload: { _zr_kind: 'status_feed', v: 1, jurisdiction: entries[0]!.jurisdiction, seq: head.seq, head: head.hash } };
|
|
410
|
+
}
|