@attest-it/core 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,10 @@ 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>;
46
50
  /** Named groups of suites */
@@ -60,6 +64,8 @@ export declare interface AttestItSettings {
60
64
  attestationsPath: string;
61
65
  /** Default command to execute for attestation (can be overridden per suite) */
62
66
  defaultCommand?: string;
67
+ /** Key provider configuration for signing attestations */
68
+ keyProvider?: KeyProviderSettings;
63
69
  }
64
70
 
65
71
  /**
@@ -94,7 +100,7 @@ export declare function checkOpenSSL(): Promise<string>;
94
100
  * Algorithm:
95
101
  * 1. List all files in packages (respecting ignore globs)
96
102
  * 2. Sort files lexicographically by relative path
97
- * 3. For each file: compute SHA256(relativePath + "\0" + content)
103
+ * 3. For each file: compute SHA256(relativePath + ":" + content)
98
104
  * 4. Concatenate all file hashes in sorted order
99
105
  * 5. Compute final SHA256 of concatenated hashes
100
106
  * 6. Return "sha256:" + hex(fingerprint)
@@ -136,70 +142,281 @@ export declare class ConfigNotFoundError extends Error {
136
142
  * Zod schema for the full configuration file.
137
143
  */
138
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
+ }>>>;
139
179
  groups: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
140
180
  settings: z.ZodDefault<z.ZodObject<{
141
181
  attestationsPath: z.ZodDefault<z.ZodString>;
142
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
+ }>>;
143
218
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
144
219
  publicKeyPath: z.ZodDefault<z.ZodString>;
145
220
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
146
221
  attestationsPath: z.ZodDefault<z.ZodString>;
147
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
+ }>>;
148
258
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
149
259
  publicKeyPath: z.ZodDefault<z.ZodString>;
150
260
  }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
151
261
  attestationsPath: z.ZodDefault<z.ZodString>;
152
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
+ }>>;
153
298
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
154
299
  publicKeyPath: z.ZodDefault<z.ZodString>;
155
300
  }, z.ZodTypeAny, "passthrough">>>;
156
- suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
301
+ suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
157
302
  command: z.ZodOptional<z.ZodString>;
158
303
  depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
159
304
  description: z.ZodOptional<z.ZodString>;
160
305
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
306
+ gate: z.ZodOptional<z.ZodString>;
161
307
  ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
308
+ interactive: z.ZodOptional<z.ZodBoolean>;
162
309
  invalidates: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
163
- packages: z.ZodArray<z.ZodString, "many">;
310
+ packages: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
311
+ timeout: z.ZodOptional<z.ZodString>;
164
312
  }, "strict", z.ZodTypeAny, {
165
313
  command?: string | undefined;
166
314
  depends_on?: string[] | undefined;
167
315
  description?: string | undefined;
168
316
  files?: string[] | undefined;
317
+ gate?: string | undefined;
169
318
  ignore?: string[] | undefined;
319
+ interactive?: boolean | undefined;
170
320
  invalidates?: string[] | undefined;
171
- packages: string[];
321
+ packages?: string[] | undefined;
322
+ timeout?: string | undefined;
172
323
  }, {
173
324
  command?: string | undefined;
174
325
  depends_on?: string[] | undefined;
175
326
  description?: string | undefined;
176
327
  files?: string[] | undefined;
328
+ gate?: string | undefined;
177
329
  ignore?: string[] | undefined;
330
+ interactive?: boolean | undefined;
178
331
  invalidates?: string[] | undefined;
179
- 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;
180
356
  }>>, Record<string, {
181
357
  command?: string | undefined;
182
358
  depends_on?: string[] | undefined;
183
359
  description?: string | undefined;
184
360
  files?: string[] | undefined;
361
+ gate?: string | undefined;
185
362
  ignore?: string[] | undefined;
363
+ interactive?: boolean | undefined;
186
364
  invalidates?: string[] | undefined;
187
- packages: string[];
365
+ packages?: string[] | undefined;
366
+ timeout?: string | undefined;
188
367
  }>, Record<string, {
189
368
  command?: string | undefined;
190
369
  depends_on?: string[] | undefined;
191
370
  description?: string | undefined;
192
371
  files?: string[] | undefined;
372
+ gate?: string | undefined;
193
373
  ignore?: string[] | undefined;
374
+ interactive?: boolean | undefined;
194
375
  invalidates?: string[] | undefined;
195
- packages: string[];
376
+ packages?: string[] | undefined;
377
+ timeout?: string | undefined;
196
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
+ }>>>;
197
395
  version: z.ZodLiteral<1>;
