@attest-it/core 0.0.2 → 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/dist/index.d.ts CHANGED
@@ -4,6 +4,21 @@ import { z } from 'zod';
4
4
  * Core types for attest-it attestation system.
5
5
  * @packageDocumentation
6
6
  */
7
+ /**
8
+ * Key provider configuration in settings.
9
+ * @public
10
+ */
11
+ interface KeyProviderSettings {
12
+ /** Provider type identifier */
13
+ type: string;
14
+ /** Provider-specific options */
15
+ options?: {
16
+ account?: string | undefined;
17
+ itemName?: string | undefined;
18
+ privateKeyPath?: string | undefined;
19
+ vault?: string | undefined;
20
+ } | undefined;
21
+ }
7
22
  /**
8
23
  * Settings from the configuration file.
9
24
  * @public
@@ -17,24 +32,75 @@ interface AttestItSettings {
17
32
  attestationsPath: string;
18
33
  /** Default command to execute for attestation (can be overridden per suite) */
19
34
  defaultCommand?: string;
35
+ /** Key provider configuration for signing attestations */
36
+ keyProvider?: KeyProviderSettings;
37
+ }
38
+ /**
39
+ * Team member configuration.
40
+ * @public
41
+ */
42
+ interface TeamMember {
43
+ /** Display name for the team member */
44
+ name: string;
45
+ /** Email address (optional) */
46
+ email?: string | undefined;
47
+ /** GitHub username (optional) */
48
+ github?: string | undefined;
49
+ /** Base64-encoded Ed25519 public key */
50
+ publicKey: string;
51
+ }
52
+ /**
53
+ * Fingerprint configuration for gates.
54
+ * @public
55
+ */
56
+ interface FingerprintConfig {
57
+ /** Glob patterns for paths to include in fingerprint */
58
+ paths: string[];
59
+ /** Patterns to exclude from fingerprint */
60
+ exclude?: string[] | undefined;
61
+ }
62
+ /**
63
+ * Gate definition - defines what needs to be signed and who can sign it.
64
+ * @public
65
+ */
66
+ interface GateConfig {
67
+ /** Human-readable name for the gate */
68
+ name: string;
69
+ /** Description of what this gate protects */
70
+ description: string;
71
+ /** Team member slugs authorized to sign for this gate */
72
+ authorizedSigners: string[];
73
+ /** Fingerprint configuration */
74
+ fingerprint: FingerprintConfig;
75
+ /** Maximum age before attestation expires (duration string like "30d", "7d", "24h") */
76
+ maxAge: string;
20
77
  }
21
78
  /**
22
79
  * Suite definition from the configuration file.
80
+ * Suites are CLI-layer extensions of gates with command execution capabilities.
23
81
  * @public
24
82
  */
25
83
  interface SuiteConfig {
84
+ /** Reference to a gate (if present, inherits gate configuration) */
85
+ gate?: string;
26
86
  /** Human-readable description of what this suite tests */
27
87
  description?: string;
28
- /** Glob patterns for npm packages to include in fingerprint */
29
- packages: string[];
88
+ /** Glob patterns for npm packages to include in fingerprint (legacy/backward compatibility) */
89
+ packages?: string[];
30
90
  /** Additional file patterns to include in fingerprint */
31
91
  files?: string[];
32
92
  /** Patterns to ignore when computing fingerprint */
33
93
  ignore?: string[];
34
94
  /** Command to execute for this suite (overrides defaultCommand) */
35
95
  command?: string;
96
+ /** Timeout for command execution (duration string) */
97
+ timeout?: string;
98
+ /** Whether the command is interactive */
99
+ interactive?: boolean;
36
100
  /** Other suite names that, when changed, invalidate this suite's attestation */
37
101
  invalidates?: string[];
102
+ /** Array of suite names this suite depends on */
103
+ depends_on?: string[];
38
104
  }
39
105
  /**
40
106
  * Full configuration file structure.
@@ -45,8 +111,14 @@ interface AttestItConfig {
45
111
  version: 1;
46
112
  /** Global settings for attestation behavior */
47
113
  settings: AttestItSettings;
114
+ /** Team members mapped by slug */
115
+ team?: Record<string, TeamMember>;
116
+ /** Gates defining authorization and fingerprinting */
117
+ gates?: Record<string, GateConfig>;
48
118
  /** Named test suites with their configurations */
49
119
  suites: Record<string, SuiteConfig>;
120
+ /** Named groups of suites */
121
+ groups?: Record<string, string[]>;
50
122
  }
51
123
  /**
52
124
  * A single attestation entry.
@@ -108,90 +180,374 @@ interface SuiteVerificationResult {
108
180
  * Zod schema for the full configuration file.
109
181
  */
