@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.
@@ -41,8 +41,14 @@ export declare interface AttestItConfig {
41
41
  version: 1;
42
42
  /** Global settings for attestation behavior */
43
43
  settings: AttestItSettings;
44
+ /** Team members mapped by slug */
45
+ team?: Record<string, TeamMember>;
46
+ /** Gates defining authorization and fingerprinting */
47
+ gates?: Record<string, GateConfig>;
44
48
  /** Named test suites with their configurations */
45
49
  suites: Record<string, SuiteConfig>;
50
+ /** Named groups of suites */
51
+ groups?: Record<string, string[]>;
46
52
  }
47
53
 
48
54
  /**
@@ -58,6 +64,8 @@ export declare interface AttestItSettings {
58
64
  attestationsPath: string;
59
65
  /** Default command to execute for attestation (can be overridden per suite) */
60
66
  defaultCommand?: string;
67
+ /** Key provider configuration for signing attestations */
68
+ keyProvider?: KeyProviderSettings;
61
69
  }
62
70
 
63
71
  /**
@@ -92,7 +100,7 @@ export declare function checkOpenSSL(): Promise<string>;
92
100
  * Algorithm:
93
101
  * 1. List all files in packages (respecting ignore globs)
94
102
  * 2. Sort files lexicographically by relative path
95
- * 3. For each file: compute SHA256(relativePath + "\0" + content)
103
+ * 3. For each file: compute SHA256(relativePath + ":" + content)
96
104
  * 4. Concatenate all file hashes in sorted order
97
105
  * 5. Compute final SHA256 of concatenated hashes
98
106
  * 6. Return "sha256:" + hex(fingerprint)
@@ -134,90 +142,374 @@ export declare class ConfigNotFoundError extends Error {
134
142
  * Zod schema for the full configuration file.
135
143
  */
136
144
  declare const configSchema: z.ZodObject<{
145
+ gates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
146
+ authorizedSigners: z.ZodArray<z.ZodString, "many">;
147
+ description: z.ZodString;
148
+ fingerprint: z.ZodObject<{
149
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
150
+ paths: z.ZodArray<z.ZodString, "many">;
151
+ }, "strict", z.ZodTypeAny, {
152
+ exclude?: string[] | undefined;
153
+ paths: string[];
154
+ }, {
155
+ exclude?: string[] | undefined;
156
+ paths: string[];
157
+ }>;
158
+ maxAge: z.ZodEffects<z.ZodString, string, string>;
159
+ name: z.ZodString;
160
+ }, "strict", z.ZodTypeAny, {
161
+ authorizedSigners: string[];
162
+ description: string;
163
+ fingerprint: {
164
+ exclude?: string[] | undefined;
165
+ paths: string[];
166
+ };
167
+ maxAge: string;
168
+ name: string;
169
+ }, {
170
+ authorizedSigners: string[];
171
+ description: string;
172
+ fingerprint: {
173
+ exclude?: string[] | undefined;
174
+ paths: string[];
175
+ };
176
+ maxAge: string;
177
+ name: string;
178
+ }>>>;
179
+ groups: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
137
180
  settings: z.ZodDefault<z.ZodObject<{
138
181
  attestationsPath: z.ZodDefault<z.ZodString>;
139
182
  defaultCommand: z.ZodOptional<z.ZodString>;
183
+ keyProvider: z.ZodOptional<z.ZodObject<{
184
+ options: z.ZodOptional<z.ZodObject<{
185
+ account: z.ZodOptional<z.ZodString>;
186
+ itemName: z.ZodOptional<z.ZodString>;
187
+ privateKeyPath: z.ZodOptional<z.ZodString>;
188
+ vault: z.ZodOptional<z.ZodString>;
189
+ }, "strict", z.ZodTypeAny, {
190
+ account?: string | undefined;
191
+ itemName?: string | undefined;
192
+ privateKeyPath?: string | undefined;
193
+ vault?: string | undefined;
194
+ }, {
195
+ account?: string | undefined;
196
+ itemName?: string | undefined;
197
+ privateKeyPath?: string | undefined;
198
+ vault?: string | undefined;
199
+ }>>;
200
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
201
+ }, "strict", z.ZodTypeAny, {
202
+ options?: {
203
+ account?: string | undefined;
204
+ itemName?: string | undefined;
205
+ privateKeyPath?: string | undefined;
206
+ vault?: string | undefined;
207
+ } | undefined;
208
+ type: string;
209
+ }, {
210
+ options?: {
211
+ account?: string | undefined;
212
+ itemName?: string | undefined;
213
+ privateKeyPath?: string | undefined;
214
+ vault?: string | undefined;
215
+ } | undefined;
216
+ type: string;
217
+ }>>;
140
218
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
141
219
  publicKeyPath: z.ZodDefault<z.ZodString>;
142
220
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
143
221
  attestationsPath: z.ZodDefault<z.ZodString>;
144
222
  defaultCommand: z.ZodOptional<z.ZodString>;
223
+ keyProvider: z.ZodOptional<z.ZodObject<{
224
+ options: z.ZodOptional<z.ZodObject<{
225
+ account: z.ZodOptional<z.ZodString>;
226
+ itemName: z.ZodOptional<z.ZodString>;
227
+ privateKeyPath: z.ZodOptional<z.ZodString>;
228
+ vault: z.ZodOptional<z.ZodString>;
229
+ }, "strict", z.ZodTypeAny, {
230
+ account?: string | undefined;
231
+ itemName?: string | undefined;
232
+ privateKeyPath?: string | undefined;
233
+ vault?: string | undefined;
234
+ }, {
235
+ account?: string | undefined;
236
+ itemName?: string | undefined;
237
+ privateKeyPath?: string | undefined;
238
+ vault?: string | undefined;
239
+ }>>;
240
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
241
+ }, "strict", z.ZodTypeAny, {
242
+ options?: {
243
+ account?: string | undefined;
244
+ itemName?: string | undefined;
245
+ privateKeyPath?: string | undefined;
246
+ vault?: string | undefined;
247
+ } | undefined;
248
+ type: string;
249
+ }, {
250
+ options?: {
251
+ account?: string | undefined;
252
+ itemName?: string | undefined;
253
+ privateKeyPath?: string | undefined;
254
+ vault?: string | undefined;
255
+ } | undefined;
256
+ type: string;
257
+ }>>;
145
258
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
146
259
  publicKeyPath: z.ZodDefault<z.ZodString>;
147
260
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
148
261
  attestationsPath: z.ZodDefault<z.ZodString>;
149
262
  defaultCommand: z.ZodOptional<z.ZodString>;
263
+ keyProvider: z.ZodOptional<z.ZodObject<{
264
+ options: z.ZodOptional<z.ZodObject<{
265
+ account: z.ZodOptional<z.ZodString>;
266
+ itemName: z.ZodOptional<z.ZodString>;
267
+ privateKeyPath: z.ZodOptional<z.ZodString>;
268
+ vault: z.ZodOptional<z.ZodString>;
269
+ }, "strict", z.ZodTypeAny, {
270
+ account?: string | undefined;
271
+ itemName?: string | undefined;
272
+ privateKeyPath?: string | undefined;
273
+ vault?: string | undefined;
274
+ }, {
275
+ account?: string | undefined;
276
+ itemName?: string | undefined;
277
+ privateKeyPath?: string | undefined;
278
+ vault?: string | undefined;
279
+ }>>;
280
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
281
+ }, "strict", z.ZodTypeAny, {
282
+ options?: {
283
+ account?: string | undefined;
284
+ itemName?: string | undefined;
285
+ privateKeyPath?: string | undefined;
286
+ vault?: string | undefined;
287
+ } | undefined;
288
+ type: string;
289
+ }, {
290
+ options?: {
291
+ account?: string | undefined;
292
+ itemName?: string | undefined;
293
+ privateKeyPath?: string | undefined;
294
+ vault?: string | undefined;
295
+ } | undefined;
296
+ type: string;
297
+ }>>;
150
298
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
151
299
  publicKeyPath: z.ZodDefault<z.ZodString>;
152
300
  }, z.ZodTypeAny, "passthrough">>>;