198
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;
199
407
  groups?: Record<string, string[]> | undefined;
200
408
  settings: {
201
409
  attestationsPath: string;
202
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;
203
420
  maxAgeDays: number;
204
421
  publicKeyPath: string;
205
422
  } & { [k: string]: unknown };
@@ -208,16 +425,70 @@ declare const configSchema: z.ZodObject<{
208
425
  depends_on?: string[] | undefined;
209
426
  description?: string | undefined;
210
427
  files?: string[] | undefined;
428
+ gate?: string | undefined;
211
429
  ignore?: string[] | undefined;
430
+ interactive?: boolean | undefined;
212
431
  invalidates?: string[] | undefined;
213
- packages: string[];
432
+ packages?: string[] | undefined;
433
+ timeout?: string | undefined;
214
434
  }>;
435
+ team?: Record<string, {
436
+ email?: string | undefined;
437
+ github?: string | undefined;
438
+ name: string;
439
+ publicKey: string;
440
+ }> | undefined;
215
441
  version: 1;
216
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;
217
453
  groups?: Record<string, string[]> | undefined;
218
454
  settings?: undefined | z.objectInputType<{
219
455
  attestationsPath: z.ZodDefault<z.ZodString>;
220
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
+ }>>;
221
492
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
222
493
  publicKeyPath: z.ZodDefault<z.ZodString>;
223
494
  }, z.ZodTypeAny, "passthrough">;
@@ -226,10 +497,19 @@ declare const configSchema: z.ZodObject<{
226
497
  depends_on?: string[] | undefined;
227
498
  description?: string | undefined;
228
499
  files?: string[] | undefined;
500
+ gate?: string | undefined;
229
501
  ignore?: string[] | undefined;
502
+ interactive?: boolean | undefined;
230
503
  invalidates?: string[] | undefined;
231
- packages: string[];
504
+ packages?: string[] | undefined;
505
+ timeout?: string | undefined;
232
506
  }>;
507
+ team?: Record<string, {
508
+ email?: string | undefined;
509
+ github?: string | undefined;
510
+ name: string;
511
+ publicKey: string;
512
+ }> | undefined;
233
513
  version: 1;
234
514
  }>;
235
515
 
@@ -261,6 +541,31 @@ export declare function createAttestation(params: {
261
541
  suite: string;
262
542
  }): Attestation;
263
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
+
264
569
  /**
265
570
  * Options for verifying signatures.
266
571
  * @public
@@ -274,6 +579,73 @@ export declare interface CryptoVerifyOptions {
274
579
  signature: string;
275
580
  }
276
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
+
277
649
  /**
278
650
  * Find an attestation for a specific suite.
279
651
  *
@@ -298,6 +670,27 @@ export declare function findAttestation(attestations: AttestationsFile, suite: s
298
670
  */
299
671
  export declare function findConfigPath(startDir?: string): null | string;
300
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
+
301
694
  /**
302
695
  * Options for computing a package fingerprint.
303
696
  * @public
@@ -324,6 +717,32 @@ export declare interface FingerprintResult {
324
717
  fileCount: number;
325
718
  }
326
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
+
327
746
  /**
328
747
  * Generate a new RSA-2048 keypair using OpenSSL.
329
748
  *
@@ -337,6 +756,25 @@ export declare interface FingerprintResult {
337
756
  */
338
757
  export declare function generateKeyPair(options?: KeygenOptions): Promise<KeyPaths>;
339
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
+
340
778
  /**
341
779
  * Get the default private key path based on OS.
342
780
  * - macOS/Linux: ~/.config/attest-it/private.pem
@@ -351,6 +789,75 @@ export declare function getDefaultPrivateKeyPath(): string;
351
789
  */
352
790
  export declare function getDefaultPublicKeyPath(): string;
353
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
+
354
861
  /**
355
862
  * Options for key generation.
356
863
  * @public
@@ -364,6 +871,17 @@ export declare interface KeygenOptions {
364
871
  force?: boolean;
365
872
  }
366
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
+
367
885
  /**
368
886
  * Paths to a generated keypair.
369
887
  * @public
@@ -375,6 +893,124 @@ export declare interface KeyPaths {
375
893
  publicPath: string;
376
894
  }
377
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
+
378
1014
  /**
379
1015
  * List files in packages, respecting ignore patterns (async).
380
1016
  *
@@ -408,6 +1044,243 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
408
1044
  */
409
1045
  export declare function loadConfigSync(configPath?: string): Config;
410
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
+
411
1284
  /**
412
1285
  * Read attestations and verify the signature.
413
1286
  *
@@ -423,10 +1296,6 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
423
1296
  */