110
182
  declare const configSchema: z.ZodObject<{
183
+ gates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
184
+ authorizedSigners: z.ZodArray<z.ZodString, "many">;
185
+ description: z.ZodString;
186
+ fingerprint: z.ZodObject<{
187
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
188
+ paths: z.ZodArray<z.ZodString, "many">;
189
+ }, "strict", z.ZodTypeAny, {
190
+ exclude?: string[] | undefined;
191
+ paths: string[];
192
+ }, {
193
+ exclude?: string[] | undefined;
194
+ paths: string[];
195
+ }>;
196
+ maxAge: z.ZodEffects<z.ZodString, string, string>;
197
+ name: z.ZodString;
198
+ }, "strict", z.ZodTypeAny, {
199
+ authorizedSigners: string[];
200
+ description: string;
201
+ fingerprint: {
202
+ exclude?: string[] | undefined;
203
+ paths: string[];
204
+ };
205
+ maxAge: string;
206
+ name: string;
207
+ }, {
208
+ authorizedSigners: string[];
209
+ description: string;
210
+ fingerprint: {
211
+ exclude?: string[] | undefined;
212
+ paths: string[];
213
+ };
214
+ maxAge: string;
215
+ name: string;
216
+ }>>>;
217
+ groups: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
111
218
  settings: z.ZodDefault<z.ZodObject<{
112
219
  attestationsPath: z.ZodDefault<z.ZodString>;
113
220
  defaultCommand: z.ZodOptional<z.ZodString>;
221
+ keyProvider: z.ZodOptional<z.ZodObject<{
222
+ options: z.ZodOptional<z.ZodObject<{
223
+ account: z.ZodOptional<z.ZodString>;
224
+ itemName: z.ZodOptional<z.ZodString>;
225
+ privateKeyPath: z.ZodOptional<z.ZodString>;
226
+ vault: z.ZodOptional<z.ZodString>;
227
+ }, "strict", z.ZodTypeAny, {
228
+ account?: string | undefined;
229
+ itemName?: string | undefined;
230
+ privateKeyPath?: string | undefined;
231
+ vault?: string | undefined;
232
+ }, {
233
+ account?: string | undefined;
234
+ itemName?: string | undefined;
235
+ privateKeyPath?: string | undefined;
236
+ vault?: string | undefined;
237
+ }>>;
238
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
239
+ }, "strict", z.ZodTypeAny, {
240
+ options?: {
241
+ account?: string | undefined;
242
+ itemName?: string | undefined;
243
+ privateKeyPath?: string | undefined;
244
+ vault?: string | undefined;
245
+ } | undefined;
246
+ type: string;
247
+ }, {
248
+ options?: {
249
+ account?: string | undefined;
250
+ itemName?: string | undefined;
251
+ privateKeyPath?: string | undefined;
252
+ vault?: string | undefined;
253
+ } | undefined;
254
+ type: string;
255
+ }>>;
114
256
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
115
257
  publicKeyPath: z.ZodDefault<z.ZodString>;
116
258
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
117
259
  attestationsPath: z.ZodDefault<z.ZodString>;
118
260
  defaultCommand: z.ZodOptional<z.ZodString>;
261
+ keyProvider: z.ZodOptional<z.ZodObject<{
262
+ options: z.ZodOptional<z.ZodObject<{
263
+ account: z.ZodOptional<z.ZodString>;
264
+ itemName: z.ZodOptional<z.ZodString>;
265
+ privateKeyPath: z.ZodOptional<z.ZodString>;
266
+ vault: z.ZodOptional<z.ZodString>;
267
+ }, "strict", z.ZodTypeAny, {
268
+ account?: string | undefined;
269
+ itemName?: string | undefined;
270
+ privateKeyPath?: string | undefined;
271
+ vault?: string | undefined;
272
+ }, {
273
+ account?: string | undefined;
274
+ itemName?: string | undefined;
275
+ privateKeyPath?: string | undefined;
276
+ vault?: string | undefined;
277
+ }>>;
278
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
279
+ }, "strict", z.ZodTypeAny, {
280
+ options?: {
281
+ account?: string | undefined;
282
+ itemName?: string | undefined;
283
+ privateKeyPath?: string | undefined;
284
+ vault?: string | undefined;
285
+ } | undefined;
286
+ type: string;
287
+ }, {
288
+ options?: {
289
+ account?: string | undefined;
290
+ itemName?: string | undefined;
291
+ privateKeyPath?: string | undefined;
292
+ vault?: string | undefined;
293
+ } | undefined;
294
+ type: string;
295
+ }>>;
119
296
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
120
297
  publicKeyPath: z.ZodDefault<z.ZodString>;
121
298
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
122
299
  attestationsPath: z.ZodDefault<z.ZodString>;
123
300
  defaultCommand: z.ZodOptional<z.ZodString>;
301
+ keyProvider: z.ZodOptional<z.ZodObject<{
302
+ options: z.ZodOptional<z.ZodObject<{
303
+ account: z.ZodOptional<z.ZodString>;
304
+ itemName: z.ZodOptional<z.ZodString>;
305
+ privateKeyPath: z.ZodOptional<z.ZodString>;
306
+ vault: z.ZodOptional<z.ZodString>;
307
+ }, "strict", z.ZodTypeAny, {
308
+ account?: string | undefined;
309
+ itemName?: string | undefined;
310
+ privateKeyPath?: string | undefined;
311
+ vault?: string | undefined;
312
+ }, {
313
+ account?: string | undefined;
314
+ itemName?: string | undefined;
315
+ privateKeyPath?: string | undefined;
316
+ vault?: string | undefined;
317
+ }>>;
318
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
319
+ }, "strict", z.ZodTypeAny, {
320
+ options?: {
321
+ account?: string | undefined;
322
+ itemName?: string | undefined;
323
+ privateKeyPath?: string | undefined;
324
+ vault?: string | undefined;
325
+ } | undefined;
326
+ type: string;
327
+ }, {
328
+ options?: {
329
+ account?: string | undefined;
330
+ itemName?: string | undefined;
331
+ privateKeyPath?: string | undefined;
332
+ vault?: string | undefined;
333
+ } | undefined;
334
+ type: string;
335
+ }>>;
124
336
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
125
337
  publicKeyPath: z.ZodDefault<z.ZodString>;
126
338
  }, z.ZodTypeAny, "passthrough">>>;
127
- suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
339
+ suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
128
340
  command: z.ZodOptional<z.ZodString>;
341
+ depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
129
342
  description: z.ZodOptional<z.ZodString>;
130
343
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
344
+ gate: z.ZodOptional<z.ZodString>;
131
345
  ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
346
+ interactive: z.ZodOptional<z.ZodBoolean>;
132
347
  invalidates: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
133
- packages: z.ZodArray<z.ZodString, "many">;
348
+ packages: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
349
+ timeout: z.ZodOptional<z.ZodString>;
134
350
  }, "strict", z.ZodTypeAny, {
135
351
  command?: string | undefined;
352
+ depends_on?: string[] | undefined;
136
353
  description?: string | undefined;
137
354
  files?: string[] | undefined;
355
+ gate?: string | undefined;
138
356
  ignore?: string[] | undefined;
357
+ interactive?: boolean | undefined;
139
358
  invalidates?: string[] | undefined;
140
- packages: string[];
359
+ packages?: string[] | undefined;
360
+ timeout?: string | undefined;
141
361
  }, {
142
362
  command?: string | undefined;
363
+ depends_on?: string[] | undefined;
143
364
  description?: string | undefined;
144
365
  files?: string[] | undefined;
366
+ gate?: string | undefined;
145
367
  ignore?: string[] | undefined;
368
+ interactive?: boolean | undefined;
146
369
  invalidates?: string[] | undefined;
147
- packages: string[];
370
+ packages?: string[] | undefined;
371
+ timeout?: string | undefined;
372
+ }>, {
373
+ command?: string | undefined;
374
+ depends_on?: string[] | undefined;
375
+ description?: string | undefined;
376
+ files?: string[] | undefined;
377
+ gate?: string | undefined;
378
+ ignore?: string[] | undefined;
379
+ interactive?: boolean | undefined;
380
+ invalidates?: string[] | undefined;
381
+ packages?: string[] | undefined;
382
+ timeout?: string | undefined;
383
+ }, {
384
+ command?: string | undefined;
385
+ depends_on?: string[] | undefined;
386
+ description?: string | undefined;
387
+ files?: string[] | undefined;
388
+ gate?: string | undefined;
389
+ ignore?: string[] | undefined;
390
+ interactive?: boolean | undefined;
391
+ invalidates?: string[] | undefined;
392
+ packages?: string[] | undefined;
393
+ timeout?: string | undefined;
148
394
  }>>, Record<string, {
149
395
  command?: string | undefined;
396
+ depends_on?: string[] | undefined;
150
397
  description?: string | undefined;
151
398
  files?: string[] | undefined;
399
+ gate?: string | undefined;
152
400
  ignore?: string[] | undefined;
401
+ interactive?: boolean | undefined;
153
402
  invalidates?: string[] | undefined;
154
- packages: string[];
403
+ packages?: string[] | undefined;
404
+ timeout?: string | undefined;
155
405
  }>, Record<string, {
156
406
  command?: string | undefined;
407
+ depends_on?: string[] | undefined;
157
408
  description?: string | undefined;
158
409
  files?: string[] | undefined;
410
+ gate?: string | undefined;
159
411
  ignore?: string[] | undefined;
412
+ interactive?: boolean | undefined;
160
413
  invalidates?: string[] | undefined;
161
- packages: string[];
414
+ packages?: string[] | undefined;
415
+ timeout?: string | undefined;
162
416
  }>>;
