@attest-it/core 0.2.0 → 0.5.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;
329
+ ignore?: string[] | undefined;
330
+ interactive?: boolean | undefined;
331
+ invalidates?: string[] | undefined;
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;
177
340
  ignore?: string[] | undefined;
341
+ interactive?: boolean | undefined;
178
342
  invalidates?: string[] | undefined;
179
- packages: string[];
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,44 @@ 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 the attest-it configuration directory.
770
+ *
771
+ * If a home directory override is set via setAttestItHomeDir(),
772
+ * returns that directory. Otherwise returns ~/.config/attest-it.
773
+ *
774
+ * @returns Path to the configuration directory
775
+ * @public
776
+ */
777
+ export declare function getAttestItConfigDir(): string;
778
+
779
+ /**
780
+ * Get the current attest-it home directory override.
781
+ *
782
+ * @returns The override directory, or null if using default
783
+ * @public
784
+ */
785
+ export declare function getAttestItHomeDir(): null | string;
786
+
787
+ /**
788
+ * Get all team members authorized to sign for a gate.
789
+ *
790
+ * @param config - The attest-it configuration
791
+ * @param gateId - The gate identifier (slug)
792
+ * @returns Array of authorized team members, or empty array if gate not found
793
+ * @public
794
+ */
795
+ export declare function getAuthorizedSignersForGate(config: AttestItConfig, gateId: string): TeamMember[];
796
+
340
797
  /**
341
798
  * Get the default private key path based on OS.
342
799
  * - macOS/Linux: ~/.config/attest-it/private.pem
@@ -351,6 +808,78 @@ export declare function getDefaultPrivateKeyPath(): string;
351
808
  */
352
809
  export declare function getDefaultPublicKeyPath(): string;
353
810
 
