@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.
- package/README.md +126 -0
- package/dist/chunk-UWYR7JNE.js +212 -0
- package/dist/chunk-UWYR7JNE.js.map +1 -0
- package/dist/core-alpha.d.ts +711 -0
- package/dist/core-beta.d.ts +711 -0
- package/dist/core-public.d.ts +711 -0
- package/dist/core-unstripped.d.ts +711 -0
- package/dist/crypto-ITLMIMRJ.js +3 -0
- package/dist/crypto-ITLMIMRJ.js.map +1 -0
- package/dist/index.cjs +915 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +691 -0
- package/dist/index.d.ts +691 -0
- package/dist/index.js +629 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
|
@@ -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 { }
|