153
- suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
301
+ suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
154
302
  command: z.ZodOptional<z.ZodString>;
303
+ depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
155
304
  description: z.ZodOptional<z.ZodString>;
156
305
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
306
+ gate: z.ZodOptional<z.ZodString>;
157
307
  ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
308
+ interactive: z.ZodOptional<z.ZodBoolean>;
158
309
  invalidates: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
159
- packages: z.ZodArray<z.ZodString, "many">;
310
+ packages: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
311
+ timeout: z.ZodOptional<z.ZodString>;
160
312
  }, "strict", z.ZodTypeAny, {
161
313
  command?: string | undefined;
314
+ depends_on?: string[] | undefined;
162
315
  description?: string | undefined;
163
316
  files?: string[] | undefined;
317
+ gate?: string | undefined;
164
318
  ignore?: string[] | undefined;
319
+ interactive?: boolean | undefined;
165
320
  invalidates?: string[] | undefined;
166
- packages: string[];
321
+ packages?: string[] | undefined;
322
+ timeout?: string | undefined;
167
323
  }, {
168
324
  command?: string | undefined;
325
+ depends_on?: string[] | undefined;
169
326
  description?: string | undefined;
170
327
  files?: string[] | undefined;
328
+ gate?: string | undefined;
171
329
  ignore?: string[] | undefined;
330
+ interactive?: boolean | undefined;
172
331
  invalidates?: string[] | undefined;
173
- packages: string[];
332
+ packages?: string[] | undefined;
333
+ timeout?: string | undefined;
334
+ }>, {
335
+ command?: string | undefined;
336
+ depends_on?: string[] | undefined;
337
+ description?: string | undefined;
338
+ files?: string[] | undefined;
339
+ gate?: string | undefined;
340
+ ignore?: string[] | undefined;
341
+ interactive?: boolean | undefined;
342
+ invalidates?: string[] | undefined;
343
+ packages?: string[] | undefined;
344
+ timeout?: string | undefined;
345
+ }, {
346
+ command?: string | undefined;
347
+ depends_on?: string[] | undefined;
348
+ description?: string | undefined;
349
+ files?: string[] | undefined;
350
+ gate?: string | undefined;
351
+ ignore?: string[] | undefined;
352
+ interactive?: boolean | undefined;
353
+ invalidates?: string[] | undefined;
354
+ packages?: string[] | undefined;
355
+ timeout?: string | undefined;
174
356
  }>>, Record<string, {
175
357
  command?: string | undefined;
358
+ depends_on?: string[] | undefined;
176
359
  description?: string | undefined;
177
360
  files?: string[] | undefined;
361
+ gate?: string | undefined;
178
362
  ignore?: string[] | undefined;
363
+ interactive?: boolean | undefined;
179
364
  invalidates?: string[] | undefined;
180
- packages: string[];
365
+ packages?: string[] | undefined;
366
+ timeout?: string | undefined;
181
367
  }>, Record<string, {
182
368
  command?: string | undefined;
369
+ depends_on?: string[] | undefined;
183
370
  description?: string | undefined;
184
371
  files?: string[] | undefined;
372
+ gate?: string | undefined;
185
373
  ignore?: string[] | undefined;
374
+ interactive?: boolean | undefined;
186
375
  invalidates?: string[] | undefined;
187
- packages: string[];
376
+ packages?: string[] | undefined;
377
+ timeout?: string | undefined;
188
378
  }>>;
379
+ team: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
380
+ email: z.ZodOptional<z.ZodString>;
381
+ github: z.ZodOptional<z.ZodString>;
382
+ name: z.ZodString;
383
+ publicKey: z.ZodString;
384
+ }, "strict", z.ZodTypeAny, {
385
+ email?: string | undefined;
386
+ github?: string | undefined;
387
+ name: string;
388
+ publicKey: string;
389
+ }, {
390
+ email?: string | undefined;
391
+ github?: string | undefined;
392
+ name: string;
393
+ publicKey: string;
394
+ }>>>;
189
395
  version: z.ZodLiteral<1>;