417
+ team: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
418
+ email: z.ZodOptional<z.ZodString>;
419
+ github: z.ZodOptional<z.ZodString>;
420
+ name: z.ZodString;
421
+ publicKey: z.ZodString;
422
+ }, "strict", z.ZodTypeAny, {
423
+ email?: string | undefined;
424
+ github?: string | undefined;
425
+ name: string;
426
+ publicKey: string;
427
+ }, {
428
+ email?: string | undefined;
429
+ github?: string | undefined;
430
+ name: string;
431
+ publicKey: string;
432
+ }>>>;
163
433
  version: z.ZodLiteral<1>;
164
434
  }, "strict", z.ZodTypeAny, {
435
+ gates?: Record<string, {
436
+ authorizedSigners: string[];
437
+ description: string;
438
+ fingerprint: {
439
+ exclude?: string[] | undefined;
440
+ paths: string[];
441
+ };
442
+ maxAge: string;
443
+ name: string;
444
+ }> | undefined;
445
+ groups?: Record<string, string[]> | undefined;
165
446
  settings: {
166
447
  attestationsPath: string;
167
448
  defaultCommand?: string | undefined;
449
+ keyProvider?: {
450
+ options?: {
451
+ account?: string | undefined;
452
+ itemName?: string | undefined;
453
+ privateKeyPath?: string | undefined;
454
+ vault?: string | undefined;
455
+ } | undefined;
456
+ type: string;
457
+ } | undefined;
168
458
  maxAgeDays: number;
169
459
  publicKeyPath: string;
170
460
  } & { [k: string]: unknown };
171
461
  suites: Record<string, {
172
462
  command?: string | undefined;
463
+ depends_on?: string[] | undefined;
173
464
  description?: string | undefined;
174
465
  files?: string[] | undefined;
466
+ gate?: string | undefined;
175
467
  ignore?: string[] | undefined;
468
+ interactive?: boolean | undefined;
176
469
  invalidates?: string[] | undefined;
177
- packages: string[];
470
+ packages?: string[] | undefined;
471
+ timeout?: string | undefined;
178
472
  }>;
473
+ team?: Record<string, {
474
+ email?: string | undefined;
475
+ github?: string | undefined;
476
+ name: string;
477
+ publicKey: string;
478
+ }> | undefined;
179
479
  version: 1;
180
480
  }, {
481
+ gates?: Record<string, {
482
+ authorizedSigners: string[];
483
+ description: string;
484
+ fingerprint: {
485
+ exclude?: string[] | undefined;
486
+ paths: string[];
487
+ };
488
+ maxAge: string;
489
+ name: string;
490
+ }> | undefined;
491
+ groups?: Record<string, string[]> | undefined;
181
492
  settings?: undefined | z.objectInputType<{
182
493
  attestationsPath: z.ZodDefault<z.ZodString>;
183
494
  defaultCommand: z.ZodOptional<z.ZodString>;
495
+ keyProvider: z.ZodOptional<z.ZodObject<{
496
+ options: z.ZodOptional<z.ZodObject<{
497
+ account: z.ZodOptional<z.ZodString>;
498
+ itemName: z.ZodOptional<z.ZodString>;
499
+ privateKeyPath: z.ZodOptional<z.ZodString>;
500
+ vault: z.ZodOptional<z.ZodString>;
501
+ }, "strict", z.ZodTypeAny, {
502
+ account?: string | undefined;
503
+ itemName?: string | undefined;
504
+ privateKeyPath?: string | undefined;
505
+ vault?: string | undefined;
506
+ }, {
507
+ account?: string | undefined;
508
+ itemName?: string | undefined;
509
+ privateKeyPath?: string | undefined;
510
+ vault?: string | undefined;
511
+ }>>;
512
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
513
+ }, "strict", z.ZodTypeAny, {
514
+ options?: {
515
+ account?: string | undefined;
516
+ itemName?: string | undefined;
517
+ privateKeyPath?: string | undefined;
518
+ vault?: string | undefined;
519
+ } | undefined;
520
+ type: string;
521
+ }, {
522
+ options?: {
523
+ account?: string | undefined;
524
+ itemName?: string | undefined;
525
+ privateKeyPath?: string | undefined;
526
+ vault?: string | undefined;
527
+ } | undefined;
528
+ type: string;
529
+ }>>;
184
530
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
185
531
  publicKeyPath: z.ZodDefault<z.ZodString>;
186
532
  }, z.ZodTypeAny, "passthrough">;
187
533
  suites: Record<string, {
188
534
  command?: string | undefined;
535
+ depends_on?: string[] | undefined;
189
536
  description?: string | undefined;
190
537
  files?: string[] | undefined;
538
+ gate?: string | undefined;
191
539
  ignore?: string[] | undefined;
540
+ interactive?: boolean | undefined;
192
541
  invalidates?: string[] | undefined;
193
- packages: string[];
542
+ packages?: string[] | undefined;
543
+ timeout?: string | undefined;
194
544
  }>;
545
+ team?: Record<string, {
546
+ email?: string | undefined;
547
+ github?: string | undefined;
548
+ name: string;
549
+ publicKey: string;
550
+ }> | undefined;
195
551
  version: 1;
196
552
  }>;
197
553
  /**
@@ -305,7 +661,7 @@ interface FingerprintResult {
305
661
  * Algorithm:
306
662
  * 1. List all files in packages (respecting ignore globs)
307
663
  * 2. Sort files lexicographically by relative path
308
- * 3. For each file: compute SHA256(relativePath + "\0" + content)
664
+ * 3. For each file: compute SHA256(relativePath + ":" + content)
309
665
  * 4. Concatenate all file hashes in sorted order
310
666
  * 5. Compute final SHA256 of concatenated hashes
311
667
  * 6. Return "sha256:" + hex(fingerprint)
@@ -338,8 +694,98 @@ declare function computeFingerprintSync(options: FingerprintOptions): Fingerprin
338
694
  declare function listPackageFiles(packages: string[], ignore?: string[], baseDir?: string): Promise<string[]>;
339
695
 
340
696
  /**
341
- * Attestation file I/O module with JSON canonicalization.
697
+ * Types and interfaces for key provider system.
698
+ *
699
+ * @remarks
700
+ * The key provider system abstracts key storage backends, allowing private keys
701
+ * to be stored in various locations (filesystem, 1Password, etc.) while maintaining
702
+ * a consistent interface for key retrieval and signing operations.
703
+ *
704
+ * @packageDocumentation
705
+ */
706
+ /**
707
+ * Configuration for a key provider instance.
708
+ * @public
709
+ */
710
+ interface KeyProviderConfig {
711
+ /** Provider type identifier */
712
+ type: string;
713
+ /** Provider-specific configuration */
714
+ options: Record<string, unknown>;
715
+ }
716
+ /**
717
+ * Result of a key retrieval operation.
718
+ * @public
719
+ */
720
+ interface KeyRetrievalResult {
721
+ /**
722
+ * Path to the private key file.
723
+ * For ephemeral providers, this is a temporary file that must be cleaned up.
724
+ */
725
+ keyPath: string;
726
+ /**
727
+ * Cleanup function to call after signing is complete.
728
+ * For filesystem provider, this is a no-op.
729
+ * For 1Password provider, this securely deletes the temp file.
730
+ */
731
+ cleanup: () => Promise<void>;
732
+ }
733
+ /**
734
+ * Result of key generation.
735
+ * @public
736
+ */
737
+ interface KeyGenerationResult {
738
+ /** Path or reference to the private key */
739
+ privateKeyRef: string;
740
+ /** Path to the public key file (always filesystem for commit to repo) */
741
+ publicKeyPath: string;
742
+ /** Human-readable storage location description */
743
+ storageDescription: string;
744
+ }
745
+ /**
746
+ * Options for key generation via provider.
747
+ * @public
748
+ */
749
+ interface KeygenProviderOptions {
750
+ /** Path for public key output (always filesystem) */
751
+ publicKeyPath: string;
752
+ /** Overwrite existing keys */
753
+ force?: boolean;
754
+ }
755
+ /**
756
+ * Abstract interface for key storage providers.
757
+ * @public
342
758
  */