811
+ /**
812
+ * Get the gate configuration for a given gate ID.
813
+ *
814
+ * @param config - The attest-it configuration
815
+ * @param gateId - The gate identifier (slug)
816
+ * @returns The gate configuration, or undefined if not found
817
+ * @public
818
+ */
819
+ export declare function getGate(config: AttestItConfig, gateId: string): GateConfig | undefined;
820
+
821
+ /**
822
+ * Get the path to the local config file.
823
+ *
824
+ * If a home directory override is set via setAttestItHomeDir(),
825
+ * returns {homeDir}/config.yaml. Otherwise returns ~/.config/attest-it/config.yaml.
826
+ *
827
+ * @returns Path to the local config file
828
+ * @public
829
+ */
830
+ export declare function getLocalConfigPath(): string;
831
+
832
+ /**
833
+ * Extract the public key from an Ed25519 private key.
834
+ *
835
+ * @param privateKeyPem - PEM-encoded private key
836
+ * @returns Base64-encoded public key (raw 32 bytes)
837
+ * @throws Error if extraction fails
838
+ * @public
839
+ */
840
+ export declare function getPublicKeyFromPrivate(privateKeyPem: string): string;
841
+
842
+ /**
843
+ * A single identity configuration.
844
+ * @public
845
+ */
846
+ export declare interface Identity {
847
+ /** Identity name (unique identifier) */
848
+ name: string;
849
+ /** Email address associated with this identity */
850
+ email?: string;
851
+ /** GitHub username associated with this identity */
852
+ github?: string;
853
+ /** Base64 Ed25519 public key */
854
+ publicKey: string;
855
+ /** Reference to where the private key is stored */
856
+ privateKey: PrivateKeyRef;
857
+ }
858
+
859
+ /**
860
+ * Check if a public key belongs to an authorized signer for a gate.
861
+ *
862
+ * @param config - The attest-it configuration
863
+ * @param gateId - The gate identifier (slug)
864
+ * @param publicKey - Base64-encoded Ed25519 public key to check
865
+ * @returns true if the public key belongs to an authorized signer for the gate
866
+ * @public
867
+ */
868
+ export declare function isAuthorizedSigner(config: AttestItConfig, gateId: string, publicKey: string): boolean;
869
+
870
+ /**
871
+ * Result of key generation.
872
+ * @public
873
+ */
874
+ export declare interface KeyGenerationResult {
875
+ /** Path or reference to the private key */
876
+ privateKeyRef: string;
877
+ /** Path to the public key file (always filesystem for commit to repo) */
878
+ publicKeyPath: string;
879
+ /** Human-readable storage location description */
880
+ storageDescription: string;
881
+ }
882
+
354
883
  /**
355
884
  * Options for key generation.
356
885
  * @public
@@ -364,6 +893,17 @@ export declare interface KeygenOptions {
364
893
  force?: boolean;
365
894
  }
366
895
 
896
+ /**
897
+ * Options for key generation via provider.
898
+ * @public
899
+ */
900
+ export declare interface KeygenProviderOptions {
901
+ /** Path for public key output (always filesystem) */
902
+ publicKeyPath: string;
903
+ /** Overwrite existing keys */
904
+ force?: boolean;
905
+ }
906
+
367
907
  /**
368
908
  * Paths to a generated keypair.
369
909
  * @public
@@ -375,6 +915,124 @@ export declare interface KeyPaths {
375
915
  publicPath: string;
376
916
  }
377
917
 
918
+ /**
919
+ * Abstract interface for key storage providers.
920
+ * @public
921
+ */
922
+ export declare interface KeyProvider {
923
+ /** Unique identifier for this provider type */
924
+ readonly type: string;
925
+ /** Human-readable name for display */
926
+ readonly displayName: string;
927
+ /**
928
+ * Check if this provider is available on the current system.
929
+ */
930
+ isAvailable(): Promise<boolean>;
931
+ /**
932
+ * Check if a key exists in this provider.
933
+ * @param keyRef - Provider-specific key reference
934
+ */
935
+ keyExists(keyRef: string): Promise<boolean>;
936
+ /**
937
+ * Retrieve the private key for signing.
938
+ * Returns a temporary file path that can be passed to OpenSSL.
939
+ * Caller MUST call cleanup() after signing is complete.
940
+ */
941
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
942
+ /**
943
+ * Generate a new keypair and store the private key.
944
+ * Public key is always written to filesystem for repository commit.
945
+ */
946
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
947
+ /**
948
+ * Get the configuration needed to use this provider.
949
+ */
950
+ getConfig(): KeyProviderConfig;
951
+ }
952
+
953
+ /**
954
+ * Configuration for a key provider instance.
955
+ * @public
956
+ */
957
+ export declare interface KeyProviderConfig {
958
+ /** Provider type identifier */
959
+ type: string;
960
+ /** Provider-specific configuration */
961
+ options: Record<string, unknown>;
962
+ }
963
+
964
+ /**
965
+ * Type for a key provider factory function.
966
+ * @public
967
+ */
968
+ export declare type KeyProviderFactory = (config: KeyProviderConfig) => KeyProvider;
969
+
970
+ /**
971
+ * Registry for key provider implementations.
972
+ *
973
+ * @remarks
974
+ * The registry allows registration of custom key providers and provides
975
+ * a factory method to create provider instances from configuration.
976
+ *
977
+ * Note: This class is used as a namespace for static methods.
978
+ * @public
979
+ */
980
+ export declare class KeyProviderRegistry {
981
+ private static providers;
982
+ /**
983
+ * Register a key provider factory.
984
+ * @param type - Provider type identifier
985
+ * @param factory - Factory function to create provider instances
986
+ */
987
+ static register(type: string, factory: KeyProviderFactory): void;
988
+ /**
989
+ * Create a key provider from configuration.
990
+ * @param config - Provider configuration
991
+ * @returns A key provider instance
992
+ * @throws Error if the provider type is not registered
993
+ */
994
+ static create(config: KeyProviderConfig): KeyProvider;
995
+ /**
996
+ * Get all registered provider types.
997
+ * @returns Array of provider type identifiers
998
+ */
999
+ static getProviderTypes(): string[];
1000
+ }
1001
+
1002
+ /**
1003
+ * Key provider configuration in settings.
1004
+ * @public
1005
+ */
1006
+ export declare interface KeyProviderSettings {
1007
+ /** Provider type identifier */
1008
+ type: string;
1009
+ /** Provider-specific options */
1010
+ options?: {
1011
+ account?: string | undefined;
1012
+ itemName?: string | undefined;
1013
+ privateKeyPath?: string | undefined;
1014
+ vault?: string | undefined;
1015
+ } | undefined;
1016
+ }
1017
+
1018
+ /**
1019
+ * Result of a key retrieval operation.
1020
+ * @public
1021
+ */
1022
+ export declare interface KeyRetrievalResult {
1023
+ /**
1024
+ * Path to the private key file.
1025
+ * For ephemeral providers, this is a temporary file that must be cleaned up.
1026
+ */
1027
+ keyPath: string;
1028
+ /**
1029
+ * Cleanup function to call after signing is complete.
1030
+ * For filesystem provider, this is a no-op.
1031
+ * For 1Password provider, this securely deletes the temp file.
1032
+ */
1033
+ cleanup: () => Promise<void>;
1034
+ }
1035
+
378
1036
  /**
379
1037
  * List files in packages, respecting ignore patterns (async).
380
1038
  *
@@ -408,6 +1066,263 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
408
1066
  */