190
396
  }, "strict", z.ZodTypeAny, {
397
+ gates?: Record<string, {
398
+ authorizedSigners: string[];
399
+ description: string;
400
+ fingerprint: {
401
+ exclude?: string[] | undefined;
402
+ paths: string[];
403
+ };
404
+ maxAge: string;
405
+ name: string;
406
+ }> | undefined;
407
+ groups?: Record<string, string[]> | undefined;
191
408
  settings: {
192
409
  attestationsPath: string;
193
410
  defaultCommand?: string | undefined;
411
+ keyProvider?: {
412
+ options?: {
413
+ account?: string | undefined;
414
+ itemName?: string | undefined;
415
+ privateKeyPath?: string | undefined;
416
+ vault?: string | undefined;
417
+ } | undefined;
418
+ type: string;
419
+ } | undefined;
194
420
  maxAgeDays: number;
195
421
  publicKeyPath: string;
196
422
  } & { [k: string]: unknown };
197
423
  suites: Record<string, {
198
424
  command?: string | undefined;
425
+ depends_on?: string[] | undefined;
199
426
  description?: string | undefined;
200
427
  files?: string[] | undefined;
428
+ gate?: string | undefined;
201
429
  ignore?: string[] | undefined;
430
+ interactive?: boolean | undefined;
202
431
  invalidates?: string[] | undefined;
203
- packages: string[];
432
+ packages?: string[] | undefined;
433
+ timeout?: string | undefined;
204
434
  }>;
435
+ team?: Record<string, {
436
+ email?: string | undefined;
437
+ github?: string | undefined;
438
+ name: string;
439
+ publicKey: string;
440
+ }> | undefined;
205
441
  version: 1;
206
442
  }, {
443
+ gates?: Record<string, {
444
+ authorizedSigners: string[];
445
+ description: string;
446
+ fingerprint: {
447
+ exclude?: string[] | undefined;
448
+ paths: string[];
449
+ };
450
+ maxAge: string;
451
+ name: string;
452
+ }> | undefined;
453
+ groups?: Record<string, string[]> | undefined;
207
454
  settings?: undefined | z.objectInputType<{
208
455
  attestationsPath: z.ZodDefault<z.ZodString>;
209
456
  defaultCommand: z.ZodOptional<z.ZodString>;
457
+ keyProvider: z.ZodOptional<z.ZodObject<{
458
+ options: z.ZodOptional<z.ZodObject<{
459
+ account: z.ZodOptional<z.ZodString>;
460
+ itemName: z.ZodOptional<z.ZodString>;
461
+ privateKeyPath: z.ZodOptional<z.ZodString>;
462
+ vault: z.ZodOptional<z.ZodString>;
463
+ }, "strict", z.ZodTypeAny, {
464
+ account?: string | undefined;
465
+ itemName?: string | undefined;
466
+ privateKeyPath?: string | undefined;
467
+ vault?: string | undefined;
468
+ }, {
469
+ account?: string | undefined;
470
+ itemName?: string | undefined;
471
+ privateKeyPath?: string | undefined;
472
+ vault?: string | undefined;
473
+ }>>;
474
+ type: z.ZodUnion<[z.ZodEnum<["filesystem", "1password"]>, z.ZodString]>;
475
+ }, "strict", z.ZodTypeAny, {
476
+ options?: {
477
+ account?: string | undefined;
478
+ itemName?: string | undefined;
479
+ privateKeyPath?: string | undefined;
480
+ vault?: string | undefined;
481
+ } | undefined;
482
+ type: string;
483
+ }, {
484
+ options?: {
485
+ account?: string | undefined;
486
+ itemName?: string | undefined;
487
+ privateKeyPath?: string | undefined;
488
+ vault?: string | undefined;
489
+ } | undefined;
490
+ type: string;
491
+ }>>;
210
492
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
211
493
  publicKeyPath: z.ZodDefault<z.ZodString>;
212
494
  }, z.ZodTypeAny, "passthrough">;
213
495
  suites: Record<string, {
214
496
  command?: string | undefined;
497
+ depends_on?: string[] | undefined;
215
498
  description?: string | undefined;
216
499
  files?: string[] | undefined;
500
+ gate?: string | undefined;
217
501
  ignore?: string[] | undefined;
502
+ interactive?: boolean | undefined;
218
503
  invalidates?: string[] | undefined;
219
- packages: string[];
504
+ packages?: string[] | undefined;
505
+ timeout?: string | undefined;
220
506
  }>;
507
+ team?: Record<string, {
508
+ email?: string | undefined;
509
+ github?: string | undefined;
510
+ name: string;
511
+ publicKey: string;
512
+ }> | undefined;
221
513
  version: 1;
222
514
  }>;
223
515
 
@@ -249,6 +541,31 @@ export declare function createAttestation(params: {
249
541
  suite: string;
250
542
  }): Attestation;
251
543
 
544
+ /**
545
+ * Create a seal by signing the canonical string: gateId:fingerprint:timestamp
546
+ *
547
+ * @param options - Seal creation options
548
+ * @returns The created seal
549
+ * @throws Error if signing fails
550
+ * @public
551
+ */
552
+ export declare function createSeal(options: CreateSealOptions): Seal;
553
+
554
+ /**
555
+ * Options for creating a seal.
556
+ * @public
557
+ */
558
+ export declare interface CreateSealOptions {
559
+ /** Gate identifier (slug) */
560
+ gateId: string;
561
+ /** SHA-256 fingerprint of the gate's content */
562
+ fingerprint: string;
563
+ /** Team member slug creating the seal */
564
+ sealedBy: string;
565
+ /** PEM-encoded Ed25519 private key for signing */
566
+ privateKey: string;
567
+ }
568
+
252
569
  /**
253
570
  * Options for verifying signatures.
254
571
  * @public
@@ -262,6 +579,73 @@ export declare interface CryptoVerifyOptions {
262
579
  signature: string;
263
580
  }
264
581
 
582
+ /**
583
+ * An Ed25519 keypair with base64-encoded public key and PEM-encoded private key.
584
+ * @public
585
+ */
586
+ export declare interface Ed25519KeyPair {
587
+ /** Base64-encoded public key (raw 32 bytes, ~44 characters) */
588
+ publicKey: string;
589
+ /** PEM-encoded private key */
590
+ privateKey: string;
591
+ }
592
+
593
+ /**
594
+ * Key provider that stores private keys on the filesystem.
595
+ *
596
+ * @remarks
597
+ * This is the default provider and maintains backward compatibility with
598
+ * existing attest-it installations. Private keys are stored at:
599
+ * - macOS/Linux: ~/.config/attest-it/private.pem
600
+ * - Windows: %APPDATA%\attest-it\private.pem
601
+ *
602
+ * @public
603
+ */
604
+ export declare class FilesystemKeyProvider implements KeyProvider {
605
+ readonly type = "filesystem";
606
+ readonly displayName = "Filesystem";
607
+ private readonly privateKeyPath;
608
+ /**
609
+ * Create a new FilesystemKeyProvider.
610
+ * @param options - Provider options
611
+ */
612
+ constructor(options?: FilesystemKeyProviderOptions);
613
+ /**
614
+ * Check if this provider is available.
615
+ * Filesystem provider is always available.
616
+ */
617
+ isAvailable(): Promise<boolean>;
618
+ /**
619
+ * Check if a key exists at the given path.
620
+ * @param keyRef - Path to the private key file
621
+ */
622
+ keyExists(keyRef: string): Promise<boolean>;
623
+ /**
624
+ * Get the private key path for signing.
625
+ * Returns the path directly with a no-op cleanup function.
626
+ * @param keyRef - Path to the private key file
627
+ */
628
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
629
+ /**
630
+ * Generate a new keypair and store on filesystem.
631
+ * @param options - Key generation options
632
+ */
633
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
634
+ /**
635
+ * Get the configuration for this provider.
636
+ */
637
+ getConfig(): KeyProviderConfig;
638
+ }
639
+
640
+ /**
641
+ * Options for creating a FilesystemKeyProvider.
642
+ * @public
643
+ */
644
+ export declare interface FilesystemKeyProviderOptions {
645
+ /** Path to the private key file (defaults to OS-specific config dir) */
646
+ privateKeyPath?: string;
647
+ }
648
+
265
649
  /**
266
650
  * Find an attestation for a specific suite.
267
651
  *
@@ -286,6 +670,27 @@ export declare function findAttestation(attestations: AttestationsFile, suite: s
286
670
  */
