@dorigjo/besa 0.1.0-alpha.2 → 0.1.0-beta.4
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 +310 -337
- package/dist/admit.d.ts +13 -2
- package/dist/admit.js +186 -26
- package/dist/crypto.d.ts +4 -1
- package/dist/crypto.js +127 -19
- package/dist/grant.js +50 -5
- package/dist/index.js +418 -57
- package/dist/io.d.ts +5 -0
- package/dist/io.js +97 -0
- package/dist/keystore.d.ts +16 -0
- package/dist/keystore.js +117 -0
- package/dist/manifest.js +83 -17
- package/dist/sdk.d.ts +2 -0
- package/dist/sdk.js +2 -0
- package/dist/signing.d.ts +16 -2
- package/dist/signing.js +317 -31
- package/dist/trust.d.ts +17 -0
- package/dist/trust.js +466 -0
- package/dist/types.d.ts +25 -0
- package/examples/request.json +3 -0
- package/package.json +66 -57
- package/scripts/postinstall.mjs +30 -0
package/dist/signing.js
CHANGED
|
@@ -1,100 +1,386 @@
|
|
|
1
|
-
import { randomUUID, sign as ed25519Sign, verify as ed25519Verify } from "node:crypto";
|
|
2
|
-
import { canonicalize,
|
|
1
|
+
import { randomUUID, sign as ed25519Sign, verify as ed25519Verify, } from "node:crypto";
|
|
2
|
+
import { canonicalize, isCanonicalBase64, privateKeyFromDer, publicKeyFromDer, publicKeyId, sha256Hex, signatureMessage, validateKeyPair, } from "./crypto.js";
|
|
3
|
+
import { validateManifest } from "./manifest.js";
|
|
4
|
+
const SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
5
|
+
const KEY_ID = /^[a-f0-9]{64}$/;
|
|
6
|
+
const RECEIPT_ID = /^rcpt_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
7
|
+
const REASON_CODE = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
8
|
+
const MAX_IDENTIFIER_LENGTH = 256;
|
|
9
|
+
function manifestSignaturePayload(signed) {
|
|
10
|
+
return {
|
|
11
|
+
artifactVersion: signed.artifactVersion,
|
|
12
|
+
manifest: signed.manifest,
|
|
13
|
+
manifestHash: signed.manifestHash,
|
|
14
|
+
algorithm: signed.algorithm,
|
|
15
|
+
publicKey: signed.publicKey,
|
|
16
|
+
publicKeyId: signed.publicKeyId,
|
|
17
|
+
signedAt: signed.signedAt,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function isObject(value) {
|
|
21
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
22
|
+
}
|
|
23
|
+
function isNonEmptyString(value, maximumLength = MAX_IDENTIFIER_LENGTH) {
|
|
24
|
+
return (typeof value === "string" &&
|
|
25
|
+
value.length <= maximumLength &&
|
|
26
|
+
value.trim().length > 0);
|
|
27
|
+
}
|
|
28
|
+
function isIsoDate(value) {
|
|
29
|
+
return (typeof value === "string" &&
|
|
30
|
+
value.length <= 35 &&
|
|
31
|
+
!Number.isNaN(Date.parse(value)) &&
|
|
32
|
+
new Date(value).toISOString() === value);
|
|
33
|
+
}
|
|
34
|
+
function isSignature(value) {
|
|
35
|
+
return (typeof value === "string" &&
|
|
36
|
+
value.length === 88 &&
|
|
37
|
+
isCanonicalBase64(value) &&
|
|
38
|
+
Buffer.from(value, "base64").length === 64);
|
|
39
|
+
}
|
|
40
|
+
function isPublicKeyEncoding(value) {
|
|
41
|
+
return (typeof value === "string" &&
|
|
42
|
+
value.length <= 128 &&
|
|
43
|
+
isCanonicalBase64(value));
|
|
44
|
+
}
|
|
45
|
+
export function validateSignedManifest(value) {
|
|
46
|
+
if (!isObject(value)) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
errors: ["signed manifest must be an object"],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const errors = [];
|
|
53
|
+
const allowedFields = new Set([
|
|
54
|
+
"artifactVersion",
|
|
55
|
+
"manifest",
|
|
56
|
+
"manifestHash",
|
|
57
|
+
"algorithm",
|
|
58
|
+
"publicKey",
|
|
59
|
+
"publicKeyId",
|
|
60
|
+
"signature",
|
|
61
|
+
"signedAt",
|
|
62
|
+
]);
|
|
63
|
+
for (const field of Object.keys(value)) {
|
|
64
|
+
if (!allowedFields.has(field)) {
|
|
65
|
+
errors.push(`unexpected signed manifest field '${field}'`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (value.artifactVersion !== 1) {
|
|
69
|
+
errors.push("artifactVersion must be 1");
|
|
70
|
+
}
|
|
71
|
+
const manifestResult = validateManifest(value.manifest);
|
|
72
|
+
if (!manifestResult.ok) {
|
|
73
|
+
errors.push(...manifestResult.errors.map((error) => `manifest.${error}`));
|
|
74
|
+
}
|
|
75
|
+
if (typeof value.manifestHash !== "string" || !SHA256_HEX.test(value.manifestHash)) {
|
|
76
|
+
errors.push("manifestHash must be a lowercase SHA-256 hex digest");
|
|
77
|
+
}
|
|
78
|
+
if (value.algorithm !== "ed25519") {
|
|
79
|
+
errors.push("algorithm must be ed25519");
|
|
80
|
+
}
|
|
81
|
+
if (!isPublicKeyEncoding(value.publicKey)) {
|
|
82
|
+
errors.push("publicKey must be canonical base64");
|
|
83
|
+
}
|
|
84
|
+
if (typeof value.publicKeyId !== "string" || !KEY_ID.test(value.publicKeyId)) {
|
|
85
|
+
errors.push("publicKeyId must be a 64-character lowercase SHA-256 fingerprint");
|
|
86
|
+
}
|
|
87
|
+
if (!isSignature(value.signature)) {
|
|
88
|
+
errors.push("signature must be a canonical base64 Ed25519 signature");
|
|
89
|
+
}
|
|
90
|
+
if (!isIsoDate(value.signedAt)) {
|
|
91
|
+
errors.push("signedAt must be a canonical ISO-8601 timestamp");
|
|
92
|
+
}
|
|
93
|
+
if (errors.length > 0 || !manifestResult.manifest) {
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
errors,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
ok: true,
|
|
101
|
+
signedManifest: value,
|
|
102
|
+
errors: [],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export function validateReceipt(value) {
|
|
106
|
+
if (!isObject(value)) {
|
|
107
|
+
return {
|
|
108
|
+
ok: false,
|
|
109
|
+
errors: ["receipt must be an object"],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const errors = [];
|
|
113
|
+
const allowedFields = new Set([
|
|
114
|
+
"artifactVersion",
|
|
115
|
+
"receiptId",
|
|
116
|
+
"manifestHash",
|
|
117
|
+
"toolName",
|
|
118
|
+
"decision",
|
|
119
|
+
"reasonCode",
|
|
120
|
+
"timestamp",
|
|
121
|
+
"requestHash",
|
|
122
|
+
"publicKeyId",
|
|
123
|
+
"algorithm",
|
|
124
|
+
"agentId",
|
|
125
|
+
"grantReasonCode",
|
|
126
|
+
"signature",
|
|
127
|
+
]);
|
|
128
|
+
for (const field of Object.keys(value)) {
|
|
129
|
+
if (!allowedFields.has(field)) {
|
|
130
|
+
errors.push(`unexpected receipt field '${field}'`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (value.artifactVersion !== 1) {
|
|
134
|
+
errors.push("artifactVersion must be 1");
|
|
135
|
+
}
|
|
136
|
+
if (typeof value.receiptId !== "string" || !RECEIPT_ID.test(value.receiptId)) {
|
|
137
|
+
errors.push("receiptId must be rcpt_ followed by a canonical UUIDv4");
|
|
138
|
+
}
|
|
139
|
+
if (typeof value.manifestHash !== "string" || !SHA256_HEX.test(value.manifestHash)) {
|
|
140
|
+
errors.push("manifestHash must be a lowercase SHA-256 hex digest");
|
|
141
|
+
}
|
|
142
|
+
if (!isNonEmptyString(value.toolName)) {
|
|
143
|
+
errors.push("toolName must be a non-empty string");
|
|
144
|
+
}
|
|
145
|
+
if (value.decision !== "allow" && value.decision !== "deny") {
|
|
146
|
+
errors.push("decision must be allow or deny");
|
|
147
|
+
}
|
|
148
|
+
if (typeof value.reasonCode !== "string" || !REASON_CODE.test(value.reasonCode)) {
|
|
149
|
+
errors.push("reasonCode must be an uppercase machine-readable code");
|
|
150
|
+
}
|
|
151
|
+
if (!isIsoDate(value.timestamp)) {
|
|
152
|
+
errors.push("timestamp must be a canonical ISO-8601 timestamp");
|
|
153
|
+
}
|
|
154
|
+
if (typeof value.requestHash !== "string" || !SHA256_HEX.test(value.requestHash)) {
|
|
155
|
+
errors.push("requestHash must be a lowercase SHA-256 hex digest");
|
|
156
|
+
}
|
|
157
|
+
if (typeof value.publicKeyId !== "string" || !KEY_ID.test(value.publicKeyId)) {
|
|
158
|
+
errors.push("publicKeyId must be a 64-character lowercase SHA-256 fingerprint");
|
|
159
|
+
}
|
|
160
|
+
if (value.algorithm !== "ed25519") {
|
|
161
|
+
errors.push("algorithm must be ed25519");
|
|
162
|
+
}
|
|
163
|
+
if (value.agentId !== undefined && !isNonEmptyString(value.agentId)) {
|
|
164
|
+
errors.push("agentId must be a non-empty string when present");
|
|
165
|
+
}
|
|
166
|
+
if (value.grantReasonCode !== undefined &&
|
|
167
|
+
(typeof value.grantReasonCode !== "string" ||
|
|
168
|
+
!REASON_CODE.test(value.grantReasonCode))) {
|
|
169
|
+
errors.push("grantReasonCode must be a non-empty string when present");
|
|
170
|
+
}
|
|
171
|
+
if (!isSignature(value.signature)) {
|
|
172
|
+
errors.push("signature must be a canonical base64 Ed25519 signature");
|
|
173
|
+
}
|
|
174
|
+
if (errors.length > 0) {
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
errors,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
ok: true,
|
|
182
|
+
receipt: value,
|
|
183
|
+
errors: [],
|
|
184
|
+
};
|
|
185
|
+
}
|
|
3
186
|
export function hashManifest(manifest) {
|
|
4
|
-
return
|
|
187
|
+
return sha256Hex(`besa:manifest:v1\0${canonicalize(manifest)}`);
|
|
188
|
+
}
|
|
189
|
+
export function hashRequest(request) {
|
|
190
|
+
return sha256Hex(`besa:request:v1\0${canonicalize(request)}`);
|
|
5
191
|
}
|
|
6
192
|
export function signManifest(manifest, keypair) {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
193
|
+
const validation = validateManifest(manifest);
|
|
194
|
+
if (!validation.ok || !validation.manifest) {
|
|
195
|
+
throw new Error(`Invalid manifest:\n - ${validation.errors.join("\n - ")}`);
|
|
196
|
+
}
|
|
197
|
+
if (!validateKeyPair(keypair)) {
|
|
198
|
+
throw new Error("invalid or mismatched Ed25519 key pair");
|
|
199
|
+
}
|
|
200
|
+
const body = {
|
|
201
|
+
artifactVersion: 1,
|
|
202
|
+
manifest: validation.manifest,
|
|
203
|
+
manifestHash: hashManifest(validation.manifest),
|
|
12
204
|
algorithm: "ed25519",
|
|
13
205
|
publicKey: keypair.publicKeyDer,
|
|
14
206
|
publicKeyId: publicKeyId(keypair.publicKeyDer),
|
|
207
|
+
signedAt: new Date().toISOString(),
|
|
208
|
+
};
|
|
209
|
+
const signature = ed25519Sign(null, signatureMessage("signed-manifest", manifestSignaturePayload(body)), privateKeyFromDer(keypair.privateKeyDer));
|
|
210
|
+
return {
|
|
211
|
+
...body,
|
|
15
212
|
signature: signature.toString("base64"),
|
|
16
|
-
signedAt: new Date().toISOString()
|
|
17
213
|
};
|
|
18
214
|
}
|
|
19
|
-
export function verifySignedManifest(
|
|
20
|
-
if (
|
|
215
|
+
export function verifySignedManifest(value) {
|
|
216
|
+
if (isObject(value) &&
|
|
217
|
+
value.artifactVersion !== undefined &&
|
|
218
|
+
value.artifactVersion !== 1) {
|
|
219
|
+
return {
|
|
220
|
+
valid: false,
|
|
221
|
+
reasonCode: "E_ARTIFACT_VERSION_UNSUPPORTED",
|
|
222
|
+
detail: "only signed manifest artifactVersion 1 is supported",
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (isObject(value) &&
|
|
226
|
+
typeof value.algorithm === "string" &&
|
|
227
|
+
value.algorithm !== "ed25519") {
|
|
21
228
|
return {
|
|
22
229
|
valid: false,
|
|
23
230
|
reasonCode: "E_ALGORITHM_UNSUPPORTED",
|
|
24
|
-
detail: "only ed25519 signed manifests are supported"
|
|
231
|
+
detail: "only ed25519 signed manifests are supported",
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
const validation = validateSignedManifest(value);
|
|
235
|
+
if (!validation.ok || !validation.signedManifest) {
|
|
236
|
+
return {
|
|
237
|
+
valid: false,
|
|
238
|
+
reasonCode: "E_SIGNED_MANIFEST_INVALID",
|
|
239
|
+
detail: validation.errors.join("; "),
|
|
25
240
|
};
|
|
26
241
|
}
|
|
27
|
-
const
|
|
242
|
+
const signed = validation.signedManifest;
|
|
28
243
|
const expectedHash = hashManifest(signed.manifest);
|
|
29
244
|
if (expectedHash !== signed.manifestHash) {
|
|
30
245
|
return {
|
|
31
246
|
valid: false,
|
|
32
247
|
reasonCode: "E_MANIFEST_HASH_MISMATCH",
|
|
33
|
-
detail: "manifest content does not match stored hash"
|
|
248
|
+
detail: "manifest content does not match stored hash",
|
|
34
249
|
};
|
|
35
250
|
}
|
|
36
251
|
if (publicKeyId(signed.publicKey) !== signed.publicKeyId) {
|
|
37
252
|
return {
|
|
38
253
|
valid: false,
|
|
39
254
|
reasonCode: "E_PUBLIC_KEY_ID_MISMATCH",
|
|
40
|
-
detail: "publicKeyId does not match publicKey"
|
|
255
|
+
detail: "publicKeyId does not match publicKey",
|
|
41
256
|
};
|
|
42
257
|
}
|
|
43
258
|
try {
|
|
44
|
-
const valid = ed25519Verify(null,
|
|
259
|
+
const valid = ed25519Verify(null, signatureMessage("signed-manifest", manifestSignaturePayload(signed)), publicKeyFromDer(signed.publicKey), Buffer.from(signed.signature, "base64"));
|
|
45
260
|
if (!valid) {
|
|
46
261
|
return {
|
|
47
262
|
valid: false,
|
|
48
263
|
reasonCode: "E_SIGNATURE_INVALID",
|
|
49
|
-
detail: "signature does not verify against the public key"
|
|
264
|
+
detail: "signature does not verify against the public key",
|
|
50
265
|
};
|
|
51
266
|
}
|
|
52
267
|
return {
|
|
53
268
|
valid: true,
|
|
54
269
|
reasonCode: "OK",
|
|
55
|
-
detail: "manifest signature is valid"
|
|
270
|
+
detail: "manifest signature is valid",
|
|
56
271
|
};
|
|
57
272
|
}
|
|
58
273
|
catch {
|
|
59
274
|
return {
|
|
60
275
|
valid: false,
|
|
61
276
|
reasonCode: "E_SIGNATURE_CHECK_FAILED",
|
|
62
|
-
detail: "signature verification failed"
|
|
277
|
+
detail: "signature verification failed",
|
|
63
278
|
};
|
|
64
279
|
}
|
|
65
280
|
}
|
|
66
281
|
export function createReceipt(input, keypair) {
|
|
282
|
+
if (!SHA256_HEX.test(input.manifestHash)) {
|
|
283
|
+
throw new Error("manifestHash must be a lowercase SHA-256 hex digest");
|
|
284
|
+
}
|
|
285
|
+
if (!isNonEmptyString(input.toolName)) {
|
|
286
|
+
throw new Error("toolName must be a non-empty string");
|
|
287
|
+
}
|
|
288
|
+
if (!REASON_CODE.test(input.reasonCode)) {
|
|
289
|
+
throw new Error("reasonCode must be an uppercase machine-readable code");
|
|
290
|
+
}
|
|
291
|
+
if (input.decision !== "allow" && input.decision !== "deny") {
|
|
292
|
+
throw new Error("decision must be allow or deny");
|
|
293
|
+
}
|
|
294
|
+
if (input.agentId !== undefined && !isNonEmptyString(input.agentId)) {
|
|
295
|
+
throw new Error("agentId must be a non-empty string when present");
|
|
296
|
+
}
|
|
297
|
+
if (input.grantReasonCode !== undefined &&
|
|
298
|
+
!REASON_CODE.test(input.grantReasonCode)) {
|
|
299
|
+
throw new Error("grantReasonCode must be a non-empty string when present");
|
|
300
|
+
}
|
|
301
|
+
if (!validateKeyPair(keypair)) {
|
|
302
|
+
throw new Error("invalid or mismatched Ed25519 key pair");
|
|
303
|
+
}
|
|
67
304
|
const body = {
|
|
305
|
+
artifactVersion: 1,
|
|
68
306
|
receiptId: "rcpt_" + randomUUID(),
|
|
69
307
|
manifestHash: input.manifestHash,
|
|
70
308
|
toolName: input.toolName,
|
|
71
309
|
decision: input.decision,
|
|
72
310
|
reasonCode: input.reasonCode,
|
|
73
311
|
timestamp: new Date().toISOString(),
|
|
74
|
-
requestHash:
|
|
75
|
-
agentId: input.agentId,
|
|
76
|
-
|
|
312
|
+
requestHash: hashRequest(input.request === undefined ? {} : input.request),
|
|
313
|
+
...(input.agentId === undefined ? {} : { agentId: input.agentId }),
|
|
314
|
+
...(input.grantReasonCode === undefined
|
|
315
|
+
? {}
|
|
316
|
+
: { grantReasonCode: input.grantReasonCode }),
|
|
77
317
|
publicKeyId: publicKeyId(keypair.publicKeyDer),
|
|
78
|
-
algorithm: "ed25519"
|
|
318
|
+
algorithm: "ed25519",
|
|
79
319
|
};
|
|
80
|
-
const signature = ed25519Sign(null,
|
|
320
|
+
const signature = ed25519Sign(null, signatureMessage("receipt", body), privateKeyFromDer(keypair.privateKeyDer));
|
|
81
321
|
return {
|
|
82
322
|
...body,
|
|
83
|
-
signature: signature.toString("base64")
|
|
323
|
+
signature: signature.toString("base64"),
|
|
84
324
|
};
|
|
85
325
|
}
|
|
86
|
-
export function
|
|
87
|
-
if (
|
|
88
|
-
|
|
326
|
+
export function verifyReceiptDetailed(value, publicKeyDer) {
|
|
327
|
+
if (isObject(value) &&
|
|
328
|
+
value.artifactVersion !== undefined &&
|
|
329
|
+
value.artifactVersion !== 1) {
|
|
330
|
+
return {
|
|
331
|
+
valid: false,
|
|
332
|
+
reasonCode: "E_ARTIFACT_VERSION_UNSUPPORTED",
|
|
333
|
+
detail: "only receipt artifactVersion 1 is supported",
|
|
334
|
+
};
|
|
89
335
|
}
|
|
336
|
+
if (isObject(value) &&
|
|
337
|
+
typeof value.algorithm === "string" &&
|
|
338
|
+
value.algorithm !== "ed25519") {
|
|
339
|
+
return {
|
|
340
|
+
valid: false,
|
|
341
|
+
reasonCode: "E_ALGORITHM_UNSUPPORTED",
|
|
342
|
+
detail: "only ed25519 receipts are supported",
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
const validation = validateReceipt(value);
|
|
346
|
+
if (!validation.ok || !validation.receipt) {
|
|
347
|
+
return {
|
|
348
|
+
valid: false,
|
|
349
|
+
reasonCode: "E_RECEIPT_INVALID",
|
|
350
|
+
detail: validation.errors.join("; "),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
const receipt = validation.receipt;
|
|
90
354
|
if (publicKeyId(publicKeyDer) !== receipt.publicKeyId) {
|
|
91
|
-
return
|
|
355
|
+
return {
|
|
356
|
+
valid: false,
|
|
357
|
+
reasonCode: "E_PUBLIC_KEY_ID_MISMATCH",
|
|
358
|
+
detail: "receipt publicKeyId does not match public key",
|
|
359
|
+
};
|
|
92
360
|
}
|
|
93
361
|
const { signature, ...body } = receipt;
|
|
94
362
|
try {
|
|
95
|
-
|
|
363
|
+
const valid = ed25519Verify(null, signatureMessage("receipt", body), publicKeyFromDer(publicKeyDer), Buffer.from(signature, "base64"));
|
|
364
|
+
return valid
|
|
365
|
+
? {
|
|
366
|
+
valid: true,
|
|
367
|
+
reasonCode: "OK",
|
|
368
|
+
detail: "receipt signature is valid",
|
|
369
|
+
}
|
|
370
|
+
: {
|
|
371
|
+
valid: false,
|
|
372
|
+
reasonCode: "E_SIGNATURE_INVALID",
|
|
373
|
+
detail: "receipt signature does not verify against the public key",
|
|
374
|
+
};
|
|
96
375
|
}
|
|
97
376
|
catch {
|
|
98
|
-
return
|
|
377
|
+
return {
|
|
378
|
+
valid: false,
|
|
379
|
+
reasonCode: "E_SIGNATURE_CHECK_FAILED",
|
|
380
|
+
detail: "receipt signature verification failed",
|
|
381
|
+
};
|
|
99
382
|
}
|
|
100
383
|
}
|
|
384
|
+
export function verifyReceipt(receipt, publicKeyDer) {
|
|
385
|
+
return verifyReceiptDetailed(receipt, publicKeyDer).valid;
|
|
386
|
+
}
|
package/dist/trust.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { KeyRotation, TrustStore } from "./types.js";
|
|
2
|
+
import { type KeyPair } from "./crypto.js";
|
|
3
|
+
import { type VerifyResult } from "./signing.js";
|
|
4
|
+
export interface TrustStoreValidationResult {
|
|
5
|
+
ok: boolean;
|
|
6
|
+
trustStore?: TrustStore;
|
|
7
|
+
errors: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function validateTrustStore(value: unknown): TrustStoreValidationResult;
|
|
10
|
+
export declare function emptyTrustStore(): TrustStore;
|
|
11
|
+
export declare function addTrustAnchor(store: TrustStore, publicKey: string, addedAt?: string): TrustStore;
|
|
12
|
+
export declare function revokeTrustAnchor(store: TrustStore, keyId: string, revokedAt?: string): TrustStore;
|
|
13
|
+
export declare function createKeyRotation(previous: KeyPair, next: KeyPair, rotatedAt?: string): KeyRotation;
|
|
14
|
+
export declare function verifyKeyRotation(value: unknown): VerifyResult;
|
|
15
|
+
export declare function applyKeyRotation(store: TrustStore, rotation: KeyRotation): TrustStore;
|
|
16
|
+
export declare function checkTrustedKey(store: TrustStore, publicKey: string, artifactTimestamp: string, purpose?: "verify" | "admit", now?: Date): VerifyResult;
|
|
17
|
+
export declare function verifyTrustedSignedManifest(value: unknown, store: TrustStore, purpose?: "verify" | "admit"): VerifyResult;
|