@predicatesystems/authority 0.3.3 → 0.4.1
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 +226 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/verify/comparators.d.ts +52 -0
- package/dist/verify/comparators.d.ts.map +1 -0
- package/dist/verify/comparators.js +100 -0
- package/dist/verify/comparators.js.map +1 -0
- package/dist/verify/index.d.ts +34 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +35 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/types.d.ts +290 -0
- package/dist/verify/types.d.ts.map +1 -0
- package/dist/verify/types.js +102 -0
- package/dist/verify/types.js.map +1 -0
- package/dist/verify/verifier.d.ts +102 -0
- package/dist/verify/verifier.d.ts.map +1 -0
- package/dist/verify/verifier.js +347 -0
- package/dist/verify/verifier.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-execution verification module.
|
|
3
|
+
*
|
|
4
|
+
* The Verifier class compares actual operations against what was
|
|
5
|
+
* authorized via a mandate, detecting unauthorized deviations.
|
|
6
|
+
*/
|
|
7
|
+
import { AuthorityClientError } from "../errors.js";
|
|
8
|
+
import { actionsMatch, resourcesMatch } from "./comparators.js";
|
|
9
|
+
import { isBrowserEvidence, isCliEvidence, isDbEvidence, isFileEvidence, isHttpEvidence, isMandateDetails, isRecordVerificationResponse, } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Verifier for post-execution authorization checks.
|
|
12
|
+
*
|
|
13
|
+
* Compares actual operations against mandates to detect unauthorized
|
|
14
|
+
* deviations from what was authorized.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const verifier = new Verifier({ baseUrl: 'http://127.0.0.1:8787' });
|
|
19
|
+
*
|
|
20
|
+
* const result = await verifier.verify({
|
|
21
|
+
* mandateId: decision.mandate_id,
|
|
22
|
+
* actual: {
|
|
23
|
+
* action: 'fs.read',
|
|
24
|
+
* resource: '/src/index.ts',
|
|
25
|
+
* },
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* if (!result.verified) {
|
|
29
|
+
* console.error('Operation mismatch:', result.reason);
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class Verifier {
|
|
34
|
+
baseUrl;
|
|
35
|
+
timeoutMs;
|
|
36
|
+
constructor(options) {
|
|
37
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
38
|
+
this.timeoutMs = options.timeoutMs ?? 2000;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Verify that an actual operation matches its mandate.
|
|
42
|
+
*
|
|
43
|
+
* @param request - Verification request with mandate ID and actual operation
|
|
44
|
+
* @returns Verification result
|
|
45
|
+
*/
|
|
46
|
+
async verify(request) {
|
|
47
|
+
// 1. Retrieve mandate details
|
|
48
|
+
const mandate = await this.getMandate(request.mandateId);
|
|
49
|
+
if (!mandate) {
|
|
50
|
+
return {
|
|
51
|
+
verified: false,
|
|
52
|
+
reason: "mandate_not_found",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// 2. Check mandate expiration
|
|
56
|
+
const expiresAt = new Date(mandate.expires_at).getTime();
|
|
57
|
+
if (expiresAt < Date.now()) {
|
|
58
|
+
return {
|
|
59
|
+
verified: false,
|
|
60
|
+
reason: "mandate_expired",
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// 3. Compare action
|
|
64
|
+
if (!actionsMatch(mandate.action, request.actual.action)) {
|
|
65
|
+
const result = {
|
|
66
|
+
verified: false,
|
|
67
|
+
reason: "action_mismatch",
|
|
68
|
+
details: {
|
|
69
|
+
authorized: { action: mandate.action, resource: mandate.resource },
|
|
70
|
+
actual: {
|
|
71
|
+
action: request.actual.action,
|
|
72
|
+
resource: request.actual.resource,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
// Record failed verification
|
|
77
|
+
await this.recordVerification({
|
|
78
|
+
mandateId: request.mandateId,
|
|
79
|
+
verified: false,
|
|
80
|
+
actual: request.actual,
|
|
81
|
+
reason: "action_mismatch",
|
|
82
|
+
});
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
// 4. Compare resource (with normalization)
|
|
86
|
+
if (!resourcesMatch(mandate.resource, request.actual.resource)) {
|
|
87
|
+
const result = {
|
|
88
|
+
verified: false,
|
|
89
|
+
reason: "resource_mismatch",
|
|
90
|
+
details: {
|
|
91
|
+
authorized: { action: mandate.action, resource: mandate.resource },
|
|
92
|
+
actual: {
|
|
93
|
+
action: request.actual.action,
|
|
94
|
+
resource: request.actual.resource,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
// Record failed verification
|
|
99
|
+
await this.recordVerification({
|
|
100
|
+
mandateId: request.mandateId,
|
|
101
|
+
verified: false,
|
|
102
|
+
actual: request.actual,
|
|
103
|
+
reason: "resource_mismatch",
|
|
104
|
+
});
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
// 5. Record successful verification
|
|
108
|
+
const auditId = await this.recordVerification({
|
|
109
|
+
mandateId: request.mandateId,
|
|
110
|
+
verified: true,
|
|
111
|
+
actual: request.actual,
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
verified: true,
|
|
115
|
+
auditId,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Verify an operation locally without sidecar communication.
|
|
120
|
+
*
|
|
121
|
+
* Use this when the sidecar endpoints are not available yet (Phase 2).
|
|
122
|
+
* This performs the same matching logic but skips mandate retrieval
|
|
123
|
+
* and audit logging.
|
|
124
|
+
*
|
|
125
|
+
* @param mandate - Known mandate details
|
|
126
|
+
* @param request - Verification request
|
|
127
|
+
* @returns Verification result (without auditId)
|
|
128
|
+
*/
|
|
129
|
+
verifyLocal(mandate, request) {
|
|
130
|
+
// Check mandate expiration
|
|
131
|
+
const expiresAt = new Date(mandate.expires_at).getTime();
|
|
132
|
+
if (expiresAt < Date.now()) {
|
|
133
|
+
return {
|
|
134
|
+
verified: false,
|
|
135
|
+
reason: "mandate_expired",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// Compare action
|
|
139
|
+
if (!actionsMatch(mandate.action, request.actual.action)) {
|
|
140
|
+
return {
|
|
141
|
+
verified: false,
|
|
142
|
+
reason: "action_mismatch",
|
|
143
|
+
details: {
|
|
144
|
+
authorized: { action: mandate.action, resource: mandate.resource },
|
|
145
|
+
actual: {
|
|
146
|
+
action: request.actual.action,
|
|
147
|
+
resource: request.actual.resource,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// Compare resource
|
|
153
|
+
if (!resourcesMatch(mandate.resource, request.actual.resource)) {
|
|
154
|
+
return {
|
|
155
|
+
verified: false,
|
|
156
|
+
reason: "resource_mismatch",
|
|
157
|
+
details: {
|
|
158
|
+
authorized: { action: mandate.action, resource: mandate.resource },
|
|
159
|
+
actual: {
|
|
160
|
+
action: request.actual.action,
|
|
161
|
+
resource: request.actual.resource,
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return { verified: true };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Retrieve mandate details from the sidecar.
|
|
170
|
+
*
|
|
171
|
+
* @param mandateId - Mandate ID to look up
|
|
172
|
+
* @returns Mandate details or null if not found
|
|
173
|
+
*/
|
|
174
|
+
async getMandate(mandateId) {
|
|
175
|
+
const controller = new AbortController();
|
|
176
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
177
|
+
try {
|
|
178
|
+
const response = await fetch(`${this.baseUrl}/v1/mandates/${encodeURIComponent(mandateId)}`, {
|
|
179
|
+
method: "GET",
|
|
180
|
+
headers: {
|
|
181
|
+
accept: "application/json",
|
|
182
|
+
},
|
|
183
|
+
signal: controller.signal,
|
|
184
|
+
});
|
|
185
|
+
if (response.status === 404) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
if (!response.ok) {
|
|
189
|
+
throw new AuthorityClientError(`mandate lookup failed: ${response.status}`, {
|
|
190
|
+
code: "server_error",
|
|
191
|
+
status: response.status,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
const payload = await response.json();
|
|
195
|
+
if (!isMandateDetails(payload)) {
|
|
196
|
+
throw new AuthorityClientError("invalid mandate response payload", {
|
|
197
|
+
code: "protocol_error",
|
|
198
|
+
status: response.status,
|
|
199
|
+
details: payload,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return payload;
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
if (error instanceof AuthorityClientError) {
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
209
|
+
throw new AuthorityClientError("mandate lookup timed out", {
|
|
210
|
+
code: "timeout",
|
|
211
|
+
cause: error,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
throw new AuthorityClientError("mandate lookup failed", {
|
|
215
|
+
code: "network_error",
|
|
216
|
+
cause: error,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
finally {
|
|
220
|
+
clearTimeout(timer);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Record a verification result in the sidecar's audit log.
|
|
225
|
+
*
|
|
226
|
+
* @param request - Verification details to record
|
|
227
|
+
* @returns Audit trail ID
|
|
228
|
+
*/
|
|
229
|
+
async recordVerification(request) {
|
|
230
|
+
const controller = new AbortController();
|
|
231
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
232
|
+
try {
|
|
233
|
+
const actualPayload = this.buildActualPayload(request.actual);
|
|
234
|
+
const response = await fetch(`${this.baseUrl}/v1/verify`, {
|
|
235
|
+
method: "POST",
|
|
236
|
+
headers: {
|
|
237
|
+
"content-type": "application/json",
|
|
238
|
+
},
|
|
239
|
+
body: JSON.stringify({
|
|
240
|
+
mandate_id: request.mandateId,
|
|
241
|
+
verified: request.verified,
|
|
242
|
+
actual: actualPayload,
|
|
243
|
+
reason: request.reason,
|
|
244
|
+
verified_at: new Date().toISOString(),
|
|
245
|
+
}),
|
|
246
|
+
signal: controller.signal,
|
|
247
|
+
});
|
|
248
|
+
if (!response.ok) {
|
|
249
|
+
throw new AuthorityClientError(`record verification failed: ${response.status}`, {
|
|
250
|
+
code: "server_error",
|
|
251
|
+
status: response.status,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
const payload = await response.json();
|
|
255
|
+
if (!isRecordVerificationResponse(payload)) {
|
|
256
|
+
// Graceful fallback: generate a local audit ID if sidecar doesn't return one
|
|
257
|
+
return `local_audit_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
258
|
+
}
|
|
259
|
+
return payload.audit_id;
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (error instanceof AuthorityClientError) {
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
266
|
+
throw new AuthorityClientError("record verification timed out", {
|
|
267
|
+
code: "timeout",
|
|
268
|
+
cause: error,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
throw new AuthorityClientError("record verification failed", {
|
|
272
|
+
code: "network_error",
|
|
273
|
+
cause: error,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
clearTimeout(timer);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Build the actual operation payload for the verification request.
|
|
282
|
+
* Handles the discriminated union by extracting type-specific fields.
|
|
283
|
+
*/
|
|
284
|
+
buildActualPayload(actual) {
|
|
285
|
+
// Common fields present on all evidence types
|
|
286
|
+
const payload = {
|
|
287
|
+
action: actual.action,
|
|
288
|
+
resource: actual.resource,
|
|
289
|
+
executed_at: actual.executedAt,
|
|
290
|
+
};
|
|
291
|
+
// Check if it has a type discriminator (new ExecutionEvidence types)
|
|
292
|
+
if ("type" in actual) {
|
|
293
|
+
payload.type = actual.type;
|
|
294
|
+
if (isFileEvidence(actual)) {
|
|
295
|
+
payload.content_hash = actual.contentHash;
|
|
296
|
+
payload.file_size = actual.fileSize;
|
|
297
|
+
payload.permissions = actual.permissions;
|
|
298
|
+
payload.modified_at = actual.modifiedAt;
|
|
299
|
+
}
|
|
300
|
+
else if (isCliEvidence(actual)) {
|
|
301
|
+
payload.command = actual.command;
|
|
302
|
+
payload.exit_code = actual.exitCode;
|
|
303
|
+
payload.stdout_hash = actual.stdoutHash;
|
|
304
|
+
payload.stderr_hash = actual.stderrHash;
|
|
305
|
+
payload.transcript_hash = actual.transcriptHash;
|
|
306
|
+
payload.cwd = actual.cwd;
|
|
307
|
+
payload.duration_ms = actual.durationMs;
|
|
308
|
+
}
|
|
309
|
+
else if (isBrowserEvidence(actual)) {
|
|
310
|
+
payload.final_url = actual.finalUrl;
|
|
311
|
+
payload.selector = actual.selector;
|
|
312
|
+
payload.a11y_tree_hash = actual.a11yTreeHash;
|
|
313
|
+
payload.dom_state_hash = actual.domStateHash;
|
|
314
|
+
payload.screenshot_hash = actual.screenshotHash;
|
|
315
|
+
payload.page_title = actual.pageTitle;
|
|
316
|
+
}
|
|
317
|
+
else if (isHttpEvidence(actual)) {
|
|
318
|
+
payload.method = actual.method;
|
|
319
|
+
payload.status_code = actual.statusCode;
|
|
320
|
+
payload.response_body_hash = actual.responseBodyHash;
|
|
321
|
+
payload.content_type = actual.contentType;
|
|
322
|
+
payload.response_size = actual.responseSize;
|
|
323
|
+
payload.duration_ms = actual.durationMs;
|
|
324
|
+
}
|
|
325
|
+
else if (isDbEvidence(actual)) {
|
|
326
|
+
payload.query_hash = actual.queryHash;
|
|
327
|
+
payload.rows_affected = actual.rowsAffected;
|
|
328
|
+
payload.result_hash = actual.resultHash;
|
|
329
|
+
payload.duration_ms = actual.durationMs;
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
// GenericEvidence
|
|
333
|
+
const generic = actual;
|
|
334
|
+
payload.evidence_hash = generic.evidenceHash;
|
|
335
|
+
payload.metadata = generic.metadata;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
// Legacy ActualOperation - extract known fields
|
|
340
|
+
const legacy = actual;
|
|
341
|
+
payload.content_hash = legacy.contentHash;
|
|
342
|
+
payload.transcript_hash = legacy.transcriptHash;
|
|
343
|
+
}
|
|
344
|
+
return payload;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../src/verify/verifier.ts"],"names":[],"mappings":"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"}
|