287
671
  export declare function findConfigPath(startDir?: string): null | string;
288
672
 
673
+ /**
674
+ * Find a team member by their public key.
675
+ *
676
+ * @param config - The attest-it configuration
677
+ * @param publicKey - Base64-encoded Ed25519 public key
678
+ * @returns The team member with matching public key, or undefined if not found
679
+ * @public
680
+ */
681
+ export declare function findTeamMemberByPublicKey(config: AttestItConfig, publicKey: string): TeamMember | undefined;
682
+
683
+ /**
684
+ * Fingerprint configuration for gates.
685
+ * @public
686
+ */
687
+ export declare interface FingerprintConfig {
688
+ /** Glob patterns for paths to include in fingerprint */
689
+ paths: string[];
690
+ /** Patterns to exclude from fingerprint */
691
+ exclude?: string[] | undefined;
692
+ }
693
+
289
694
  /**
290
695
  * Options for computing a package fingerprint.
291
696
  * @public
@@ -312,6 +717,32 @@ export declare interface FingerprintResult {
312
717
  fileCount: number;
313
718
  }
314
719
 
720
+ /**
721
+ * Gate definition - defines what needs to be signed and who can sign it.
722
+ * @public
723
+ */
724
+ export declare interface GateConfig {
725
+ /** Human-readable name for the gate */
726
+ name: string;
727
+ /** Description of what this gate protects */
728
+ description: string;
729
+ /** Team member slugs authorized to sign for this gate */
730
+ authorizedSigners: string[];
731
+ /** Fingerprint configuration */
732
+ fingerprint: FingerprintConfig;
733
+ /** Maximum age before attestation expires (duration string like "30d", "7d", "24h") */
734
+ maxAge: string;
735
+ }
736
+
737
+ /**
738
+ * Generate a new Ed25519 keypair.
739
+ *
740
+ * @returns A keypair with base64-encoded public key and PEM-encoded private key
741
+ * @throws Error if key generation fails
742
+ * @public
743
+ */
744
+ export declare function generateEd25519KeyPair(): Ed25519KeyPair;
745
+
315
746
  /**
316
747
  * Generate a new RSA-2048 keypair using OpenSSL.
317
748
  *
@@ -325,6 +756,25 @@ export declare interface FingerprintResult {
325
756
  */
326
757
  export declare function generateKeyPair(options?: KeygenOptions): Promise<KeyPaths>;
327
758
 
759
+ /**
760
+ * Get the active identity from a config.
761
+ *
762
+ * @param config - LocalConfig object
763
+ * @returns The active Identity, or undefined if not found
764
+ * @public
765
+ */
766
+ export declare function getActiveIdentity(config: LocalConfig): Identity | undefined;
767
+
768
+ /**
769
+ * Get all team members authorized to sign for a gate.
770
+ *
771
+ * @param config - The attest-it configuration
772
+ * @param gateId - The gate identifier (slug)
773
+ * @returns Array of authorized team members, or empty array if gate not found
774
+ * @public
775
+ */
776
+ export declare function getAuthorizedSignersForGate(config: AttestItConfig, gateId: string): TeamMember[];
777
+
328
778
  /**
329
779
  * Get the default private key path based on OS.
330
780
  * - macOS/Linux: ~/.config/attest-it/private.pem
@@ -339,6 +789,75 @@ export declare function getDefaultPrivateKeyPath(): string;
339
789
  */
340
790
  export declare function getDefaultPublicKeyPath(): string;
341
791
 