409
1067
  export declare function loadConfigSync(configPath?: string): Config;
410
1068
 
1069
+ /**
1070
+ * Load and validate local config from file (async).
1071
+ *
1072
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1073
+ * @returns Validated LocalConfig object, or null if file does not exist
1074
+ * @throws {LocalConfigValidationError} If validation fails
1075
+ * @public
1076
+ */
1077
+ export declare function loadLocalConfig(configPath?: string): Promise<LocalConfig | null>;
1078
+
1079
+ /**
1080
+ * Load and validate local config from file (sync).
1081
+ *
1082
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1083
+ * @returns Validated LocalConfig object, or null if file does not exist
1084
+ * @throws {LocalConfigValidationError} If validation fails
1085
+ * @public
1086
+ */
1087
+ export declare function loadLocalConfigSync(configPath?: string): LocalConfig | null;
1088
+
1089
+ /**
1090
+ * The local config file structure at ~/.config/attest-it/config.yaml.
1091
+ * @public
1092
+ */
1093
+ export declare interface LocalConfig {
1094
+ /** Name of the currently active identity */
1095
+ activeIdentity: string;
1096
+ /** Map of identity names to identity configurations */
1097
+ identities: Record<string, Identity>;
1098
+ }
1099
+
1100
+ /**
1101
+ * Error thrown when local config validation fails.
1102
+ * @public
1103
+ */
1104
+ export declare class LocalConfigValidationError extends Error {
1105
+ readonly issues: z.ZodIssue[];
1106
+ constructor(message: string, issues: z.ZodIssue[]);
1107
+ }
1108
+
1109
+ /**
1110
+ * Information about a macOS keychain.
1111
+ * @public
1112
+ */
1113
+ export declare interface MacOSKeychain {
1114
+ /** Full path to the keychain file */
1115
+ path: string;
1116
+ /** Display name (filename without extension) */
1117
+ name: string;
1118
+ }
1119
+
1120
+ /**
1121
+ * Key provider that stores private keys in macOS Keychain.
1122
+ *
1123
+ * @remarks
1124
+ * This provider requires macOS and uses the `security` CLI tool.
1125
+ * Private keys are stored as base64-encoded strings in the keychain and decoded
1126
+ * to temporary files for signing operations.
1127
+ *
1128
+ * @public
1129
+ */
1130
+ export declare class MacOSKeychainKeyProvider implements KeyProvider {
1131
+ readonly type = "macos-keychain";
1132
+ readonly displayName = "macOS Keychain";
1133
+ private readonly itemName;
1134
+ private readonly keychain?;
1135
+ private static readonly ACCOUNT;
1136
+ /**
1137
+ * Create a new MacOSKeychainKeyProvider.
1138
+ * @param options - Provider options
1139
+ */
1140
+ constructor(options: MacOSKeychainKeyProviderOptions);
1141
+ /**
1142
+ * Check if this provider is available.
1143
+ * Only available on macOS platforms.
1144
+ */
1145
+ static isAvailable(): boolean;
1146
+ /**
1147
+ * List available keychains on the system.
1148
+ * @returns Array of keychain information
1149
+ */
1150
+ static listKeychains(): Promise<MacOSKeychain[]>;
1151
+ /**
1152
+ * Check if this provider is available on the current system.
1153
+ */
1154
+ isAvailable(): Promise<boolean>;
1155
+ /**
1156
+ * Check if a key exists in the keychain.
1157
+ * @param keyRef - Item name in keychain
1158
+ */
1159
+ keyExists(keyRef: string): Promise<boolean>;
1160
+ /**
1161
+ * Get the private key from keychain for signing.
1162
+ * Downloads to a temporary file and returns a cleanup function.
1163
+ * @param keyRef - Item name in keychain
1164
+ * @throws Error if the key does not exist in keychain
1165
+ */
1166
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
1167
+ /**
1168
+ * Generate a new keypair and store private key in keychain.
1169
+ * Public key is written to filesystem for repository commit.
1170
+ * @param options - Key generation options
1171
+ */
1172
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
1173
+ /**
1174
+ * Get the configuration for this provider.
1175
+ */
1176
+ getConfig(): KeyProviderConfig;
1177
+ }
1178
+
1179
+ /**
1180
+ * Options for creating a MacOSKeychainKeyProvider.
1181
+ * @public
1182
+ */
1183
+ export declare interface MacOSKeychainKeyProviderOptions {
1184
+ /** Item name in keychain (e.g., "attest-it-private-key") */
1185
+ itemName: string;
1186
+ /** Path to the keychain file (optional, uses default keychain if not specified) */
1187
+ keychain?: string;
1188
+ }
1189
+
1190
+ /**
1191
+ * Information about a 1Password account.
1192
+ * @public
1193
+ */
1194
+ export declare interface OnePasswordAccount {
1195
+ /** Account UUID */
1196
+ account_uuid: string;
1197
+ /** User email address */
1198
+ email: string;
1199
+ /** Account URL */
1200
+ url: string;
1201
+ /** User UUID */
1202
+ user_uuid: string;
1203
+ }
1204
+
1205
+ /**
1206
+ * Key provider that stores private keys in 1Password.
1207
+ *
1208
+ * @remarks
1209
+ * This provider requires the `op` CLI tool to be installed and authenticated.
1210
+ * Private keys are stored as documents in 1Password and downloaded to
1211
+ * temporary files for signing operations.
1212
+ *
1213
+ * @public
1214
+ */
1215
+ export declare class OnePasswordKeyProvider implements KeyProvider {
1216
+ readonly type = "1password";
1217
+ readonly displayName = "1Password";
1218
+ private readonly account?;
1219
+ private readonly vault;
1220
+ private readonly itemName;
1221
+ /**
1222
+ * Create a new OnePasswordKeyProvider.
1223
+ * @param options - Provider options
1224
+ */
1225
+ constructor(options: OnePasswordKeyProviderOptions);
1226
+ /**
1227
+ * Check if the 1Password CLI is installed.
1228
+ * @returns True if `op` command is available
1229
+ */
1230
+ static isInstalled(): Promise<boolean>;
1231
+ /**
1232
+ * List all 1Password accounts.
1233
+ * @returns Array of account information
1234
+ */
1235
+ static listAccounts(): Promise<OnePasswordAccount[]>;
1236
+ /**
1237
+ * List vaults in a specific account.
1238
+ * @param account - Account email (optional if only one account)
1239
+ * @returns Array of vault information
1240
+ */
1241
+ static listVaults(account?: string): Promise<OnePasswordVault[]>;
1242
+ /**
1243
+ * Check if this provider is available.
1244
+ * Requires `op` CLI to be installed and authenticated.
1245
+ */
1246
+ isAvailable(): Promise<boolean>;
1247
+ /**
1248
+ * Check if a key exists in 1Password.
1249
+ * @param keyRef - Item name in 1Password
1250
+ */
1251
+ keyExists(keyRef: string): Promise<boolean>;
1252
+ /**
1253
+ * Get the private key from 1Password for signing.
1254
+ * Downloads to a temporary file and returns a cleanup function.
1255
+ * @param keyRef - Item name in 1Password
1256
+ * @throws Error if the key does not exist in 1Password
1257
+ */
1258
+ getPrivateKey(keyRef: string): Promise<KeyRetrievalResult>;
1259
+ /**
1260
+ * Generate a new keypair and store private key in 1Password.
1261
+ * Public key is written to filesystem for repository commit.
1262
+ * @param options - Key generation options
1263
+ */
1264
+ generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult>;
1265
+ /**
1266
+ * Get the configuration for this provider.
1267
+ */
1268
+ getConfig(): KeyProviderConfig;
1269
+ }
1270
+
1271
+ /**
1272
+ * Options for creating a OnePasswordKeyProvider.
1273
+ * @public
1274
+ */
1275
+ export declare interface OnePasswordKeyProviderOptions {
1276
+ /** 1Password account email (optional if only one account) */
1277
+ account?: string;
1278
+ /** Vault name or ID where the key is stored */
1279
+ vault: string;
1280
+ /** Item name in 1Password */
1281
+ itemName: string;
1282
+ }
1283
+
1284
+ /**
1285
+ * Information about a 1Password vault.
1286
+ * @public
1287
+ */
1288
+ export declare interface OnePasswordVault {
1289
+ /** Vault UUID */
1290
+ id: string;
1291
+ /** Vault name */
1292
+ name: string;
1293
+ }
1294
+
1295
+ /**
1296
+ * Parse a duration string to milliseconds.
1297
+ * Uses the ms library to parse strings like "30d", "7d", "24h".
1298
+ *
1299
+ * @param duration - Duration string (e.g., "30d", "7d", "24h")
1300
+ * @returns Duration in milliseconds
1301
+ * @throws {Error} If duration string is invalid
1302
+ * @public
1303
+ */
1304
+ export declare function parseDuration(duration: string): number;
1305
+
1306
+ /**
1307
+ * Private key reference - points to where the key is stored.
1308
+ * @public
1309
+ */
1310
+ export declare type PrivateKeyRef = {
1311
+ account: string;
1312
+ keychain?: string;
1313
+ service: string;
1314
+ type: 'keychain';
1315
+ } | {
1316
+ account?: string;
1317
+ field?: string;
1318
+ item: string;
1319
+ type: '1password';
1320
+ vault: string;
1321
+ } | {
1322
+ path: string;
1323
+ type: 'file';
1324
+ };
1325
+
411
1326
  /**
412
1327
  * Read attestations and verify the signature.
413
1328
  *
@@ -423,10 +1338,6 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
423
1338
  */