759
+ interface KeyProvider {
760
+ /** Unique identifier for this provider type */
761
+ readonly type: string;
762
+ /** Human-readable name for display */
763
+ readonly displayName: string;
764
+ /**
765
+ * Check if this provider is available on the current system.
766
+ */
767
+ isAvailable(): Promise<boolean>;
768
+ /**
769
+ * Check if a key exists in this provider.
770
+ * @param keyRef - Provider-specific key reference
771
+ */
772
+ keyExists(keyRef: string): Promise<boolean>;
773
+ /**
774
+ * Retrieve the private key for signing.
775
+ * Returns a temporary file path that can be passed to OpenSSL.
776
+ * Caller MUST call cleanup() after signing is complete.
777
+ */
778
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
779
+ /**
780
+ * Generate a new keypair and store the private key.
781
+ * Public key is always written to filesystem for repository commit.
782
+ */
783
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
784
+ /**
785
+ * Get the configuration needed to use this provider.
786
+ */
787
+ getConfig(): KeyProviderConfig;
788
+ }
343
789
 
344
790
  /**
345
791
  * Read attestations file from disk (async).
@@ -461,8 +907,12 @@ interface WriteSignedAttestationsOptions {
461
907
  filePath: string;
462
908
  /** Array of attestations to write */
463
909
  attestations: Attestation[];
464
- /** Path to the private key for signing */
465
- privateKeyPath: string;
910
+ /** Path to the private key for signing (legacy) */
911
+ privateKeyPath?: string;
912
+ /** Key provider for signing */
913
+ keyProvider?: KeyProvider;
914
+ /** Key reference for the provider */
915
+ keyRef?: string;
466
916
  }
467
917
  /**
468
918
  * Options for reading and verifying signed attestations.
@@ -548,8 +998,12 @@ interface KeygenOptions {
548
998
  * @public
549
999
  */
550
1000
  interface SignOptions {
551
- /** Path to the private key file */
552
- privateKeyPath: string;
1001
+ /** Path to the private key file (legacy) */
1002
+ privateKeyPath?: string;
1003
+ /** Key provider to use for retrieving the private key */
1004
+ keyProvider?: KeyProvider;
1005
+ /** Key reference for the provider */
1006
+ keyRef?: string;
553
1007
  /** Data to sign (string or Buffer) */
554
1008
  data: Buffer | string;
555
1009
  }
@@ -595,7 +1049,7 @@ declare function getDefaultPublicKeyPath(): string;
595
1049
  * @throws Error if OpenSSL fails or keys exist without force
596
1050
  * @public
597
1051
  */
598
- declare function generateKeyPair(options?: KeygenOptions): Promise<KeyPaths>;
1052
+ declare function generateKeyPair$1(options?: KeygenOptions): Promise<KeyPaths>;
599
1053
  /**
600
1054
  * Sign data using an RSA private key with SHA-256.
601
1055
  *
@@ -607,7 +1061,7 @@ declare function generateKeyPair(options?: KeygenOptions): Promise<KeyPaths>;
607
1061
  * @throws Error if signing fails
608
1062
  * @public
609
1063
  */
610
- declare function sign(options: SignOptions): Promise<string>;
1064
+ declare function sign$1(options: SignOptions): Promise<string>;
611
1065
  /**
612
1066
  * Verify a signature using an RSA public key with SHA-256.
613
1067
  *
@@ -619,7 +1073,7 @@ declare function sign(options: SignOptions): Promise<string>;
619
1073
  * @throws Error if verification fails (not just invalid signature)
620
1074
  * @public
621
1075
  */
622
- declare function verify(options: VerifyOptions$1): Promise<boolean>;
1076
+ declare function verify$1(options: VerifyOptions$1): Promise<boolean>;
623
1077
  /**
624
1078
  * Set restrictive permissions on a private key file.
625
1079
  * @param keyPath - Path to the private key
@@ -627,6 +1081,65 @@ declare function verify(options: VerifyOptions$1): Promise<boolean>;
627
1081
  */
628
1082
  declare function setKeyPermissions(keyPath: string): Promise<void>;
629
1083
 
1084
+ /**
1085
+ * Ed25519 cryptographic operations using Node.js native crypto module.
1086
+ *
1087
+ * @remarks
1088
+ * This module provides Ed25519 digital signature operations using Node.js
1089
+ * native crypto support (available in Node 18+). Ed25519 offers better security
1090
+ * and performance than RSA-2048 with much smaller key and signature sizes.
1091
+ *
1092
+ * @packageDocumentation
1093
+ */
1094
+ /**
1095
+ * An Ed25519 keypair with base64-encoded public key and PEM-encoded private key.
1096
+ * @public
1097
+ */
1098
+ interface KeyPair {
1099
+ /** Base64-encoded public key (raw 32 bytes, ~44 characters) */
1100
+ publicKey: string;
1101
+ /** PEM-encoded private key */
1102
+ privateKey: string;
1103
+ }
1104
+ /**
1105
+ * Generate a new Ed25519 keypair.
1106
+ *
1107
+ * @returns A keypair with base64-encoded public key and PEM-encoded private key
1108
+ * @throws Error if key generation fails
1109
+ * @public
1110
+ */
1111
+ declare function generateKeyPair(): KeyPair;
1112
+ /**
1113
+ * Sign data with an Ed25519 private key.
1114
+ *
1115
+ * @param data - Data to sign (Buffer or UTF-8 string)
1116
+ * @param privateKeyPem - PEM-encoded private key
1117
+ * @returns Base64-encoded signature
1118
+ * @throws Error if signing fails
1119
+ * @public
1120
+ */
1121
+ declare function sign(data: Buffer | string, privateKeyPem: string): string;
1122
+ /**
1123
+ * Verify an Ed25519 signature.
1124
+ *
1125
+ * @param data - Original data that was signed
1126
+ * @param signature - Base64-encoded signature to verify
1127
+ * @param publicKeyBase64 - Base64-encoded public key (raw 32 bytes)
1128
+ * @returns true if signature is valid, false otherwise
1129
+ * @throws Error if verification fails (not just invalid signature)
1130
+ * @public
1131
+ */
1132
+ declare function verify(data: Buffer | string, signature: string, publicKeyBase64: string): boolean;
1133
+ /**
1134
+ * Extract the public key from an Ed25519 private key.
1135
+ *
1136
+ * @param privateKeyPem - PEM-encoded private key
1137
+ * @returns Base64-encoded public key (raw 32 bytes)
1138
+ * @throws Error if extraction fails
1139
+ * @public
1140
+ */
1141
+ declare function getPublicKeyFromPrivate(privateKeyPem: string): string;
1142
+
630
1143
  /**
631
1144
  * Verification logic for attestations.
632
1145
  * @packageDocumentation
@@ -675,6 +1188,632 @@ interface VerifyResult {
675
1188
  */
