@attest-it/core 0.0.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.
@@ -0,0 +1,711 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Supported signature algorithms.
5
+ * @public
6
+ */
7
+ export declare type Algorithm = 'ed25519' | 'rsa';
8
+
9
+ /**
10
+ * A single attestation entry.
11
+ * @public
12
+ */
13
+ export declare interface Attestation {
14
+ /** Test suite name (e.g., "unit", "integration") */
15
+ suite: string;
16
+ /** SHA-256 fingerprint of test files in format "sha256:<hex>" */
17
+ fingerprint: string;
18
+ /** ISO 8601 timestamp when attestation was created */
19
+ attestedAt: string;
20
+ /** User who created the attestation */
21
+ attestedBy: string;
22
+ /** Command that was executed */
23
+ command: string;
24
+ /** Exit code (must be 0 for valid attestation) */
25
+ exitCode: 0;
26
+ }
27
+
28
+ /**
29
+ * Attestations file structure.
30
+ * @public
31
+ */
32
+ export declare interface AttestationsFile {
33
+ /** Schema version for forward compatibility */
34
+ schemaVersion: '1';
35
+ /** Array of attestations */
36
+ attestations: Attestation[];
37
+ /** Base64-encoded signature over canonical attestations array */
38
+ signature: string;
39
+ }
40
+
41
+ /**
42
+ * Full configuration file structure.
43
+ * @public
44
+ */
45
+ export declare interface AttestItConfig {
46
+ /** Configuration schema version */
47
+ version: 1;
48
+ /** Global settings for attestation behavior */
49
+ settings: AttestItSettings;
50
+ /** Named test suites with their configurations */
51
+ suites: Record<string, SuiteConfig>;
52
+ }
53
+
54
+ /**
55
+ * Settings from the configuration file.
56
+ * @public
57
+ */
58
+ export declare interface AttestItSettings {
59
+ /** Maximum age in days before an attestation expires */
60
+ maxAgeDays: number;
61
+ /** Path to the public key file used for signature verification */
62
+ publicKeyPath: string;
63
+ /** Path to the attestations file */
64
+ attestationsPath: string;
65
+ /** Default command to execute for attestation (can be overridden per suite) */
66
+ defaultCommand?: string;
67
+ /** Cryptographic algorithm to use for signatures */
68
+ algorithm: 'ed25519' | 'rsa';
69
+ }
70
+
71
+ /**
72
+ * Compute canonical JSON representation for signing.
73
+ *
74
+ * Implements RFC 8785 JSON Canonicalization Scheme. The canonicalize package provides:
75
+ * 1. Keys sorted lexicographically (Unicode code point order)
76
+ * 2. No whitespace between tokens
77
+ * 3. No trailing commas
78
+ * 4. Strings escaped using \uXXXX for control characters
79
+ * 5. Numbers: no leading zeros, no +, use lowercase 'e' for exponent
80
+ * 6. UTF-8 encoding
81
+ *
82
+ * @param attestations - Array of attestations to canonicalize
83
+ * @returns Canonical JSON string representation
84
+ * @throws Error if canonicalization fails
85
+ * @public
86
+ */
87
+ export declare function canonicalizeAttestations(attestations: Attestation[]): string;
88
+
89
+ /**
90
+ * Check if OpenSSL is available and get version info.
91
+ * @returns OpenSSL version string
92
+ * @throws Error if OpenSSL is not available
93
+ * @public
94
+ */
95
+ export declare function checkOpenSSL(): Promise<string>;
96
+
97
+ /**
98
+ * Compute a deterministic fingerprint for a set of packages (async).
99
+ *
100
+ * Algorithm:
101
+ * 1. List all files in packages (respecting ignore globs)
102
+ * 2. Sort files lexicographically by relative path
103
+ * 3. For each file: compute SHA256(relativePath + "\0" + content)
104
+ * 4. Concatenate all file hashes in sorted order
105
+ * 5. Compute final SHA256 of concatenated hashes
106
+ * 6. Return "sha256:" + hex(fingerprint)
107
+ *
108
+ * @param options - Configuration for fingerprint computation
109
+ * @returns Result containing the fingerprint hash and list of files processed
110
+ * @throws Error if packages array is empty or if package paths don't exist
111
+ * @public
112
+ */
113
+ export declare function computeFingerprint(options: FingerprintOptions): Promise<FingerprintResult>;
114
+
115
+ /**
116
+ * Compute a deterministic fingerprint for a set of packages (sync).
117
+ *
118
+ * @param options - Configuration for fingerprint computation
119
+ * @returns Result containing the fingerprint hash and list of files processed
120
+ * @throws Error if packages array is empty or if package paths don't exist
121
+ * @public
122
+ * @see {@link computeFingerprint} for the async version
123
+ */
124
+ export declare function computeFingerprintSync(options: FingerprintOptions): FingerprintResult;
125
+
126
+ /**
127
+ * Type inference from Zod schema (should match AttestItConfig).
128
+ * This is the same as AttestItConfig but with defaults applied.
129
+ * @public
130
+ */
131
+ export declare type Config = z.infer<typeof configSchema>;
132
+
133
+ /**
134
+ * Error thrown when configuration file cannot be found.
135
+ * @public
136
+ */
137
+ export declare class ConfigNotFoundError extends Error {
138
+ constructor(message: string);
139
+ }
140
+
141
+ /**
142
+ * Zod schema for the full configuration file.
143
+ */
144
+ declare const configSchema: z.ZodObject<{
145
+ settings: z.ZodDefault<z.ZodObject<{
146
+ algorithm: z.ZodDefault<z.ZodEnum<["ed25519", "rsa"]>>;
147
+ attestationsPath: z.ZodDefault<z.ZodString>;
148
+ defaultCommand: z.ZodOptional<z.ZodString>;
149
+ maxAgeDays: z.ZodDefault<z.ZodNumber>;
150
+ publicKeyPath: z.ZodDefault<z.ZodString>;
151
+ }, "strict", z.ZodTypeAny, {
152
+ algorithm: "ed25519" | "rsa";
153
+ attestationsPath: string;
154
+ defaultCommand?: string | undefined;
155
+ maxAgeDays: number;
156
+ publicKeyPath: string;
157
+ }, {
158
+ algorithm?: "ed25519" | "rsa" | undefined;
159
+ attestationsPath?: string | undefined;
160
+ defaultCommand?: string | undefined;
161
+ maxAgeDays?: number | undefined;
162
+ publicKeyPath?: string | undefined;
163
+ }>>;
164
+ suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
165
+ command: z.ZodOptional<z.ZodString>;
166
+ description: z.ZodOptional<z.ZodString>;
167
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
168
+ ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
169
+ invalidates: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
170
+ packages: z.ZodArray<z.ZodString, "many">;
171
+ }, "strict", z.ZodTypeAny, {
172
+ command?: string | undefined;
173
+ description?: string | undefined;
174
+ files?: string[] | undefined;
175
+ ignore?: string[] | undefined;
176
+ invalidates?: string[] | undefined;
177
+ packages: string[];
178
+ }, {
179
+ command?: string | undefined;
180
+ description?: string | undefined;
181
+ files?: string[] | undefined;
182
+ ignore?: string[] | undefined;
183
+ invalidates?: string[] | undefined;
184
+ packages: string[];
185
+ }>>, Record<string, {
186
+ command?: string | undefined;
187
+ description?: string | undefined;
188
+ files?: string[] | undefined;
189
+ ignore?: string[] | undefined;
190
+ invalidates?: string[] | undefined;
191
+ packages: string[];
192
+ }>, Record<string, {
193
+ command?: string | undefined;
194
+ description?: string | undefined;
195
+ files?: string[] | undefined;
196
+ ignore?: string[] | undefined;
197
+ invalidates?: string[] | undefined;
198
+ packages: string[];
199
+ }>>;
200
+ version: z.ZodLiteral<1>;
201
+ }, "strict", z.ZodTypeAny, {
202
+ settings: {
203
+ algorithm: "ed25519" | "rsa";
204
+ attestationsPath: string;
205
+ defaultCommand?: string | undefined;
206
+ maxAgeDays: number;
207
+ publicKeyPath: string;
208
+ };
209
+ suites: Record<string, {
210
+ command?: string | undefined;
211
+ description?: string | undefined;
212
+ files?: string[] | undefined;
213
+ ignore?: string[] | undefined;
214
+ invalidates?: string[] | undefined;
215
+ packages: string[];
216
+ }>;
217
+ version: 1;
218
+ }, {
219
+ settings?: {
220
+ algorithm?: "ed25519" | "rsa" | undefined;
221
+ attestationsPath?: string | undefined;
222
+ defaultCommand?: string | undefined;
223
+ maxAgeDays?: number | undefined;
224
+ publicKeyPath?: string | undefined;
225
+ } | undefined;
226
+ suites: Record<string, {
227
+ command?: string | undefined;
228
+ description?: string | undefined;
229
+ files?: string[] | undefined;
230
+ ignore?: string[] | undefined;
231
+ invalidates?: string[] | undefined;
232
+ packages: string[];
233
+ }>;
234
+ version: 1;
235
+ }>;
236
+
237
+ /**
238
+ * Error thrown when configuration is invalid.
239
+ * @public
240
+ */
241
+ export declare class ConfigValidationError extends Error {
242
+ readonly issues: z.ZodIssue[];
243
+ constructor(message: string, issues: z.ZodIssue[]);
244
+ }
245
+
246
+ /**
247
+ * Create a new attestation entry.
248
+ *
249
+ * @param params - Parameters for creating the attestation
250
+ * @param params.suite - Name of the test suite
251
+ * @param params.fingerprint - Fingerprint of the packages in sha256 format
252
+ * @param params.command - Command that was executed
253
+ * @param params.attestedBy - Optional username (defaults to current OS user)
254
+ * @returns Validated attestation object
255
+ * @throws Error if attestation validation fails
256
+ * @public
257
+ */
258
+ export declare function createAttestation(params: {
259
+ attestedBy?: string;
260
+ command: string;
261
+ fingerprint: string;
262
+ suite: string;
263
+ }): Attestation;
264
+
265
+ /**
266
+ * Options for verifying signatures.
267
+ * @public
268
+ */
269
+ export declare interface CryptoVerifyOptions {
270
+ /** Path to the public key file */
271
+ publicKeyPath: string;
272
+ /** Original data that was signed */
273
+ data: Buffer | string;
274
+ /** Base64-encoded signature to verify */
275
+ signature: string;
276
+ }
277
+
278
+ /**
279
+ * Find an attestation for a specific suite.
280
+ *
281
+ * @param attestations - Attestations file containing all attestations
282
+ * @param suite - Name of the suite to find
283
+ * @returns The attestation if found, undefined otherwise
284
+ * @public
285
+ */
286
+ export declare function findAttestation(attestations: AttestationsFile, suite: string): Attestation | undefined;
287
+
288
+ /**
289
+ * Find the configuration file in default locations.
290
+ *
291
+ * Searches in this order:
292
+ * 1. .attest-it/config.yaml
293
+ * 2. .attest-it/config.yml
294
+ * 3. .attest-it/config.json
295
+ *
296
+ * @param startDir - Directory to start searching from (defaults to cwd)
297
+ * @returns Absolute path to the config file, or null if not found
298
+ * @public
299
+ */
300
+ export declare function findConfigPath(startDir?: string): null | string;
301
+
302
+ /**
303
+ * Options for computing a package fingerprint.
304
+ * @public
305
+ */
306
+ export declare interface FingerprintOptions {
307
+ /** Package directories to include */
308
+ packages: string[];
309
+ /** Glob patterns to exclude from fingerprint */
310
+ ignore?: string[];
311
+ /** Base directory for resolving paths */
312
+ baseDir?: string;
313
+ }
314
+
315
+ /**
316
+ * Result of computing a package fingerprint.
317
+ * @public
318
+ */
319
+ export declare interface FingerprintResult {
320
+ /** The fingerprint in "sha256:..." format */
321
+ fingerprint: string;
322
+ /** List of files included in fingerprint calculation */
323
+ files: string[];
324
+ /** Number of files processed */
325
+ fileCount: number;
326
+ }
327
+
328
+ /**
329
+ * Generate a new keypair using OpenSSL.
330
+ * @param options - Generation options
331
+ * @returns Paths to generated keys
332
+ * @throws Error if OpenSSL fails or keys exist without force
333
+ * @public
334
+ */
335
+ export declare function generateKeyPair(options?: KeygenOptions): Promise<KeyPaths>;
336
+
337
+ /**
338
+ * Get the default private key path based on OS.
339
+ * - macOS/Linux: ~/.config/attest-it/private.pem
340
+ * - Windows: %APPDATA%\attest-it\private.pem
341
+ * @public
342
+ */
343
+ export declare function getDefaultPrivateKeyPath(): string;
344
+
345
+ /**
346
+ * Get the default public key path (in repo).
347
+ * @public
348
+ */
349
+ export declare function getDefaultPublicKeyPath(): string;
350
+
351
+ /**
352
+ * Options for key generation.
353
+ * @public
354
+ */
355
+ export declare interface KeygenOptions {
356
+ /** Algorithm to use (default: ed25519) */
357
+ algorithm?: Algorithm;
358
+ /** Path for private key (default: OS-specific config dir) */
359
+ privatePath?: string;
360
+ /** Path for public key (default: repo root) */
361
+ publicPath?: string;
362
+ /** Overwrite existing keys (default: false) */
363
+ force?: boolean;
364
+ }
365
+
366
+ /**
367
+ * Paths to a generated keypair.
368
+ * @public
369
+ */
370
+ export declare interface KeyPaths {
371
+ /** Path to the private key file */
372
+ privatePath: string;
373
+ /** Path to the public key file */
374
+ publicPath: string;
375
+ }
376
+
377
+ /**
378
+ * List files in packages, respecting ignore patterns (async).
379
+ *
380
+ * @param packages - Array of package directory paths
381
+ * @param ignore - Optional glob patterns to exclude
382
+ * @param baseDir - Base directory for resolving paths (defaults to cwd)
383
+ * @returns Array of relative file paths
384
+ * @public
385
+ */
386
+ export declare function listPackageFiles(packages: string[], ignore?: string[], baseDir?: string): Promise<string[]>;
387
+
388
+ /**
389
+ * Load and validate configuration from a file (async).
390
+ *
391
+ * @param configPath - Optional path to config file. If not provided, searches default locations.
392
+ * @returns Validated configuration object
393
+ * @throws {@link ConfigNotFoundError} If config file cannot be found
394
+ * @throws {@link ConfigValidationError} If validation fails
395
+ * @public
396
+ */
397
+ export declare function loadConfig(configPath?: string): Promise<Config>;
398
+
399
+ /**
400
+ * Load and validate configuration from a file (sync).
401
+ *
402
+ * @param configPath - Optional path to config file. If not provided, searches default locations.
403
+ * @returns Validated configuration object
404
+ * @throws {@link ConfigNotFoundError} If config file cannot be found
405
+ * @throws {@link ConfigValidationError} If validation fails
406
+ * @public
407
+ */
408
+ export declare function loadConfigSync(configPath?: string): Config;
409
+
410
+ /**
411
+ * Read attestations and verify the signature.
412
+ *
413
+ * This function reads the attestations file, canonicalizes the attestations,
414
+ * and verifies the signature using the public key. It throws an error if the
415
+ * file doesn't exist or if signature verification fails.
416
+ *
417
+ * @param options - Options for reading and verifying attestations
418
+ * @returns The attestations file if signature is valid
419
+ * @throws Error if attestations file not found
420
+ * @throws SignatureInvalidError if signature verification fails
421
+ * @public
422
+ */
423
+ export declare function readAndVerifyAttestations(options: ReadSignedAttestationsOptions): Promise<AttestationsFile>;
424
+
425
+ /**
426
+ * Attestation file I/O module with JSON canonicalization.
427
+ */
428
+
429
+ /**
430
+ * Read attestations file from disk (async).
431
+ *
432
+ * @param filePath - Absolute path to the attestations JSON file
433
+ * @returns Parsed attestations file, or null if the file doesn't exist
434
+ * @throws Error on parse or validation errors
435
+ * @public
436
+ */
437
+ export declare function readAttestations(filePath: string): Promise<AttestationsFile | null>;
438
+
439
+ /**
440
+ * Read attestations file from disk (sync).
441
+ *
442
+ * @param filePath - Absolute path to the attestations JSON file
443
+ * @returns Parsed attestations file, or null if the file doesn't exist
444
+ * @throws Error on parse or validation errors
445
+ * @public
446
+ */
447
+ export declare function readAttestationsSync(filePath: string): AttestationsFile | null;
448
+
449
+ /**
450
+ * Options for reading and verifying signed attestations.
451
+ * @public
452
+ */
453
+ export declare interface ReadSignedAttestationsOptions {
454
+ /** Path to read the attestations file from */
455
+ filePath: string;
456
+ /** Path to the public key for verification */
457
+ publicKeyPath: string;
458
+ }
459
+
460
+ /**
461
+ * Remove attestations for a suite.
462
+ *
463
+ * This is an immutable operation that returns a new array.
464
+ *
465
+ * @param attestations - Current array of attestations
466
+ * @param suite - Name of the suite to remove
467
+ * @returns New attestations array without the specified suite
468
+ * @public
469
+ */
470
+ export declare function removeAttestation(attestations: Attestation[], suite: string): Attestation[];
471
+
472
+ /**
473
+ * Resolve relative paths in the configuration against the repository root.
474
+ *
475
+ * This converts relative paths in settings.publicKeyPath and settings.attestationsPath
476
+ * to absolute paths relative to the repository root.
477
+ *
478
+ * @param config - The configuration object
479
+ * @param repoRoot - Absolute path to the repository root
480
+ * @returns Configuration with resolved absolute paths
481
+ * @public
482
+ */
483
+ export declare function resolveConfigPaths(config: Config, repoRoot: string): Config;
484
+
485
+ /**
486
+ * Set restrictive permissions on a private key file.
487
+ * @param keyPath - Path to the private key
488
+ * @public
489
+ */
490
+ export declare function setKeyPermissions(keyPath: string): Promise<void>;
491
+
492
+ /**
493
+ * Sign data using a private key.
494
+ * @param options - Signing options
495
+ * @returns Base64-encoded signature
496
+ * @throws Error if signing fails
497
+ * @public
498
+ */
499
+ export declare function sign(options: SignOptions): Promise<string>;
500
+
501
+ /**
502
+ * Error thrown when signature verification fails.
503
+ * @public
504
+ */
505
+ export declare class SignatureInvalidError extends Error {
506
+ /**
507
+ * Create a new SignatureInvalidError.
508
+ * @param filePath - Path to the file that failed verification
509
+ */
510
+ constructor(filePath: string);
511
+ }
512
+
513
+ /**
514
+ * Options for signing data.
515
+ * @public
516
+ */
517
+ export declare interface SignOptions {
518
+ /** Path to the private key file */
519
+ privateKeyPath: string;
520
+ /** Data to sign (string or Buffer) */
521
+ data: Buffer | string;
522
+ }
523
+
524
+ /**
525
+ * Suite definition from the configuration file.
526
+ * @public
527
+ */
528
+ export declare interface SuiteConfig {
529
+ /** Human-readable description of what this suite tests */
530
+ description?: string;
531
+ /** Glob patterns for npm packages to include in fingerprint */
532
+ packages: string[];
533
+ /** Additional file patterns to include in fingerprint */
534
+ files?: string[];
535
+ /** Patterns to ignore when computing fingerprint */
536
+ ignore?: string[];
537
+ /** Command to execute for this suite (overrides defaultCommand) */
538
+ command?: string;
539
+ /** Other suite names that, when changed, invalidate this suite's attestation */
540
+ invalidates?: string[];
541
+ }
542
+
543
+ /**
544
+ * Result of verifying a single suite's attestation.
545
+ * @public
546
+ */
547
+ export declare interface SuiteVerificationResult {
548
+ /** Name of the suite being verified */
549
+ suite: string;
550
+ /** Current verification status */
551
+ status: VerificationStatus;
552
+ /** Current computed fingerprint for the suite */
553
+ fingerprint: string;
554
+ /** The attestation record, if one exists */
555
+ attestation?: Attestation;
556
+ /** List of files that changed (if status is FINGERPRINT_CHANGED) */
557
+ changedFiles?: string[];
558
+ /** Age of the attestation in days (if expired) */
559
+ age?: number;
560
+ /** Human-readable message explaining the status */
561
+ message?: string;
562
+ }
563
+
564
+ /**
565
+ * Convert Zod-validated Config to AttestItConfig by removing undefined values.
566
+ *
567
+ * The Config type (from Zod) has optional fields as `T | undefined`,
568
+ * while AttestItConfig has optional fields as `T?` (can be absent, not undefined).
569
+ *
570
+ * This adapter removes any undefined values to match the AttestItConfig interface
571
+ * that the core functions expect.
572
+ *
573
+ * @param config - The Zod-validated configuration from loadConfig()
574
+ * @returns Configuration compatible with AttestItConfig
575
+ * @public
576
+ */
577
+ export declare function toAttestItConfig(config: Config): AttestItConfig;
578
+
579
+ /**
580
+ * Add or update an attestation for a suite.
581
+ *
582
+ * This is an immutable operation that returns a new array.
583
+ *
584
+ * @param attestations - Current array of attestations
585
+ * @param newAttestation - Attestation to add or update
586
+ * @returns New attestations array with the upserted attestation
587
+ * @throws Error if the new attestation fails validation
588
+ * @public
589
+ */
590
+ export declare function upsertAttestation(attestations: Attestation[], newAttestation: Attestation): Attestation[];
591
+
592
+ /**
593
+ * Verification status codes for suite attestations.
594
+ * @public
595
+ */
596
+ export declare type VerificationStatus = 'EXPIRED' | 'FINGERPRINT_CHANGED' | 'INVALIDATED_BY_PARENT' | 'NEEDS_ATTESTATION' | 'SIGNATURE_INVALID' | 'VALID';
597
+
598
+ /**
599
+ * Verify a signature using a public key.
600
+ * @param options - Verification options
601
+ * @returns true if signature is valid
602
+ * @throws Error if verification fails (not just invalid signature)
603
+ * @public
604
+ */
605
+ export declare function verify(options: CryptoVerifyOptions): Promise<boolean>;
606
+
607
+ /**
608
+ * Verify all attestations against current code state.
609
+ *
610
+ * Verification algorithm:
611
+ * 1. Load and verify attestations file signature
612
+ * 2. For each suite in config:
613
+ * a. Compute current fingerprint
614
+ * b. Find matching attestation
615
+ * c. Compare fingerprints
616
+ * d. Check age
617
+ * 3. Check invalidation chains
618
+ * 4. Return aggregated results
619
+ *
620
+ * @param options - Verification options
621
+ * @returns Verification result with status for each suite
622
+ * @public
623
+ */
624
+ export declare function verifyAttestations(options: VerifyOptions): Promise<VerifyResult>;
625
+
626
+ /**
627
+ * Options for verifying attestations.
628
+ * @public
629
+ */
630
+ export declare interface VerifyOptions {
631
+ /** Configuration object */
632
+ config: AttestItConfig;
633
+ /** Repository root directory (defaults to process.cwd()) */
634
+ repoRoot?: string;
635
+ }
636
+
637
+ /**
638
+ * Result of verifying all attestations.
639
+ * @public
640
+ */
641
+ export declare interface VerifyResult {
642
+ /** Overall success - true if all attestations are valid */
643
+ success: boolean;
644
+ /** Whether the attestations file signature is valid */
645
+ signatureValid: boolean;
646
+ /** Verification results for each suite */
647
+ suites: SuiteVerificationResult[];
648
+ /** Error messages encountered during verification */
649
+ errors: string[];
650
+ }
651
+
652
+ /**
653
+ * Package version
654
+ * @public
655
+ */
656
+ export declare const version = "0.0.0";
657
+
658
+ /**
659
+ * Write attestations file to disk (async).
660
+ *
661
+ * Creates parent directories if needed. The signature should be computed
662
+ * separately and passed in.
663
+ *
664
+ * @param filePath - Absolute path to write the attestations file
665
+ * @param attestations - Array of attestation entries
666
+ * @param signature - Cryptographic signature of the attestations
667
+ * @throws Error on validation or write errors
668
+ * @public
669
+ */
670
+ export declare function writeAttestations(filePath: string, attestations: Attestation[], signature: string): Promise<void>;
671
+
672
+ /**
673
+ * Write attestations file to disk (sync).
674
+ *
675
+ * Creates parent directories if needed. The signature should be computed
676
+ * separately and passed in.
677
+ *
678
+ * @param filePath - Absolute path to write the attestations file
679
+ * @param attestations - Array of attestation entries
680
+ * @param signature - Cryptographic signature of the attestations
681
+ * @throws Error on validation or write errors
682
+ * @public
683
+ */
684
+ export declare function writeAttestationsSync(filePath: string, attestations: Attestation[], signature: string): void;
685
+
686
+ /**
687
+ * Write attestations with a cryptographic signature.
688
+ *
689
+ * This function canonicalizes the attestations, signs them with the private key,
690
+ * and writes the attestations file with the signature.
691
+ *
692
+ * @param options - Options for writing signed attestations
693
+ * @throws Error if signing or writing fails
694
+ * @public
695
+ */
696
+ export declare function writeSignedAttestations(options: WriteSignedAttestationsOptions): Promise<void>;
697
+
698
+ /**
699
+ * Options for writing signed attestations.
700
+ * @public
701
+ */
702
+ export declare interface WriteSignedAttestationsOptions {
703
+ /** Path to write the attestations file */
704
+ filePath: string;
705
+ /** Array of attestations to write */
706
+ attestations: Attestation[];
707
+ /** Path to the private key for signing */
708
+ privateKeyPath: string;
709
+ }
710
+
711
+ export { }