424
1339
  export declare function readAndVerifyAttestations(options: ReadSignedAttestationsOptions): Promise<AttestationsFile>;
425
1340
 
426
- /**
427
- * Attestation file I/O module with JSON canonicalization.
428
- */
429
-
430
1341
  /**
431
1342
  * Read attestations file from disk (async).
432
1343
  *
@@ -447,6 +1358,26 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
447
1358
  */
448
1359
  export declare function readAttestationsSync(filePath: string): AttestationsFile | null;
449
1360
 
1361
+ /**
1362
+ * Read seals from the seals.json file (async).
1363
+ *
1364
+ * @param dir - Directory containing .attest-it/seals.json
1365
+ * @returns The seals file contents, or an empty seals file if the file doesn't exist
1366
+ * @throws Error if file exists but cannot be read or parsed
1367
+ * @public
1368
+ */
1369
+ export declare function readSeals(dir: string): Promise<SealsFile>;
1370
+
1371
+ /**
1372
+ * Read seals from the seals.json file (sync).
1373
+ *
1374
+ * @param dir - Directory containing .attest-it/seals.json
1375
+ * @returns The seals file contents, or an empty seals file if the file doesn't exist
1376
+ * @throws Error if file exists but cannot be read or parsed
1377
+ * @public
1378
+ */
1379
+ export declare function readSealsSync(dir: string): SealsFile;
1380
+
450
1381
  /**
451
1382
  * Options for reading and verifying signed attestations.
452
1383
  * @public
@@ -483,6 +1414,79 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
483
1414
  */