676
1189
  declare function verifyAttestations(options: VerifyOptions): Promise<VerifyResult>;
677
1190
 
1191
+ /**
1192
+ * Filesystem-based key provider implementation.
1193
+ *
1194
+ * @remarks
1195
+ * This provider stores private keys on the local filesystem, maintaining
1196
+ * backward compatibility with the existing attest-it key storage behavior.
1197
+ *
1198
+ * @packageDocumentation
1199
+ */
1200
+
1201
+ /**
1202
+ * Options for creating a FilesystemKeyProvider.
1203
+ * @public
1204
+ */
1205
+ interface FilesystemKeyProviderOptions {
1206
+ /** Path to the private key file (defaults to OS-specific config dir) */
1207
+ privateKeyPath?: string;
1208
+ }
1209
+ /**
1210
+ * Key provider that stores private keys on the filesystem.
1211
+ *
1212
+ * @remarks
1213
+ * This is the default provider and maintains backward compatibility with
1214
+ * existing attest-it installations. Private keys are stored at:
1215
+ * - macOS/Linux: ~/.config/attest-it/private.pem
1216
+ * - Windows: %APPDATA%\attest-it\private.pem
1217
+ *
1218
+ * @public
1219
+ */
1220
+ declare class FilesystemKeyProvider implements KeyProvider {
1221
+ readonly type = "filesystem";
1222
+ readonly displayName = "Filesystem";
1223
+ private readonly privateKeyPath;
1224
+ /**
1225
+ * Create a new FilesystemKeyProvider.
1226
+ * @param options - Provider options
1227
+ */
1228
+ constructor(options?: FilesystemKeyProviderOptions);
1229
+ /**
1230
+ * Check if this provider is available.
1231
+ * Filesystem provider is always available.
1232
+ */
1233
+ isAvailable(): Promise<boolean>;
1234
+ /**
1235
+ * Check if a key exists at the given path.
1236
+ * @param keyRef - Path to the private key file
1237
+ */
1238
+ keyExists(keyRef: string): Promise<boolean>;
1239
+ /**
1240
+ * Get the private key path for signing.
1241
+ * Returns the path directly with a no-op cleanup function.
1242
+ * @param keyRef - Path to the private key file
1243
+ */
1244
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
1245
+ /**
1246
+ * Generate a new keypair and store on filesystem.
1247
+ * @param options - Key generation options
1248
+ */
1249
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
1250
+ /**
1251
+ * Get the configuration for this provider.
1252
+ */
1253
+ getConfig(): KeyProviderConfig;
1254
+ }
1255
+
1256
+ /**
1257
+ * 1Password-based key provider implementation.
1258
+ *
1259
+ * @remarks
1260
+ * This provider stores private keys in 1Password and retrieves them via the
1261
+ * `op` CLI tool. Keys are downloaded to a temporary file for signing and
1262
+ * securely deleted after use.
1263
+ *
1264
+ * @packageDocumentation
1265
+ */
1266
+
1267
+ /**
1268
+ * Options for creating a OnePasswordKeyProvider.
1269
+ * @public
1270
+ */
1271
+ interface OnePasswordKeyProviderOptions {
1272
+ /** 1Password account email (optional if only one account) */
1273
+ account?: string;
1274
+ /** Vault name or ID where the key is stored */
1275
+ vault: string;
1276
+ /** Item name in 1Password */
1277
+ itemName: string;
1278
+ }
1279
+ /**
1280
+ * Information about a 1Password account.
1281
+ * @public
1282
+ */
1283
+ interface OnePasswordAccount {
1284
+ /** Account UUID */
1285
+ account_uuid: string;
1286
+ /** User email address */
1287
+ email: string;
1288
+ /** Account URL */
1289
+ url: string;
1290
+ /** User UUID */
1291
+ user_uuid: string;
1292
+ }
1293
+ /**
1294
+ * Information about a 1Password vault.
1295
+ * @public
1296
+ */
1297
+ interface OnePasswordVault {
1298
+ /** Vault UUID */
1299
+ id: string;
1300
+ /** Vault name */
1301
+ name: string;
1302
+ }
1303
+ /**
1304
+ * Key provider that stores private keys in 1Password.
1305
+ *
1306
+ * @remarks
1307
+ * This provider requires the `op` CLI tool to be installed and authenticated.
1308
+ * Private keys are stored as documents in 1Password and downloaded to
1309
+ * temporary files for signing operations.
1310
+ *
1311
+ * @public
1312
+ */
1313
+ declare class OnePasswordKeyProvider implements KeyProvider {
1314
+ readonly type = "1password";
1315
+ readonly displayName = "1Password";
1316
+ private readonly account?;
1317
+ private readonly vault;
1318
+ private readonly itemName;
1319
+ /**
1320
+ * Create a new OnePasswordKeyProvider.
1321
+ * @param options - Provider options
1322
+ */
1323
+ constructor(options: OnePasswordKeyProviderOptions);
1324
+ /**
1325
+ * Check if the 1Password CLI is installed.
1326
+ * @returns True if `op` command is available
1327
+ */
1328
+ static isInstalled(): Promise<boolean>;
1329
+ /**
1330
+ * List all 1Password accounts.
1331
+ * @returns Array of account information
1332
+ */
1333
+ static listAccounts(): Promise<OnePasswordAccount[]>;
1334
+ /**
1335
+ * List vaults in a specific account.
1336
+ * @param account - Account email (optional if only one account)
1337
+ * @returns Array of vault information
1338
+ */
1339
+ static listVaults(account?: string): Promise<OnePasswordVault[]>;
1340
+ /**
1341
+ * Check if this provider is available.
1342
+ * Requires `op` CLI to be installed and authenticated.
1343
+ */
1344
+ isAvailable(): Promise<boolean>;
1345
+ /**
1346
+ * Check if a key exists in 1Password.
1347
+ * @param keyRef - Item name in 1Password
1348
+ */
1349
+ keyExists(keyRef: string): Promise<boolean>;
1350
+ /**
1351
+ * Get the private key from 1Password for signing.
1352
+ * Downloads to a temporary file and returns a cleanup function.
1353
+ * @param keyRef - Item name in 1Password
1354
+ * @throws Error if the key does not exist in 1Password
1355
+ */
1356
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
1357
+ /**
1358
+ * Generate a new keypair and store private key in 1Password.
1359
+ * Public key is written to filesystem for repository commit.
1360
+ * @param options - Key generation options
1361
+ */
1362
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
1363
+ /**
1364
+ * Get the configuration for this provider.
1365
+ */
1366
+ getConfig(): KeyProviderConfig;
1367
+ }
1368
+
1369
+ /**
1370
+ * macOS Keychain-based key provider implementation.
1371
+ *
1372
+ * @remarks
1373
+ * This provider stores private keys in the macOS Keychain and retrieves them via the
1374
+ * `security` CLI tool. Keys are stored as base64-encoded strings and downloaded to
1375
+ * temporary files for signing operations, then securely deleted after use.
1376
+ *
1377
+ * @packageDocumentation
1378
+ */
1379
+
1380
+ /**
1381
+ * Options for creating a MacOSKeychainKeyProvider.
1382
+ * @public
1383
+ */
1384
+ interface MacOSKeychainKeyProviderOptions {
1385
+ /** Item name in keychain (e.g., "attest-it-private-key") */
1386
+ itemName: string;
1387
+ }
1388
+ /**
1389
+ * Key provider that stores private keys in macOS Keychain.
1390
+ *
1391
+ * @remarks
1392
+ * This provider requires macOS and uses the `security` CLI tool.
1393
+ * Private keys are stored as base64-encoded strings in the keychain and decoded
1394
+ * to temporary files for signing operations.
1395
+ *
1396
+ * @public
1397
+ */
1398
+ declare class MacOSKeychainKeyProvider implements KeyProvider {
1399
+ readonly type = "macos-keychain";
1400
+ readonly displayName = "macOS Keychain";
1401
+ private readonly itemName;
1402
+ private static readonly ACCOUNT;
1403
+ /**
1404
+ * Create a new MacOSKeychainKeyProvider.
1405
+ * @param options - Provider options
1406
+ */
1407
+ constructor(options: MacOSKeychainKeyProviderOptions);
1408
+ /**
1409
+ * Check if this provider is available.
1410
+ * Only available on macOS platforms.
1411
+ */
1412
+ static isAvailable(): boolean;
1413
+ /**
1414
+ * Check if this provider is available on the current system.
1415
+ */
1416
+ isAvailable(): Promise<boolean>;
1417
+ /**
1418
+ * Check if a key exists in the keychain.
1419
+ * @param keyRef - Item name in keychain
1420
+ */
1421
+ keyExists(keyRef: string): Promise<boolean>;
1422
+ /**
1423
+ * Get the private key from keychain for signing.
1424
+ * Downloads to a temporary file and returns a cleanup function.
1425
+ * @param keyRef - Item name in keychain
1426
+ * @throws Error if the key does not exist in keychain
1427
+ */
1428
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
1429
+ /**
1430
+ * Generate a new keypair and store private key in keychain.
1431
+ * Public key is written to filesystem for repository commit.
1432
+ * @param options - Key generation options
1433
+ */
1434
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
1435
+ /**
1436
+ * Get the configuration for this provider.
1437
+ */
1438
+ getConfig(): KeyProviderConfig;
1439
+ }
1440
+
1441
+ /**
1442
+ * Registry for key provider implementations.
1443
+ *
1444
+ * @remarks
1445
+ * The registry maintains a mapping of provider types to factory functions,
1446
+ * allowing dynamic creation of key providers based on configuration.
1447
+ *
1448
+ * @packageDocumentation
1449
+ */
1450
+
1451
+ /**
1452
+ * Type for a key provider factory function.
1453
+ * @public
1454
+ */
1455
+ type KeyProviderFactory = (config: KeyProviderConfig) => KeyProvider;
1456
+ /**
1457
+ * Registry for key provider implementations.
1458
+ *
1459
+ * @remarks
1460
+ * The registry allows registration of custom key providers and provides
1461
+ * a factory method to create provider instances from configuration.
1462
+ *
1463
+ * Note: This class is used as a namespace for static methods.
1464
+ * @public
1465
+ */
1466
+ declare class KeyProviderRegistry {
1467
+ private static providers;
1468
+ /**
1469
+ * Register a key provider factory.
1470
+ * @param type - Provider type identifier
1471
+ * @param factory - Factory function to create provider instances
1472
+ */
1473
+ static register(type: string, factory: KeyProviderFactory): void;
1474
+ /**
1475
+ * Create a key provider from configuration.
1476
+ * @param config - Provider configuration
1477
+ * @returns A key provider instance
1478
+ * @throws Error if the provider type is not registered
1479
+ */
1480
+ static create(config: KeyProviderConfig): KeyProvider;
1481
+ /**
1482
+ * Get all registered provider types.
1483
+ * @returns Array of provider type identifiers
1484
+ */
1485
+ static getProviderTypes(): string[];
1486
+ }
1487
+
1488
+ /**
1489
+ * Identity system types for attest-it v2.0.
1490
+ * @packageDocumentation
1491
+ */
1492
+ /**
1493
+ * Private key reference - points to where the key is stored.
1494
+ * @public
1495
+ */
1496
+ type PrivateKeyRef = {
1497
+ account: string;
1498
+ service: string;
1499
+ type: 'keychain';
1500
+ } | {
1501
+ account?: string;
1502
+ field?: string;
1503
+ item: string;
1504
+ type: '1password';
1505
+ vault: string;
1506
+ } | {
1507
+ path: string;
1508
+ type: 'file';
1509
+ };
1510
+ /**
1511
+ * A single identity configuration.
1512
+ * @public
1513
+ */
1514
+ interface Identity {
1515
+ /** Identity name (unique identifier) */
1516
+ name: string;
1517
+ /** Email address associated with this identity */
1518
+ email?: string;
1519
+ /** GitHub username associated with this identity */
1520
+ github?: string;
1521
+ /** Base64 Ed25519 public key */
1522
+ publicKey: string;
1523
+ /** Reference to where the private key is stored */
1524
+ privateKey: PrivateKeyRef;
1525
+ }
1526
+ /**
1527
+ * The local config file structure at ~/.config/attest-it/config.yaml.
1528
+ * @public
1529
+ */
1530
+ interface LocalConfig {
1531
+ /** Name of the currently active identity */
1532
+ activeIdentity: string;
1533
+ /** Map of identity names to identity configurations */
1534
+ identities: Record<string, Identity>;
1535
+ }
1536
+
1537
+ /**
1538
+ * Configuration loading for local identity system.
1539
+ * @packageDocumentation
1540
+ */
1541
+
1542
+ /**
1543
+ * Error thrown when local config validation fails.
1544
+ * @public
1545
+ */
1546
+ declare class LocalConfigValidationError extends Error {
1547
+ readonly issues: z.ZodIssue[];
1548
+ constructor(message: string, issues: z.ZodIssue[]);
1549
+ }
1550
+ /**
1551
+ * Get the path to the local config file.
1552
+ *
1553
+ * @returns Path to ~/.config/attest-it/config.yaml
1554
+ * @public
1555
+ */
1556
+ declare function getLocalConfigPath(): string;
1557
+ /**
1558
+ * Load and validate local config from file (async).
1559
+ *
1560
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1561
+ * @returns Validated LocalConfig object, or null if file does not exist
1562
+ * @throws {LocalConfigValidationError} If validation fails
1563
+ * @public
1564
+ */
1565
+ declare function loadLocalConfig(configPath?: string): Promise<LocalConfig | null>;
1566
+ /**
1567
+ * Load and validate local config from file (sync).
1568
+ *
1569
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1570
+ * @returns Validated LocalConfig object, or null if file does not exist
1571
+ * @throws {LocalConfigValidationError} If validation fails
1572
+ * @public
1573
+ */
1574
+ declare function loadLocalConfigSync(configPath?: string): LocalConfig | null;
1575
+ /**
1576
+ * Save local config to file (async).
1577
+ *
1578
+ * @param config - LocalConfig object to save
1579
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1580
+ * @throws {Error} If write fails
1581
+ * @public
1582
+ */
1583
+ declare function saveLocalConfig(config: LocalConfig, configPath?: string): Promise<void>;
1584
+ /**
1585
+ * Save local config to file (sync).
1586
+ *
1587
+ * @param config - LocalConfig object to save
1588
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1589
+ * @throws {Error} If write fails
1590
+ * @public
1591
+ */
1592
+ declare function saveLocalConfigSync(config: LocalConfig, configPath?: string): void;
1593
+ /**
1594
+ * Get the active identity from a config.
1595
+ *
1596
+ * @param config - LocalConfig object
1597
+ * @returns The active Identity, or undefined if not found
1598
+ * @public
1599
+ */
1600
+ declare function getActiveIdentity(config: LocalConfig): Identity | undefined;
1601
+
1602
+ /**
1603
+ * Authorization logic for attest-it v2.0.
1604
+ * @packageDocumentation
1605
+ */
1606
+
1607
+ /**
1608
+ * Check if a public key belongs to an authorized signer for a gate.
1609
+ *
1610
+ * @param config - The attest-it configuration
1611
+ * @param gateId - The gate identifier (slug)
1612
+ * @param publicKey - Base64-encoded Ed25519 public key to check
1613
+ * @returns true if the public key belongs to an authorized signer for the gate
1614
+ * @public
1615
+ */
1616
+ declare function isAuthorizedSigner(config: AttestItConfig, gateId: string, publicKey: string): boolean;
1617
+ /**
1618
+ * Get all team members authorized to sign for a gate.
1619
+ *
1620
+ * @param config - The attest-it configuration
1621
+ * @param gateId - The gate identifier (slug)
1622
+ * @returns Array of authorized team members, or empty array if gate not found
1623
+ * @public
1624
+ */
1625
+ declare function getAuthorizedSignersForGate(config: AttestItConfig, gateId: string): TeamMember[];
1626
+ /**
1627
+ * Find a team member by their public key.
1628
+ *
1629
+ * @param config - The attest-it configuration
1630
+ * @param publicKey - Base64-encoded Ed25519 public key
1631
+ * @returns The team member with matching public key, or undefined if not found
1632
+ * @public
1633
+ */
1634
+ declare function findTeamMemberByPublicKey(config: AttestItConfig, publicKey: string): TeamMember | undefined;
1635
+ /**
1636
+ * Get the gate configuration for a given gate ID.
1637
+ *
1638
+ * @param config - The attest-it configuration
1639
+ * @param gateId - The gate identifier (slug)
1640
+ * @returns The gate configuration, or undefined if not found
1641
+ * @public
1642
+ */
1643
+ declare function getGate(config: AttestItConfig, gateId: string): GateConfig | undefined;
1644
+ /**
1645
+ * Parse a duration string to milliseconds.
1646
+ * Uses the ms library to parse strings like "30d", "7d", "24h".
1647
+ *
1648
+ * @param duration - Duration string (e.g., "30d", "7d", "24h")
1649
+ * @returns Duration in milliseconds
1650
+ * @throws {Error} If duration string is invalid
1651
+ * @public
1652
+ */
1653
+ declare function parseDuration(duration: string): number;
1654
+
1655
+ /**
1656
+ * Seal types for attest-it v2.0.
1657
+ * @packageDocumentation
1658
+ */
1659
+ /**
1660
+ * A seal represents a cryptographic attestation that a gate's fingerprint
1661
+ * was signed by an authorized team member.
1662
+ * @public
1663
+ */
1664
+ interface Seal {
1665
+ /** Gate identifier (slug) */
1666
+ gateId: string;
1667
+ /** SHA-256 fingerprint of the gate's content in format "sha256:..." */
1668
+ fingerprint: string;
1669
+ /** ISO 8601 timestamp when the seal was created */
1670
+ timestamp: string;
1671
+ /** Team member slug who created the seal */
1672
+ sealedBy: string;
1673
+ /** Base64-encoded Ed25519 signature of gateId:fingerprint:timestamp */
1674
+ signature: string;
1675
+ }
1676
+ /**
1677
+ * The seals file structure stored at .attest-it/seals.json.
1678
+ * @public
1679
+ */
1680
+ interface SealsFile {
1681
+ /** Schema version for forward compatibility */
1682
+ version: 1;
1683
+ /** Map of gate slugs to their seals */
1684
+ seals: Record<string, Seal>;
1685
+ }
1686
+
1687
+ /**
1688
+ * Seal operations for creating, verifying, and managing seals.
1689
+ * @packageDocumentation
1690
+ */
1691
+
1692
+ /**
1693
+ * Options for creating a seal.
1694
+ * @public
1695
+ */
1696
+ interface CreateSealOptions {
1697
+ /** Gate identifier (slug) */
1698
+ gateId: string;
1699
+ /** SHA-256 fingerprint of the gate's content */
1700
+ fingerprint: string;
1701
+ /** Team member slug creating the seal */
1702
+ sealedBy: string;
1703
+ /** PEM-encoded Ed25519 private key for signing */
1704
+ privateKey: string;
1705
+ }
1706
+ /**
1707
+ * Result of seal signature verification.
1708
+ * @public
1709
+ */
1710
+ interface SignatureVerificationResult {
1711
+ /** Whether the seal signature is valid */
1712
+ valid: boolean;
1713
+ /** Error message if verification failed */
1714
+ error?: string;
1715
+ }
1716
+ /**
1717
+ * Create a seal by signing the canonical string: gateId:fingerprint:timestamp
1718
+ *
1719
+ * @param options - Seal creation options
1720
+ * @returns The created seal
1721
+ * @throws Error if signing fails
1722
+ * @public
1723
+ */
1724
+ declare function createSeal(options: CreateSealOptions): Seal;
1725
+ /**
1726
+ * Verify a seal's signature against the team member's public key.
1727
+ *
1728
+ * @param seal - The seal to verify
1729
+ * @param config - The attest-it configuration containing team members
1730
+ * @returns Verification result with success status and optional error message
1731
+ * @public
1732
+ */
1733
+ declare function verifySeal(seal: Seal, config: AttestItConfig): SignatureVerificationResult;
1734
+ /**
1735
+ * Read seals from the seals.json file (async).
1736
+ *
1737
+ * @param dir - Directory containing .attest-it/seals.json
1738
+ * @returns The seals file contents, or an empty seals file if the file doesn't exist
1739
+ * @throws Error if file exists but cannot be read or parsed
1740
+ * @public
1741
+ */
1742
+ declare function readSeals(dir: string): Promise<SealsFile>;
1743
+ /**
1744
+ * Read seals from the seals.json file (sync).
1745
+ *
1746
+ * @param dir - Directory containing .attest-it/seals.json
1747
+ * @returns The seals file contents, or an empty seals file if the file doesn't exist
1748
+ * @throws Error if file exists but cannot be read or parsed
1749
+ * @public
1750
+ */
1751
+ declare function readSealsSync(dir: string): SealsFile;
1752
+ /**
1753
+ * Write seals to the seals.json file (async).
1754
+ *
1755
+ * @param dir - Directory containing .attest-it/seals.json
1756
+ * @param sealsFile - The seals file to write
1757
+ * @throws Error if file cannot be written
1758
+ * @public
1759
+ */
1760
+ declare function writeSeals(dir: string, sealsFile: SealsFile): Promise<void>;
1761
+ /**
1762
+ * Write seals to the seals.json file (sync).
1763
+ *
1764
+ * @param dir - Directory containing .attest-it/seals.json
1765
+ * @param sealsFile - The seals file to write
1766
+ * @throws Error if file cannot be written
1767
+ * @public
1768
+ */
1769
+ declare function writeSealsSync(dir: string, sealsFile: SealsFile): void;
1770
+
1771
+ /**
1772
+ * Seal verification logic and states.
1773
+ * @packageDocumentation
1774
+ */
1775
+
1776
+ /**
1777
+ * Verification state for a gate's seal.
1778
+ * @public
1779
+ */
1780
+ type VerificationState = 'FINGERPRINT_MISMATCH' | 'INVALID_SIGNATURE' | 'MISSING' | 'STALE' | 'UNKNOWN_SIGNER' | 'VALID';
1781
+ /**
1782
+ * Result of verifying a single gate's seal.
1783
+ * @public
1784
+ */
1785
+ interface SealVerificationResult {
1786
+ /** Gate identifier */
1787
+ gateId: string;
1788
+ /** Verification state */
1789
+ state: VerificationState;
1790
+ /** The seal, if one exists */
1791
+ seal?: Seal;
1792
+ /** Human-readable message explaining the state */
1793
+ message?: string;
1794
+ }
1795
+ /**
1796
+ * Verify a single gate's seal.
1797
+ *
1798
+ * @param config - The attest-it configuration
1799
+ * @param gateId - Gate identifier to verify
1800
+ * @param seals - The seals file containing all seals
1801
+ * @param currentFingerprint - Current computed fingerprint for the gate
1802
+ * @returns Verification result for the gate
1803
+ * @public
1804
+ */
1805
+ declare function verifyGateSeal(config: AttestItConfig, gateId: string, seals: SealsFile, currentFingerprint: string): SealVerificationResult;
1806
+ /**
1807
+ * Verify all gates' seals.
1808
+ *
1809
+ * @param config - The attest-it configuration
1810
+ * @param seals - The seals file containing all seals
1811
+ * @param fingerprints - Map of gate IDs to their current fingerprints
1812
+ * @returns Array of verification results for all gates
1813
+ * @public
1814
+ */
1815
+ declare function verifyAllSeals(config: AttestItConfig, seals: SealsFile, fingerprints: Record<string, string>): SealVerificationResult[];
1816
+
678
1817
  /**
679
1818
  * @attest-it/core
680
1819
  *
@@ -687,4 +1826,4 @@ declare function verifyAttestations(options: VerifyOptions): Promise<VerifyResul
687
1826
  */