792
+ /**
793
+ * Get the gate configuration for a given gate ID.
794
+ *
795
+ * @param config - The attest-it configuration
796
+ * @param gateId - The gate identifier (slug)
797
+ * @returns The gate configuration, or undefined if not found
798
+ * @public
799
+ */
800
+ export declare function getGate(config: AttestItConfig, gateId: string): GateConfig | undefined;
801
+
802
+ /**
803
+ * Get the path to the local config file.
804
+ *
805
+ * @returns Path to ~/.config/attest-it/config.yaml
806
+ * @public
807
+ */
808
+ export declare function getLocalConfigPath(): string;
809
+
810
+ /**
811
+ * Extract the public key from an Ed25519 private key.
812
+ *
813
+ * @param privateKeyPem - PEM-encoded private key
814
+ * @returns Base64-encoded public key (raw 32 bytes)
815
+ * @throws Error if extraction fails
816
+ * @public
817
+ */
818
+ export declare function getPublicKeyFromPrivate(privateKeyPem: string): string;
819
+
820
+ /**
821
+ * A single identity configuration.
822
+ * @public
823
+ */
824
+ export declare interface Identity {
825
+ /** Identity name (unique identifier) */
826
+ name: string;
827
+ /** Email address associated with this identity */
828
+ email?: string;
829
+ /** GitHub username associated with this identity */
830
+ github?: string;
831
+ /** Base64 Ed25519 public key */
832
+ publicKey: string;
833
+ /** Reference to where the private key is stored */
834
+ privateKey: PrivateKeyRef;
835
+ }
836
+
837
+ /**
838
+ * Check if a public key belongs to an authorized signer for a gate.
839
+ *
840
+ * @param config - The attest-it configuration
841
+ * @param gateId - The gate identifier (slug)
842
+ * @param publicKey - Base64-encoded Ed25519 public key to check
843
+ * @returns true if the public key belongs to an authorized signer for the gate
844
+ * @public
845
+ */
846
+ export declare function isAuthorizedSigner(config: AttestItConfig, gateId: string, publicKey: string): boolean;
847
+
848
+ /**
849
+ * Result of key generation.
850
+ * @public
851
+ */
852
+ export declare interface KeyGenerationResult {
853
+ /** Path or reference to the private key */
854
+ privateKeyRef: string;
855
+ /** Path to the public key file (always filesystem for commit to repo) */
856
+ publicKeyPath: string;
857
+ /** Human-readable storage location description */
858
+ storageDescription: string;
859
+ }
860
+
342
861
  /**
343
862
  * Options for key generation.
344
863
  * @public
@@ -352,6 +871,17 @@ export declare interface KeygenOptions {
352
871
  force?: boolean;
353
872
  }
354
873
 
874
+ /**
875
+ * Options for key generation via provider.
876
+ * @public
877
+ */
878
+ export declare interface KeygenProviderOptions {
879
+ /** Path for public key output (always filesystem) */
880
+ publicKeyPath: string;
881
+ /** Overwrite existing keys */
882
+ force?: boolean;
883
+ }
884
+
355
885
  /**
356
886
  * Paths to a generated keypair.
357
887
  * @public
@@ -363,6 +893,124 @@ export declare interface KeyPaths {
363
893
  publicPath: string;
364
894
  }
365
895
 
896
+ /**
897
+ * Abstract interface for key storage providers.
898
+ * @public
899
+ */
900
+ export declare interface KeyProvider {
901
+ /** Unique identifier for this provider type */
902
+ readonly type: string;
903
+ /** Human-readable name for display */
904
+ readonly displayName: string;
905
+ /**
906
+ * Check if this provider is available on the current system.
907
+ */
908
+ isAvailable(): Promise<boolean>;
909
+ /**
910
+ * Check if a key exists in this provider.
911
+ * @param keyRef - Provider-specific key reference
912
+ */
913
+ keyExists(keyRef: string): Promise<boolean>;
914
+ /**
915
+ * Retrieve the private key for signing.
916
+ * Returns a temporary file path that can be passed to OpenSSL.
917
+ * Caller MUST call cleanup() after signing is complete.
918
+ */
919
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
920
+ /**
921
+ * Generate a new keypair and store the private key.
922
+ * Public key is always written to filesystem for repository commit.
923
+ */
924
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
925
+ /**
926
+ * Get the configuration needed to use this provider.
927
+ */
928
+ getConfig(): KeyProviderConfig;
929
+ }
930
+
931
+ /**
932
+ * Configuration for a key provider instance.
933
+ * @public
934
+ */
935
+ export declare interface KeyProviderConfig {
936
+ /** Provider type identifier */
937
+ type: string;
938
+ /** Provider-specific configuration */
939
+ options: Record<string, unknown>;
940
+ }
941
+
942
+ /**
943
+ * Type for a key provider factory function.
944
+ * @public
945
+ */
946
+ export declare type KeyProviderFactory = (config: KeyProviderConfig) => KeyProvider;
947
+
948
+ /**
949
+ * Registry for key provider implementations.
950
+ *
951
+ * @remarks
952
+ * The registry allows registration of custom key providers and provides
953
+ * a factory method to create provider instances from configuration.
954
+ *
955
+ * Note: This class is used as a namespace for static methods.
956
+ * @public
957
+ */
958
+ export declare class KeyProviderRegistry {
959
+ private static providers;
960
+ /**
961
+ * Register a key provider factory.
962
+ * @param type - Provider type identifier
963
+ * @param factory - Factory function to create provider instances
964
+ */
965
+ static register(type: string, factory: KeyProviderFactory): void;
966
+ /**
967
+ * Create a key provider from configuration.
968
+ * @param config - Provider configuration
969
+ * @returns A key provider instance
970
+ * @throws Error if the provider type is not registered
971
+ */
972
+ static create(config: KeyProviderConfig): KeyProvider;
973
+ /**
974
+ * Get all registered provider types.
975
+ * @returns Array of provider type identifiers
976
+ */
977
+ static getProviderTypes(): string[];
978
+ }
979
+
980
+ /**
981
+ * Key provider configuration in settings.
982
+ * @public
983
+ */
984
+ export declare interface KeyProviderSettings {
985
+ /** Provider type identifier */
986
+ type: string;
987
+ /** Provider-specific options */
988
+ options?: {
989
+ account?: string | undefined;
990
+ itemName?: string | undefined;
991
+ privateKeyPath?: string | undefined;
992
+ vault?: string | undefined;
993
+ } | undefined;
994
+ }
995
+
996
+ /**
997
+ * Result of a key retrieval operation.
998
+ * @public
999
+ */
1000
+ export declare interface KeyRetrievalResult {
1001
+ /**
1002
+ * Path to the private key file.
1003
+ * For ephemeral providers, this is a temporary file that must be cleaned up.
1004
+ */
1005
+ keyPath: string;
1006
+ /**
1007
+ * Cleanup function to call after signing is complete.
1008
+ * For filesystem provider, this is a no-op.
1009
+ * For 1Password provider, this securely deletes the temp file.
1010
+ */
1011
+ cleanup: () => Promise<void>;
1012
+ }
1013
+
366
1014
  /**
367
1015
  * List files in packages, respecting ignore patterns (async).
368
1016
  *
@@ -396,6 +1044,243 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
396
1044
  */
397
1045
  export declare function loadConfigSync(configPath?: string): Config;
398
1046
 