484
1415
  export declare function resolveConfigPaths(config: Config, repoRoot: string): Config;
485
1416
 
1417
+ /**
1418
+ * Save local config to file (async).
1419
+ *
1420
+ * @param config - LocalConfig object to save
1421
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1422
+ * @throws {Error} If write fails
1423
+ * @public
1424
+ */
1425
+ export declare function saveLocalConfig(config: LocalConfig, configPath?: string): Promise<void>;
1426
+
1427
+ /**
1428
+ * Save local config to file (sync).
1429
+ *
1430
+ * @param config - LocalConfig object to save
1431
+ * @param configPath - Optional path to config file. If not provided, uses default location.
1432
+ * @throws {Error} If write fails
1433
+ * @public
1434
+ */
1435
+ export declare function saveLocalConfigSync(config: LocalConfig, configPath?: string): void;
1436
+
1437
+ /**
1438
+ * A seal represents a cryptographic attestation that a gate's fingerprint
1439
+ * was signed by an authorized team member.
1440
+ * @public
1441
+ */
1442
+ export declare interface Seal {
1443
+ /** Gate identifier (slug) */
1444
+ gateId: string;
1445
+ /** SHA-256 fingerprint of the gate's content in format "sha256:..." */
1446
+ fingerprint: string;
1447
+ /** ISO 8601 timestamp when the seal was created */
1448
+ timestamp: string;
1449
+ /** Team member slug who created the seal */
1450
+ sealedBy: string;
1451
+ /** Base64-encoded Ed25519 signature of gateId:fingerprint:timestamp */
1452
+ signature: string;
1453
+ }
1454
+
1455
+ /**
1456
+ * The seals file structure stored at .attest-it/seals.json.
1457
+ * @public
1458
+ */
1459
+ export declare interface SealsFile {
1460
+ /** Schema version for forward compatibility */
1461
+ version: 1;
1462
+ /** Map of gate slugs to their seals */
1463
+ seals: Record<string, Seal>;
1464
+ }
1465
+
1466
+ /**
1467
+ * Result of verifying a single gate's seal.
1468
+ * @public
1469
+ */
1470
+ export declare interface SealVerificationResult {
1471
+ /** Gate identifier */
1472
+ gateId: string;
1473
+ /** Verification state */
1474
+ state: VerificationState;
1475
+ /** The seal, if one exists */
1476
+ seal?: Seal;
1477
+ /** Human-readable message explaining the state */
1478
+ message?: string;
1479
+ }
1480
+
1481
+ /**
1482
+ * Set a custom home directory for attest-it configuration.
1483
+ * This is useful for testing or running with isolated state.
1484
+ *
1485
+ * @param dir - The directory to use, or null to reset to default
1486
+ * @public
1487
+ */
1488
+ export declare function setAttestItHomeDir(dir: null | string): void;
1489
+
486
1490
  /**
487
1491
  * Set restrictive permissions on a private key file.
488
1492
  * @param keyPath - Path to the private key
@@ -515,32 +1519,65 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
515
1519
  constructor(filePath: string);
516
1520
  }
517
1521
 
1522
+ /**
1523
+ * Result of seal signature verification.
1524
+ * @public
1525
+ */
1526
+ export declare interface SignatureVerificationResult {
1527
+ /** Whether the seal signature is valid */
1528
+ valid: boolean;
1529
+ /** Error message if verification failed */
1530
+ error?: string;
1531
+ }
1532
+
1533
+ /**
1534
+ * Sign data with an Ed25519 private key.
1535
+ *
1536
+ * @param data - Data to sign (Buffer or UTF-8 string)
1537
+ * @param privateKeyPem - PEM-encoded private key
1538
+ * @returns Base64-encoded signature
1539
+ * @throws Error if signing fails
1540
+ * @public
1541
+ */
1542
+ export declare function signEd25519(data: Buffer | string, privateKeyPem: string): string;
1543
+
518
1544
  /**
519
1545
  * Options for signing data.
520
1546
  * @public
521
1547
  */