688
1827
  declare const version = "0.0.0";
689
1828
 
690
- export { type AttestItConfig, type AttestItSettings, type Attestation, type AttestationsFile, type Config, ConfigNotFoundError, ConfigValidationError, type VerifyOptions$1 as CryptoVerifyOptions, type FingerprintOptions, type FingerprintResult, type KeyPaths, type KeygenOptions, type ReadSignedAttestationsOptions, type SignOptions, SignatureInvalidError, type SuiteConfig, type SuiteVerificationResult, type VerificationStatus, type VerifyOptions, type VerifyResult, type WriteSignedAttestationsOptions, canonicalizeAttestations, checkOpenSSL, computeFingerprint, computeFingerprintSync, createAttestation, findAttestation, findConfigPath, generateKeyPair, getDefaultPrivateKeyPath, getDefaultPublicKeyPath, listPackageFiles, loadConfig, loadConfigSync, readAndVerifyAttestations, readAttestations, readAttestationsSync, removeAttestation, resolveConfigPaths, setKeyPermissions, sign, toAttestItConfig, upsertAttestation, verify, verifyAttestations, version, writeAttestations, writeAttestationsSync, writeSignedAttestations };
1829
+ export { type AttestItConfig, type AttestItSettings, type Attestation, type AttestationsFile, type Config, ConfigNotFoundError, ConfigValidationError, type CreateSealOptions, type VerifyOptions$1 as CryptoVerifyOptions, type KeyPair as Ed25519KeyPair, FilesystemKeyProvider, type FilesystemKeyProviderOptions, type FingerprintConfig, type FingerprintOptions, type FingerprintResult, type GateConfig, type Identity, type KeyGenerationResult, type KeyPaths, type KeyProvider, type KeyProviderConfig, type KeyProviderFactory, KeyProviderRegistry, type KeyProviderSettings, type KeyRetrievalResult, type KeygenOptions, type KeygenProviderOptions, type LocalConfig, LocalConfigValidationError, MacOSKeychainKeyProvider, type MacOSKeychainKeyProviderOptions, type OnePasswordAccount, OnePasswordKeyProvider, type OnePasswordKeyProviderOptions, type OnePasswordVault, type PrivateKeyRef, type ReadSignedAttestationsOptions, type Seal, type SealVerificationResult, type SealsFile, type SignOptions, SignatureInvalidError, type SignatureVerificationResult, type SuiteConfig, type SuiteVerificationResult, type TeamMember, type VerificationState, type VerificationStatus, type VerifyOptions, type VerifyResult, type WriteSignedAttestationsOptions, canonicalizeAttestations, checkOpenSSL, computeFingerprint, computeFingerprintSync, createAttestation, createSeal, findAttestation, findConfigPath, findTeamMemberByPublicKey, generateKeyPair as generateEd25519KeyPair, generateKeyPair$1 as generateKeyPair, getActiveIdentity, getAuthorizedSignersForGate, getDefaultPrivateKeyPath, getDefaultPublicKeyPath, getGate, getLocalConfigPath, getPublicKeyFromPrivate, isAuthorizedSigner, listPackageFiles, loadConfig, loadConfigSync, loadLocalConfig, loadLocalConfigSync, parseDuration, readAndVerifyAttestations, readAttestations, readAttestationsSync, readSeals, readSealsSync, removeAttestation, resolveConfigPaths, saveLocalConfig, saveLocalConfigSync, setKeyPermissions, sign$1 as sign, sign as signEd25519, toAttestItConfig, upsertAttestation, verify$1 as verify, verifyAllSeals, verifyAttestations, verify as verifyEd25519, verifyGateSeal, verifySeal, version, writeAttestations, writeAttestationsSync, writeSeals, writeSealsSync, writeSignedAttestations };