424
1297
  export declare function readAndVerifyAttestations(options: ReadSignedAttestationsOptions): Promise<AttestationsFile>;
425
1298
 
426
- /**
427
- * Attestation file I/O module with JSON canonicalization.
428
- */
429
-
430
1299
  /**
431
1300
  * Read attestations file from disk (async).
432
1301
  *
@@ -447,6 +1316,26 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
447
1316
  */
448
1317
  export declare function readAttestationsSync(filePath: string): AttestationsFile | null;
449
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
+
450
1339
  /**
451
1340
  * Options for reading and verifying signed attestations.
452
1341
  * @public
@@ -483,6 +1372,70 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
483
1372
  */
484
1373
  export declare function resolveConfigPaths(config: Config, repoRoot: string): Config;
485
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
+
486
1439
  /**
487
1440
  * Set restrictive permissions on a private key file.
488
1441
  * @param keyPath - Path to the private key
@@ -515,32 +1468,65 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
515
1468
  constructor(filePath: string);
516
1469
  }
517
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
+
518
1493
  /**
519
1494
  * Options for signing data.
520
1495
  * @public
521
1496
  */
522
1497
  export declare interface SignOptions {
523
- /** Path to the private key file */
524
- 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;
525
1504
  /** Data to sign (string or Buffer) */
526
1505
  data: Buffer | string;
527
1506
  }
528
1507
 
529
1508
  /**
530
1509
  * Suite definition from the configuration file.
1510
+ * Suites are CLI-layer extensions of gates with command execution capabilities.
531
1511
  * @public
532
1512
  */
533
1513
  export declare interface SuiteConfig {
1514
+ /** Reference to a gate (if present, inherits gate configuration) */
1515
+ gate?: string;
534
1516
  /** Human-readable description of what this suite tests */
535
1517
  description?: string;
536
- /** Glob patterns for npm packages to include in fingerprint */
537
- packages: string[];
1518
+ /** Glob patterns for npm packages to include in fingerprint (legacy/backward compatibility) */
1519
+ packages?: string[];
538
1520
  /** Additional file patterns to include in fingerprint */
539
1521
  files?: string[];
540
1522
  /** Patterns to ignore when computing fingerprint */
541
1523
  ignore?: string[];
542
1524
  /** Command to execute for this suite (overrides defaultCommand) */
543
1525
  command?: string;
1526
+ /** Timeout for command execution (duration string) */
1527
+ timeout?: string;
1528
+ /** Whether the command is interactive */
1529
+ interactive?: boolean;
544
1530
  /** Other suite names that, when changed, invalidate this suite's attestation */
545
1531
  invalidates?: string[];
546
1532
  /** Array of suite names this suite depends on */
@@ -568,6 +1554,21 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
568
1554
  message?: string;
569
1555
  }
570
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
+
571
1572
  /**
572
1573
  * Convert Zod-validated Config to AttestItConfig by removing undefined values.
573
1574
  *
@@ -596,6 +1597,12 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
596
1597
  */
597
1598
  export declare function upsertAttestation(attestations: Attestation[], newAttestation: Attestation): Attestation[];
598
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
+
599
1606
  /**
600
1607
  * Verification status codes for suite attestations.
601
1608
  * @public
@@ -615,6 +1622,17 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
615
1622
  */
616
1623
  export declare function verify(options: CryptoVerifyOptions): Promise<boolean>;
617
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
+
618
1636
  /**
619
1637
  * Verify all attestations against current code state.
620
1638
  *
@@ -634,6 +1652,30 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
634
1652
  */
635
1653
  export declare function verifyAttestations(options: VerifyOptions): Promise<VerifyResult>;
636
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
+
637
1679
  /**
638
1680
  * Options for verifying attestations.
639
1681
  * @public
@@ -660,6 +1702,16 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
660
1702
  errors: string[];
661
1703
  }
662
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
+
663
1715
  /**
664
1716
  * Package version
665
1717
  * @public
@@ -694,6 +1746,26 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
694
1746
  */
695
1747
  export declare function writeAttestationsSync(filePath: string, attestations: Attestation[], signature: string): void;
696
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
+
697
1769
  /**
698
1770
  * Write attestations with a cryptographic signature.
699
1771
  *
@@ -715,8 +1787,12 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
715
1787
  filePath: string;
716
1788
  /** Array of attestations to write */
717
1789
  attestations: Attestation[];
718
- /** Path to the private key for signing */
719
- 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;
720
1796
  }
721
1797
 
722
1798
  export { }