522
1548
  export declare interface SignOptions {
523
- /** Path to the private key file */
524
- privateKeyPath: string;
1549
+ /** Path to the private key file (legacy) */
1550
+ privateKeyPath?: string;
1551
+ /** Key provider to use for retrieving the private key */
1552
+ keyProvider?: KeyProvider;
1553
+ /** Key reference for the provider */
1554
+ keyRef?: string;
525
1555
  /** Data to sign (string or Buffer) */
526
1556
  data: Buffer | string;
527
1557
  }
528
1558
 
529
1559
  /**
530
1560
  * Suite definition from the configuration file.
1561
+ * Suites are CLI-layer extensions of gates with command execution capabilities.
531
1562
  * @public
532
1563
  */
533
1564
  export declare interface SuiteConfig {
1565
+ /** Reference to a gate (if present, inherits gate configuration) */
1566
+ gate?: string;
534
1567
  /** Human-readable description of what this suite tests */
535
1568
  description?: string;
536
- /** Glob patterns for npm packages to include in fingerprint */
537
- packages: string[];
1569
+ /** Glob patterns for npm packages to include in fingerprint (legacy/backward compatibility) */
1570
+ packages?: string[];
538
1571
  /** Additional file patterns to include in fingerprint */
539
1572
  files?: string[];
540
1573
  /** Patterns to ignore when computing fingerprint */
541
1574
  ignore?: string[];
542
1575
  /** Command to execute for this suite (overrides defaultCommand) */
543
1576
  command?: string;
1577
+ /** Timeout for command execution (duration string) */
1578
+ timeout?: string;
1579
+ /** Whether the command is interactive */
1580
+ interactive?: boolean;
544
1581
  /** Other suite names that, when changed, invalidate this suite's attestation */
545
1582
  invalidates?: string[];
546
1583
  /** Array of suite names this suite depends on */
@@ -568,6 +1605,21 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
568
1605
  message?: string;
569
1606
  }