1047
+ /**
1048
+ * Load and validate local config from file (async).
1049
+ *
1050
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1051
+ * @returns Validated LocalConfig object, or null if file does not exist
1052
+ * @throws {LocalConfigValidationError} If validation fails
1053
+ * @public
1054
+ */
1055
+ export declare function loadLocalConfig(configPath?: string): Promise<LocalConfig | null>;
1056
+
1057
+ /**
1058
+ * Load and validate local config from file (sync).
1059
+ *
1060
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1061
+ * @returns Validated LocalConfig object, or null if file does not exist
1062
+ * @throws {LocalConfigValidationError} If validation fails
1063
+ * @public
1064
+ */
1065
+ export declare function loadLocalConfigSync(configPath?: string): LocalConfig | null;
1066
+
1067
+ /**
1068
+ * The local config file structure at ~/.config/attest-it/config.yaml.
1069
+ * @public
1070
+ */
1071
+ export declare interface LocalConfig {
1072
+ /** Name of the currently active identity */
1073
+ activeIdentity: string;
1074
+ /** Map of identity names to identity configurations */
1075
+ identities: Record<string, Identity>;
1076
+ }
1077
+
1078
+ /**
1079
+ * Error thrown when local config validation fails.
1080
+ * @public
1081
+ */
1082
+ export declare class LocalConfigValidationError extends Error {
1083
+ readonly issues: z.ZodIssue[];
1084
+ constructor(message: string, issues: z.ZodIssue[]);
1085
+ }
1086
+
1087
+ /**
1088
+ * Key provider that stores private keys in macOS Keychain.
1089
+ *
1090
+ * @remarks
1091
+ * This provider requires macOS and uses the `security` CLI tool.
1092
+ * Private keys are stored as base64-encoded strings in the keychain and decoded
1093
+ * to temporary files for signing operations.
1094
+ *
1095
+ * @public
1096
+ */
1097
+ export declare class MacOSKeychainKeyProvider implements KeyProvider {
1098
+ readonly type = "macos-keychain";
1099
+ readonly displayName = "macOS Keychain";
1100
+ private readonly itemName;
1101
+ private static readonly ACCOUNT;
1102
+ /**
1103
+ * Create a new MacOSKeychainKeyProvider.
1104
+ * @param options - Provider options
1105
+ */
1106
+ constructor(options: MacOSKeychainKeyProviderOptions);
1107
+ /**
1108
+ * Check if this provider is available.
1109
+ * Only available on macOS platforms.
1110
+ */
1111
+ static isAvailable(): boolean;
1112
+ /**
1113
+ * Check if this provider is available on the current system.
1114
+ */
1115
+ isAvailable(): Promise<boolean>;
1116
+ /**
1117
+ * Check if a key exists in the keychain.
1118
+ * @param keyRef - Item name in keychain
1119
+ */
1120
+ keyExists(keyRef: string): Promise<boolean>;
1121
+ /**
1122
+ * Get the private key from keychain for signing.
1123
+ * Downloads to a temporary file and returns a cleanup function.
1124
+ * @param keyRef - Item name in keychain
1125
+ * @throws Error if the key does not exist in keychain
1126
+ */
1127
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
1128
+ /**
1129
+ * Generate a new keypair and store private key in keychain.
1130
+ * Public key is written to filesystem for repository commit.
1131
+ * @param options - Key generation options
1132
+ */
1133
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
1134
+ /**
1135
+ * Get the configuration for this provider.
1136
+ */
1137
+ getConfig(): KeyProviderConfig;
1138
+ }
1139
+
1140
+ /**
1141
+ * Options for creating a MacOSKeychainKeyProvider.
1142
+ * @public
1143
+ */
1144
+ export declare interface MacOSKeychainKeyProviderOptions {
1145
+ /** Item name in keychain (e.g., "attest-it-private-key") */
1146
+ itemName: string;
1147
+ }
1148
+
1149
+ /**
1150
+ * Information about a 1Password account.
1151
+ * @public
1152
+ */
1153
+ export declare interface OnePasswordAccount {
1154
+ /** Account UUID */
1155
+ account_uuid: string;
1156
+ /** User email address */
1157
+ email: string;
1158
+ /** Account URL */
1159
+ url: string;
1160
+ /** User UUID */
1161
+ user_uuid: string;
1162
+ }
1163
+
1164
+ /**
1165
+ * Key provider that stores private keys in 1Password.
1166
+ *
1167
+ * @remarks
1168
+ * This provider requires the `op` CLI tool to be installed and authenticated.
1169
+ * Private keys are stored as documents in 1Password and downloaded to
1170
+ * temporary files for signing operations.
1171
+ *
1172
+ * @public
1173
+ */
1174
+ export declare class OnePasswordKeyProvider implements KeyProvider {
1175
+ readonly type = "1password";
1176
+ readonly displayName = "1Password";
1177
+ private readonly account?;
1178
+ private readonly vault;
1179
+ private readonly itemName;
1180
+ /**
1181
+ * Create a new OnePasswordKeyProvider.
1182
+ * @param options - Provider options
1183
+ */
1184
+ constructor(options: OnePasswordKeyProviderOptions);
1185
+ /**
1186
+ * Check if the 1Password CLI is installed.
1187
+ * @returns True if `op` command is available
1188
+ */
1189
+ static isInstalled(): Promise<boolean>;
1190
+ /**
1191
+ * List all 1Password accounts.
1192
+ * @returns Array of account information
1193
+ */
1194
+ static listAccounts(): Promise<OnePasswordAccount[]>;
1195
+ /**
1196
+ * List vaults in a specific account.
1197
+ * @param account - Account email (optional if only one account)
1198
+ * @returns Array of vault information
1199
+ */
1200
+ static listVaults(account?: string): Promise<OnePasswordVault[]>;
1201
+ /**
1202
+ * Check if this provider is available.
1203
+ * Requires `op` CLI to be installed and authenticated.
1204
+ */
1205
+ isAvailable(): Promise<boolean>;
1206
+ /**
1207
+ * Check if a key exists in 1Password.
1208
+ * @param keyRef - Item name in 1Password
1209
+ */
1210
+ keyExists(keyRef: string): Promise<boolean>;
1211
+ /**
1212
+ * Get the private key from 1Password for signing.
1213
+ * Downloads to a temporary file and returns a cleanup function.
1214
+ * @param keyRef - Item name in 1Password
1215
+ * @throws Error if the key does not exist in 1Password
1216
+ */
1217
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
1218
+ /**
1219
+ * Generate a new keypair and store private key in 1Password.
1220
+ * Public key is written to filesystem for repository commit.
1221
+ * @param options - Key generation options
1222
+ */
1223
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
1224
+ /**
1225
+ * Get the configuration for this provider.
1226
+ */
1227
+ getConfig(): KeyProviderConfig;
1228
+ }
1229
+
1230
+ /**
1231
+ * Options for creating a OnePasswordKeyProvider.
1232
+ * @public
1233
+ */
1234
+ export declare interface OnePasswordKeyProviderOptions {
1235
+ /** 1Password account email (optional if only one account) */
1236
+ account?: string;
1237
+ /** Vault name or ID where the key is stored */
1238
+ vault: string;
1239
+ /** Item name in 1Password */
1240
+ itemName: string;
1241
+ }
1242
+
1243
+ /**
1244
+ * Information about a 1Password vault.
1245
+ * @public
1246
+ */
1247
+ export declare interface OnePasswordVault {
1248
+ /** Vault UUID */
1249
+ id: string;
1250
+ /** Vault name */
1251
+ name: string;
1252
+ }
1253
+
1254
+ /**
1255
+ * Parse a duration string to milliseconds.
1256
+ * Uses the ms library to parse strings like "30d", "7d", "24h".
1257
+ *
1258
+ * @param duration - Duration string (e.g., "30d", "7d", "24h")
1259
+ * @returns Duration in milliseconds
1260
+ * @throws {Error} If duration string is invalid
1261
+ * @public
1262
+ */
1263
+ export declare function parseDuration(duration: string): number;
1264
+
1265
+ /**
1266
+ * Private key reference - points to where the key is stored.
1267
+ * @public
1268
+ */
1269
+ export declare type PrivateKeyRef = {
1270
+ account: string;
1271
+ service: string;
1272
+ type: 'keychain';
1273
+ } | {
1274
+ account?: string;
1275
+ field?: string;
1276
+ item: string;
1277
+ type: '1password';
1278
+ vault: string;
1279
+ } | {
1280
+ path: string;
1281
+ type: 'file';
1282
+ };
1283
+
399
1284
  /**
400
1285
  * Read attestations and verify the signature.
401
1286
  *
@@ -411,10 +1296,6 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
411
1296
  */