570
1607
 
1608
+ /**
1609
+ * Team member configuration.
1610
+ * @public
1611
+ */
1612
+ export declare interface TeamMember {
1613
+ /** Display name for the team member */
1614
+ name: string;
1615
+ /** Email address (optional) */
1616
+ email?: string | undefined;
1617
+ /** GitHub username (optional) */
1618
+ github?: string | undefined;
1619
+ /** Base64-encoded Ed25519 public key */
1620
+ publicKey: string;
1621
+ }
1622
+
571
1623
  /**
572
1624
  * Convert Zod-validated Config to AttestItConfig by removing undefined values.
573
1625
  *
@@ -596,6 +1648,12 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
596
1648
  */
597
1649
  export declare function upsertAttestation(attestations: Attestation[], newAttestation: Attestation): Attestation[];
598
1650
 
1651
+ /**
1652
+ * Verification state for a gate's seal.
1653
+ * @public
1654
+ */
1655
+ export declare type VerificationState = 'FINGERPRINT_MISMATCH' | 'INVALID_SIGNATURE' | 'MISSING' | 'STALE' | 'UNKNOWN_SIGNER' | 'VALID';
1656
+
599
1657
  /**
600
1658
  * Verification status codes for suite attestations.
601
1659
  * @public
@@ -615,6 +1673,17 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
615
1673
  */
616
1674
  export declare function verify(options: CryptoVerifyOptions): Promise<boolean>;
617
1675
 
1676
+ /**
1677
+ * Verify all gates' seals.
1678
+ *
1679
+ * @param config - The attest-it configuration
1680
+ * @param seals - The seals file containing all seals
1681
+ * @param fingerprints - Map of gate IDs to their current fingerprints
1682
+ * @returns Array of verification results for all gates
1683
+ * @public
1684
+ */
1685
+ export declare function verifyAllSeals(config: AttestItConfig, seals: SealsFile, fingerprints: Record<string, string>): SealVerificationResult[];
1686
+
618
1687
  /**
619
1688
  * Verify all attestations against current code state.
620
1689
  *
@@ -634,6 +1703,30 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
634
1703
  */
635
1704
  export declare function verifyAttestations(options: VerifyOptions): Promise<VerifyResult>;
636
1705
 
1706
+ /**
1707
+ * Verify an Ed25519 signature.
1708
+ *
1709
+ * @param data - Original data that was signed
1710
+ * @param signature - Base64-encoded signature to verify
1711
+ * @param publicKeyBase64 - Base64-encoded public key (raw 32 bytes)
1712
+ * @returns true if signature is valid, false otherwise
1713
+ * @throws Error if verification fails (not just invalid signature)
1714
+ * @public
1715
+ */
1716
+ export declare function verifyEd25519(data: Buffer | string, signature: string, publicKeyBase64: string): boolean;
1717
+
1718
+ /**
1719
+ * Verify a single gate's seal.
1720
+ *
1721
+ * @param config - The attest-it configuration
1722
+ * @param gateId - Gate identifier to verify
1723
+ * @param seals - The seals file containing all seals
1724
+ * @param currentFingerprint - Current computed fingerprint for the gate
1725
+ * @returns Verification result for the gate
1726
+ * @public
1727
+ */
1728
+ export declare function verifyGateSeal(config: AttestItConfig, gateId: string, seals: SealsFile, currentFingerprint: string): SealVerificationResult;
1729
+
637
1730
  /**
638
1731
  * Options for verifying attestations.
639
1732
  * @public
@@ -660,6 +1753,16 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
660
1753
  errors: string[];
661
1754
  }
662
1755
 
1756
+ /**
1757
+ * Verify a seal's signature against the team member's public key.
1758
+ *
1759
+ * @param seal - The seal to verify
1760
+ * @param config - The attest-it configuration containing team members
1761
+ * @returns Verification result with success status and optional error message
1762
+ * @public
1763
+ */
1764
+ export declare function verifySeal(seal: Seal, config: AttestItConfig): SignatureVerificationResult;
1765
+
663
1766
  /**
664
1767
  * Package version
665
1768
  * @public
@@ -694,6 +1797,26 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
694
1797
  */
695
1798
  export declare function writeAttestationsSync(filePath: string, attestations: Attestation[], signature: string): void;
696
1799
 
1800
+ /**
1801
+ * Write seals to the seals.json file (async).
1802
+ *
1803
+ * @param dir - Directory containing .attest-it/seals.json
1804
+ * @param sealsFile - The seals file to write
1805
+ * @throws Error if file cannot be written
1806
+ * @public
1807
+ */
1808
+ export declare function writeSeals(dir: string, sealsFile: SealsFile): Promise<void>;
1809
+
1810
+ /**
1811
+ * Write seals to the seals.json file (sync).
1812
+ *
1813
+ * @param dir - Directory containing .attest-it/seals.json
1814
+ * @param sealsFile - The seals file to write
1815
+ * @throws Error if file cannot be written
1816
+ * @public
1817
+ */
1818
+ export declare function writeSealsSync(dir: string, sealsFile: SealsFile): void;
1819
+
697
1820
  /**
698
1821
  * Write attestations with a cryptographic signature.
699
1822
  *
@@ -715,8 +1838,12 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
715
1838
  filePath: string;
716
1839
  /** Array of attestations to write */
717
1840
  attestations: Attestation[];
718
- /** Path to the private key for signing */
719
- privateKeyPath: string;
1841
+ /** Path to the private key for signing (legacy) */
1842
+ privateKeyPath?: string;
1843
+ /** Key provider for signing */
1844
+ keyProvider?: KeyProvider;
1845
+ /** Key reference for the provider */
1846
+ keyRef?: string;
720
1847
  }
721
1848
 
722
1849
  export { }