412
1297
  export declare function readAndVerifyAttestations(options: ReadSignedAttestationsOptions): Promise<AttestationsFile>;
413
1298
 
414
- /**
415
- * Attestation file I/O module with JSON canonicalization.
416
- */
417
-
418
1299
  /**
419
1300
  * Read attestations file from disk (async).
420
1301
  *
@@ -435,6 +1316,26 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
435
1316
  */
436
1317
  export declare function readAttestationsSync(filePath: string): AttestationsFile | null;
437
1318
 
1319
+ /**
1320
+ * Read seals from the seals.json file (async).
1321
+ *
1322
+ * @param dir - Directory containing .attest-it/seals.json
1323
+ * @returns The seals file contents, or an empty seals file if the file doesn't exist
1324
+ * @throws Error if file exists but cannot be read or parsed
1325
+ * @public
1326
+ */
1327
+ export declare function readSeals(dir: string): Promise<SealsFile>;
1328
+
1329
+ /**
1330
+ * Read seals from the seals.json file (sync).
1331
+ *
1332
+ * @param dir - Directory containing .attest-it/seals.json
1333
+ * @returns The seals file contents, or an empty seals file if the file doesn't exist
1334
+ * @throws Error if file exists but cannot be read or parsed
1335
+ * @public
1336
+ */
1337
+ export declare function readSealsSync(dir: string): SealsFile;
1338
+
438
1339
  /**
439
1340
  * Options for reading and verifying signed attestations.
440
1341
  * @public
@@ -471,6 +1372,70 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
471
1372
  */
472
1373
  export declare function resolveConfigPaths(config: Config, repoRoot: string): Config;
473
1374
 
1375
+ /**
1376
+ * Save local config to file (async).
1377
+ *
1378
+ * @param config - LocalConfig object to save
1379
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1380
+ * @throws {Error} If write fails
1381
+ * @public
1382
+ */
1383
+ export declare function saveLocalConfig(config: LocalConfig, configPath?: string): Promise<void>;
1384
+
1385
+ /**
1386
+ * Save local config to file (sync).
1387
+ *
1388
+ * @param config - LocalConfig object to save
1389
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1390
+ * @throws {Error} If write fails
1391
+ * @public
1392
+ */
1393
+ export declare function saveLocalConfigSync(config: LocalConfig, configPath?: string): void;
1394
+
1395
+ /**
1396
+ * A seal represents a cryptographic attestation that a gate's fingerprint
1397
+ * was signed by an authorized team member.
1398
+ * @public
1399
+ */
1400
+ export declare interface Seal {
1401
+ /** Gate identifier (slug) */
1402
+ gateId: string;
1403
+ /** SHA-256 fingerprint of the gate's content in format "sha256:..." */
1404
+ fingerprint: string;
1405
+ /** ISO 8601 timestamp when the seal was created */
1406
+ timestamp: string;
1407
+ /** Team member slug who created the seal */
1408
+ sealedBy: string;
1409
+ /** Base64-encoded Ed25519 signature of gateId:fingerprint:timestamp */
1410
+ signature: string;
1411
+ }
1412
+
1413
+ /**
1414
+ * The seals file structure stored at .attest-it/seals.json.
1415
+ * @public
1416
+ */
1417
+ export declare interface SealsFile {
1418
+ /** Schema version for forward compatibility */
1419
+ version: 1;
1420
+ /** Map of gate slugs to their seals */
1421
+ seals: Record<string, Seal>;
1422
+ }
1423
+
1424
+ /**
1425
+ * Result of verifying a single gate's seal.
1426
+ * @public
1427
+ */
1428
+ export declare interface SealVerificationResult {
1429
+ /** Gate identifier */
1430
+ gateId: string;
1431
+ /** Verification state */
1432
+ state: VerificationState;
1433
+ /** The seal, if one exists */
1434
+ seal?: Seal;
1435
+ /** Human-readable message explaining the state */
1436
+ message?: string;
1437
+ }
1438
+
474
1439
  /**
475
1440
  * Set restrictive permissions on a private key file.
476
1441
  * @param keyPath - Path to the private key
@@ -503,34 +1468,69 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
503
1468
  constructor(filePath: string);
504
1469
  }
505
1470
 
1471
+ /**
1472
+ * Result of seal signature verification.
1473
+ * @public
1474
+ */
1475
+ export declare interface SignatureVerificationResult {
1476
+ /** Whether the seal signature is valid */
1477
+ valid: boolean;
1478
+ /** Error message if verification failed */
1479
+ error?: string;
1480
+ }
1481
+
1482
+ /**
1483
+ * Sign data with an Ed25519 private key.
1484
+ *
1485
+ * @param data - Data to sign (Buffer or UTF-8 string)
1486
+ * @param privateKeyPem - PEM-encoded private key
1487
+ * @returns Base64-encoded signature
1488
+ * @throws Error if signing fails
1489
+ * @public
1490
+ */
1491
+ export declare function signEd25519(data: Buffer | string, privateKeyPem: string): string;
1492
+
506
1493
  /**
507
1494
  * Options for signing data.
508
1495
  * @public
509
1496
  */
510
1497
  export declare interface SignOptions {
511
- /** Path to the private key file */
512
- privateKeyPath: string;
1498
+ /** Path to the private key file (legacy) */
1499
+ privateKeyPath?: string;
1500
+ /** Key provider to use for retrieving the private key */
1501
+ keyProvider?: KeyProvider;
1502
+ /** Key reference for the provider */
1503
+ keyRef?: string;
513
1504
  /** Data to sign (string or Buffer) */
514
1505
  data: Buffer | string;
515
1506
  }
516
1507
 
517
1508
  /**
518
1509
  * Suite definition from the configuration file.
1510
+ * Suites are CLI-layer extensions of gates with command execution capabilities.
519
1511
  * @public
520
1512
  */
521
1513
  export declare interface SuiteConfig {
1514
+ /** Reference to a gate (if present, inherits gate configuration) */
1515
+ gate?: string;
522
1516
  /** Human-readable description of what this suite tests */
523
1517
  description?: string;
524
- /** Glob patterns for npm packages to include in fingerprint */
525
- packages: string[];
1518
+ /** Glob patterns for npm packages to include in fingerprint (legacy/backward compatibility) */
1519
+ packages?: string[];
526
1520
  /** Additional file patterns to include in fingerprint */
527
1521
  files?: string[];
528
1522
  /** Patterns to ignore when computing fingerprint */
529
1523
  ignore?: string[];
530
1524
  /** Command to execute for this suite (overrides defaultCommand) */
531
1525
  command?: string;
1526
+ /** Timeout for command execution (duration string) */
1527
+ timeout?: string;
1528
+ /** Whether the command is interactive */
1529
+ interactive?: boolean;
532
1530
  /** Other suite names that, when changed, invalidate this suite's attestation */
533
1531
  invalidates?: string[];
1532
+ /** Array of suite names this suite depends on */
1533
+ depends_on?: string[];
534
1534
  }
535
1535
 
536
1536
  /**
@@ -554,6 +1554,21 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
554
1554
  message?: string;
555
1555
  }
556
1556
 
1557
+ /**
1558
+ * Team member configuration.
1559
+ * @public
1560
+ */
1561
+ export declare interface TeamMember {
1562
+ /** Display name for the team member */
1563
+ name: string;
1564
+ /** Email address (optional) */
1565
+ email?: string | undefined;
1566
+ /** GitHub username (optional) */
1567
+ github?: string | undefined;
1568
+ /** Base64-encoded Ed25519 public key */
1569
+ publicKey: string;
1570
+ }
1571
+
557
1572
  /**
558
1573
  * Convert Zod-validated Config to AttestItConfig by removing undefined values.
559
1574
  *
@@ -582,6 +1597,12 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
582
1597
  */
583
1598
  export declare function upsertAttestation(attestations: Attestation[], newAttestation: Attestation): Attestation[];
584
1599
 
1600
+ /**
1601
+ * Verification state for a gate's seal.
1602
+ * @public
1603
+ */
1604
+ export declare type VerificationState = 'FINGERPRINT_MISMATCH' | 'INVALID_SIGNATURE' | 'MISSING' | 'STALE' | 'UNKNOWN_SIGNER' | 'VALID';
1605
+
585
1606
  /**
586
1607
  * Verification status codes for suite attestations.
587
1608
  * @public
@@ -601,6 +1622,17 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
601
1622
  */
602
1623
  export declare function verify(options: CryptoVerifyOptions): Promise<boolean>;
603
1624
 
1625
+ /**
1626
+ * Verify all gates' seals.
1627
+ *
1628
+ * @param config - The attest-it configuration
1629
+ * @param seals - The seals file containing all seals
1630
+ * @param fingerprints - Map of gate IDs to their current fingerprints
1631
+ * @returns Array of verification results for all gates
1632
+ * @public
1633
+ */
1634
+ export declare function verifyAllSeals(config: AttestItConfig, seals: SealsFile, fingerprints: Record<string, string>): SealVerificationResult[];
1635
+
604
1636
  /**
605
1637
  * Verify all attestations against current code state.
606
1638
  *
@@ -620,6 +1652,30 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
620
1652
  */
621
1653
  export declare function verifyAttestations(options: VerifyOptions): Promise<VerifyResult>;
622
1654
 
1655
+ /**
1656
+ * Verify an Ed25519 signature.
1657
+ *
1658
+ * @param data - Original data that was signed
1659
+ * @param signature - Base64-encoded signature to verify
1660
+ * @param publicKeyBase64 - Base64-encoded public key (raw 32 bytes)
1661
+ * @returns true if signature is valid, false otherwise
1662
+ * @throws Error if verification fails (not just invalid signature)
1663
+ * @public
1664
+ */
1665
+ export declare function verifyEd25519(data: Buffer | string, signature: string, publicKeyBase64: string): boolean;
1666
+
1667
+ /**
1668
+ * Verify a single gate's seal.
1669
+ *
1670
+ * @param config - The attest-it configuration
1671
+ * @param gateId - Gate identifier to verify
1672
+ * @param seals - The seals file containing all seals
1673
+ * @param currentFingerprint - Current computed fingerprint for the gate
1674
+ * @returns Verification result for the gate
1675
+ * @public
1676
+ */
1677
+ export declare function verifyGateSeal(config: AttestItConfig, gateId: string, seals: SealsFile, currentFingerprint: string): SealVerificationResult;
1678
+
623
1679
  /**
624
1680
  * Options for verifying attestations.
625
1681
  * @public
@@ -646,6 +1702,16 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
646
1702
  errors: string[];
647
1703
  }
648
1704
 
1705
+ /**
1706
+ * Verify a seal's signature against the team member's public key.
1707
+ *
1708
+ * @param seal - The seal to verify
1709
+ * @param config - The attest-it configuration containing team members
1710
+ * @returns Verification result with success status and optional error message
1711
+ * @public
1712
+ */
1713
+ export declare function verifySeal(seal: Seal, config: AttestItConfig): SignatureVerificationResult;
1714
+
649
1715
  /**
650
1716
  * Package version
651
1717
  * @public
@@ -680,6 +1746,26 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
680
1746
  */
681
1747
  export declare function writeAttestationsSync(filePath: string, attestations: Attestation[], signature: string): void;
682
1748
 
1749
+ /**
1750
+ * Write seals to the seals.json file (async).
1751
+ *
1752
+ * @param dir - Directory containing .attest-it/seals.json
1753
+ * @param sealsFile - The seals file to write
1754
+ * @throws Error if file cannot be written
1755
+ * @public
1756
+ */
1757
+ export declare function writeSeals(dir: string, sealsFile: SealsFile): Promise<void>;
1758
+
1759
+ /**
1760
+ * Write seals to the seals.json file (sync).
1761
+ *
1762
+ * @param dir - Directory containing .attest-it/seals.json
1763
+ * @param sealsFile - The seals file to write
1764
+ * @throws Error if file cannot be written
1765
+ * @public
1766
+ */
1767
+ export declare function writeSealsSync(dir: string, sealsFile: SealsFile): void;
1768
+
683
1769
  /**
684
1770
  * Write attestations with a cryptographic signature.
685
1771
  *
@@ -701,8 +1787,12 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
701
1787
  filePath: string;
702
1788
  /** Array of attestations to write */
703
1789
  attestations: Attestation[];
704
- /** Path to the private key for signing */
705
- privateKeyPath: string;
1790
+ /** Path to the private key for signing (legacy) */
1791
+ privateKeyPath?: string;
1792
+ /** Key provider for signing */
1793
+ keyProvider?: KeyProvider;
1794
+ /** Key reference for the provider */
1795
+ keyRef?: string;
706
1796
  }
707
1797
 
708
1798
  export { }