@attest-it/core 0.0.0 → 0.2.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.
@@ -1,11 +1,5 @@
1
1
  import { z } from 'zod';
2
2
 
3
- /**
4
- * Supported signature algorithms.
5
- * @public
6
- */
7
- export declare type Algorithm = 'ed25519' | 'rsa';
8
-
9
3
  /**
10
4
  * A single attestation entry.
11
5
  * @public
@@ -49,6 +43,8 @@ export declare interface AttestItConfig {
49
43
  settings: AttestItSettings;
50
44
  /** Named test suites with their configurations */
51
45
  suites: Record<string, SuiteConfig>;
46
+ /** Named groups of suites */
47
+ groups?: Record<string, string[]>;
52
48
  }
53
49
 
54
50
  /**
@@ -64,8 +60,6 @@ export declare interface AttestItSettings {
64
60
  attestationsPath: string;
65
61
  /** Default command to execute for attestation (can be overridden per suite) */
66
62
  defaultCommand?: string;
67
- /** Cryptographic algorithm to use for signatures */
68
- algorithm: 'ed25519' | 'rsa';
69
63
  }
70
64
 
71
65
  /**
@@ -142,27 +136,26 @@ export declare class ConfigNotFoundError extends Error {
142
136
  * Zod schema for the full configuration file.
143
137
  */
144
138
  declare const configSchema: z.ZodObject<{
139
+ groups: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
145
140
  settings: z.ZodDefault<z.ZodObject<{
146
- algorithm: z.ZodDefault<z.ZodEnum<["ed25519", "rsa"]>>;
147
141
  attestationsPath: z.ZodDefault<z.ZodString>;
148
142
  defaultCommand: z.ZodOptional<z.ZodString>;
149
143
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
150
144
  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
- }>>;
145
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
146
+ attestationsPath: z.ZodDefault<z.ZodString>;
147
+ defaultCommand: z.ZodOptional<z.ZodString>;
148
+ maxAgeDays: z.ZodDefault<z.ZodNumber>;
149
+ publicKeyPath: z.ZodDefault<z.ZodString>;
150
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
151
+ attestationsPath: z.ZodDefault<z.ZodString>;
152
+ defaultCommand: z.ZodOptional<z.ZodString>;
153
+ maxAgeDays: z.ZodDefault<z.ZodNumber>;
154
+ publicKeyPath: z.ZodDefault<z.ZodString>;
155
+ }, z.ZodTypeAny, "passthrough">>>;
164
156
  suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
165
157
  command: z.ZodOptional<z.ZodString>;
158
+ depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
166
159
  description: z.ZodOptional<z.ZodString>;
167
160
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
168
161
  ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
@@ -170,6 +163,7 @@ declare const configSchema: z.ZodObject<{
170
163
  packages: z.ZodArray<z.ZodString, "many">;
171
164
  }, "strict", z.ZodTypeAny, {
172
165
  command?: string | undefined;
166
+ depends_on?: string[] | undefined;
173
167
  description?: string | undefined;
174
168
  files?: string[] | undefined;
175
169
  ignore?: string[] | undefined;
@@ -177,6 +171,7 @@ declare const configSchema: z.ZodObject<{
177
171
  packages: string[];
178
172
  }, {
179
173
  command?: string | undefined;
174
+ depends_on?: string[] | undefined;
180
175
  description?: string | undefined;
181
176
  files?: string[] | undefined;
182
177
  ignore?: string[] | undefined;
@@ -184,6 +179,7 @@ declare const configSchema: z.ZodObject<{
184
179
  packages: string[];
185
180
  }>>, Record<string, {
186
181
  command?: string | undefined;
182
+ depends_on?: string[] | undefined;
187
183
  description?: string | undefined;
188
184
  files?: string[] | undefined;
189
185
  ignore?: string[] | undefined;
@@ -191,6 +187,7 @@ declare const configSchema: z.ZodObject<{
191
187
  packages: string[];
192
188
  }>, Record<string, {
193
189
  command?: string | undefined;
190
+ depends_on?: string[] | undefined;
194
191
  description?: string | undefined;
195
192
  files?: string[] | undefined;
196
193
  ignore?: string[] | undefined;
@@ -199,15 +196,16 @@ declare const configSchema: z.ZodObject<{
199
196
  }>>;
200
197
  version: z.ZodLiteral<1>;
201
198
  }, "strict", z.ZodTypeAny, {
199
+ groups?: Record<string, string[]> | undefined;
202
200
  settings: {
203
- algorithm: "ed25519" | "rsa";
204
201
  attestationsPath: string;
205
202
  defaultCommand?: string | undefined;
206
203
  maxAgeDays: number;
207
204
  publicKeyPath: string;
208
- };
205
+ } & { [k: string]: unknown };
209
206
  suites: Record<string, {
210
207
  command?: string | undefined;
208
+ depends_on?: string[] | undefined;
211
209
  description?: string | undefined;
212
210
  files?: string[] | undefined;
213
211
  ignore?: string[] | undefined;
@@ -216,15 +214,16 @@ declare const configSchema: z.ZodObject<{
216
214
  }>;
217
215
  version: 1;
218
216
  }, {
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;
217
+ groups?: Record<string, string[]> | undefined;
218
+ settings?: undefined | z.objectInputType<{
219
+ attestationsPath: z.ZodDefault<z.ZodString>;
220
+ defaultCommand: z.ZodOptional<z.ZodString>;
221
+ maxAgeDays: z.ZodDefault<z.ZodNumber>;
222
+ publicKeyPath: z.ZodDefault<z.ZodString>;
223
+ }, z.ZodTypeAny, "passthrough">;
226
224
  suites: Record<string, {
227
225
  command?: string | undefined;
226
+ depends_on?: string[] | undefined;
228
227
  description?: string | undefined;
229
228
  files?: string[] | undefined;
230
229
  ignore?: string[] | undefined;
@@ -326,7 +325,11 @@ export declare interface FingerprintResult {
326
325
  }
327
326
 
328
327
  /**
329
- * Generate a new keypair using OpenSSL.
328
+ * Generate a new RSA-2048 keypair using OpenSSL.
329
+ *
330
+ * RSA-2048 with SHA-256 is used because it's universally supported across
331
+ * all OpenSSL and LibreSSL versions, including older macOS systems.
332
+ *
330
333
  * @param options - Generation options
331
334
  * @returns Paths to generated keys
332
335
  * @throws Error if OpenSSL fails or keys exist without force
@@ -353,8 +356,6 @@ export declare function getDefaultPublicKeyPath(): string;
353
356
  * @public
354
357
  */
355
358
  export declare interface KeygenOptions {
356
- /** Algorithm to use (default: ed25519) */
357
- algorithm?: Algorithm;
358
359
  /** Path for private key (default: OS-specific config dir) */
359
360
  privatePath?: string;
360
361
  /** Path for public key (default: repo root) */
@@ -490,7 +491,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
490
491
  export declare function setKeyPermissions(keyPath: string): Promise<void>;
491
492
 
492
493
  /**
493
- * Sign data using a private key.
494
+ * Sign data using an RSA private key with SHA-256.
495
+ *
496
+ * Uses `openssl dgst -sha256 -sign` which is universally supported across
497
+ * all OpenSSL and LibreSSL versions.
498
+ *
494
499
  * @param options - Signing options
495
500
  * @returns Base64-encoded signature
496
501
  * @throws Error if signing fails
@@ -538,6 +543,8 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
538
543
  command?: string;
539
544
  /** Other suite names that, when changed, invalidate this suite's attestation */
540
545
  invalidates?: string[];
546
+ /** Array of suite names this suite depends on */
547
+ depends_on?: string[];
541
548
  }
542
549
 
543
550
  /**
@@ -596,7 +603,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
596
603
  export declare type VerificationStatus = 'EXPIRED' | 'FINGERPRINT_CHANGED' | 'INVALIDATED_BY_PARENT' | 'NEEDS_ATTESTATION' | 'SIGNATURE_INVALID' | 'VALID';
597
604
 
598
605
  /**
599
- * Verify a signature using a public key.
606
+ * Verify a signature using an RSA public key with SHA-256.
607
+ *
608
+ * Uses `openssl dgst -sha256 -verify` which is universally supported across
609
+ * all OpenSSL and LibreSSL versions.
610
+ *
600
611
  * @param options - Verification options
601
612
  * @returns true if signature is valid
602
613
  * @throws Error if verification fails (not just invalid signature)
@@ -1,11 +1,5 @@
1
1
  import { z } from 'zod';
2
2
 
3
- /**
4
- * Supported signature algorithms.
5
- * @public
6
- */
7
- export declare type Algorithm = 'ed25519' | 'rsa';
8
-
9
3
  /**
10
4
  * A single attestation entry.
11
5
  * @public
@@ -49,6 +43,8 @@ export declare interface AttestItConfig {
49
43
  settings: AttestItSettings;
50
44
  /** Named test suites with their configurations */
51
45
  suites: Record<string, SuiteConfig>;
46
+ /** Named groups of suites */
47
+ groups?: Record<string, string[]>;
52
48
  }
53
49
 
54
50
  /**
@@ -64,8 +60,6 @@ export declare interface AttestItSettings {
64
60
  attestationsPath: string;
65
61
  /** Default command to execute for attestation (can be overridden per suite) */
66
62
  defaultCommand?: string;
67
- /** Cryptographic algorithm to use for signatures */
68
- algorithm: 'ed25519' | 'rsa';
69
63
  }
70
64
 
71
65
  /**
@@ -142,27 +136,26 @@ export declare class ConfigNotFoundError extends Error {
142
136
  * Zod schema for the full configuration file.
143
137
  */
144
138
  declare const configSchema: z.ZodObject<{
139
+ groups: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
145
140
  settings: z.ZodDefault<z.ZodObject<{
146
- algorithm: z.ZodDefault<z.ZodEnum<["ed25519", "rsa"]>>;
147
141
  attestationsPath: z.ZodDefault<z.ZodString>;
148
142
  defaultCommand: z.ZodOptional<z.ZodString>;
149
143
  maxAgeDays: z.ZodDefault<z.ZodNumber>;
150
144
  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
- }>>;
145
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
146
+ attestationsPath: z.ZodDefault<z.ZodString>;
147
+ defaultCommand: z.ZodOptional<z.ZodString>;
148
+ maxAgeDays: z.ZodDefault<z.ZodNumber>;
149
+ publicKeyPath: z.ZodDefault<z.ZodString>;
150
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
151
+ attestationsPath: z.ZodDefault<z.ZodString>;
152
+ defaultCommand: z.ZodOptional<z.ZodString>;
153
+ maxAgeDays: z.ZodDefault<z.ZodNumber>;
154
+ publicKeyPath: z.ZodDefault<z.ZodString>;
155
+ }, z.ZodTypeAny, "passthrough">>>;
164
156
  suites: z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodObject<{
165
157
  command: z.ZodOptional<z.ZodString>;
158
+ depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
166
159
  description: z.ZodOptional<z.ZodString>;
167
160
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
168
161
  ignore: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
@@ -170,6 +163,7 @@ declare const configSchema: z.ZodObject<{
170
163
  packages: z.ZodArray<z.ZodString, "many">;
171
164
  }, "strict", z.ZodTypeAny, {
172
165
  command?: string | undefined;
166
+ depends_on?: string[] | undefined;
173
167
  description?: string | undefined;
174
168
  files?: string[] | undefined;
175
169
  ignore?: string[] | undefined;
@@ -177,6 +171,7 @@ declare const configSchema: z.ZodObject<{
177
171
  packages: string[];
178
172
  }, {
179
173
  command?: string | undefined;
174
+ depends_on?: string[] | undefined;
180
175
  description?: string | undefined;
181
176
  files?: string[] | undefined;
182
177
  ignore?: string[] | undefined;
@@ -184,6 +179,7 @@ declare const configSchema: z.ZodObject<{
184
179
  packages: string[];
185
180
  }>>, Record<string, {
186
181
  command?: string | undefined;
182
+ depends_on?: string[] | undefined;
187
183
  description?: string | undefined;
188
184
  files?: string[] | undefined;
189
185
  ignore?: string[] | undefined;
@@ -191,6 +187,7 @@ declare const configSchema: z.ZodObject<{
191
187
  packages: string[];
192
188
  }>, Record<string, {
193
189
  command?: string | undefined;
190
+ depends_on?: string[] | undefined;
194
191
  description?: string | undefined;
195
192
  files?: string[] | undefined;
196
193
  ignore?: string[] | undefined;
@@ -199,15 +196,16 @@ declare const configSchema: z.ZodObject<{
199
196
  }>>;
200
197
  version: z.ZodLiteral<1>;
201
198
  }, "strict", z.ZodTypeAny, {
199
+ groups?: Record<string, string[]> | undefined;
202
200
  settings: {
203
- algorithm: "ed25519" | "rsa";
204
201
  attestationsPath: string;
205
202
  defaultCommand?: string | undefined;
206
203
  maxAgeDays: number;
207
204
  publicKeyPath: string;
208
- };
205
+ } & { [k: string]: unknown };
209
206
  suites: Record<string, {
210
207
  command?: string | undefined;
208
+ depends_on?: string[] | undefined;
211
209
  description?: string | undefined;
212
210
  files?: string[] | undefined;
213
211
  ignore?: string[] | undefined;
@@ -216,15 +214,16 @@ declare const configSchema: z.ZodObject<{
216
214
  }>;
217
215
  version: 1;
218
216
  }, {
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;
217
+ groups?: Record<string, string[]> | undefined;
218
+ settings?: undefined | z.objectInputType<{
219
+ attestationsPath: z.ZodDefault<z.ZodString>;
220
+ defaultCommand: z.ZodOptional<z.ZodString>;
221
+ maxAgeDays: z.ZodDefault<z.ZodNumber>;
222
+ publicKeyPath: z.ZodDefault<z.ZodString>;
223
+ }, z.ZodTypeAny, "passthrough">;
226
224
  suites: Record<string, {
227
225
  command?: string | undefined;
226
+ depends_on?: string[] | undefined;
228
227
  description?: string | undefined;
229
228
  files?: string[] | undefined;
230
229
  ignore?: string[] | undefined;
@@ -326,7 +325,11 @@ export declare interface FingerprintResult {
326
325
  }
327
326
 
328
327
  /**
329
- * Generate a new keypair using OpenSSL.
328
+ * Generate a new RSA-2048 keypair using OpenSSL.
329
+ *
330
+ * RSA-2048 with SHA-256 is used because it's universally supported across
331
+ * all OpenSSL and LibreSSL versions, including older macOS systems.
332
+ *
330
333
  * @param options - Generation options
331
334
  * @returns Paths to generated keys
332
335
  * @throws Error if OpenSSL fails or keys exist without force
@@ -353,8 +356,6 @@ export declare function getDefaultPublicKeyPath(): string;
353
356
  * @public
354
357
  */
355
358
  export declare interface KeygenOptions {
356
- /** Algorithm to use (default: ed25519) */
357
- algorithm?: Algorithm;
358
359
  /** Path for private key (default: OS-specific config dir) */
359
360
  privatePath?: string;
360
361
  /** Path for public key (default: repo root) */
@@ -490,7 +491,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
490
491
  export declare function setKeyPermissions(keyPath: string): Promise<void>;
491
492
 
492
493
  /**
493
- * Sign data using a private key.
494
+ * Sign data using an RSA private key with SHA-256.
495
+ *
496
+ * Uses `openssl dgst -sha256 -sign` which is universally supported across
497
+ * all OpenSSL and LibreSSL versions.
498
+ *
494
499
  * @param options - Signing options
495
500
  * @returns Base64-encoded signature
496
501
  * @throws Error if signing fails
@@ -538,6 +543,8 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
538
543
  command?: string;
539
544
  /** Other suite names that, when changed, invalidate this suite's attestation */
540
545
  invalidates?: string[];
546
+ /** Array of suite names this suite depends on */
547
+ depends_on?: string[];
541
548
  }
542
549
 
543
550
  /**
@@ -596,7 +603,11 @@ export declare function listPackageFiles(packages: string[], ignore?: string[],
596
603
  export declare type VerificationStatus = 'EXPIRED' | 'FINGERPRINT_CHANGED' | 'INVALIDATED_BY_PARENT' | 'NEEDS_ATTESTATION' | 'SIGNATURE_INVALID' | 'VALID';
597
604
 
598
605
  /**
599
- * Verify a signature using a public key.
606
+ * Verify a signature using an RSA public key with SHA-256.
607
+ *
608
+ * Uses `openssl dgst -sha256 -verify` which is universally supported across
609
+ * all OpenSSL and LibreSSL versions.
610
+ *
600
611
  * @param options - Verification options
601
612
  * @returns true if signature is valid
602
613
  * @throws Error if verification fails (not just invalid signature)
@@ -1,3 +1,3 @@
1
- export { checkOpenSSL, generateKeyPair, getDefaultPrivateKeyPath, getDefaultPublicKeyPath, setKeyPermissions, sign, verify } from './chunk-UWYR7JNE.js';
2
- //# sourceMappingURL=crypto-ITLMIMRJ.js.map
3
- //# sourceMappingURL=crypto-ITLMIMRJ.js.map
1
+ export { checkOpenSSL, generateKeyPair, getDefaultPrivateKeyPath, getDefaultPublicKeyPath, setKeyPermissions, sign, verify } from './chunk-CEE7ONNG.js';
2
+ //# sourceMappingURL=crypto-VAXWUGKL.js.map
3
+ //# sourceMappingURL=crypto-VAXWUGKL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"crypto-ITLMIMRJ.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"crypto-VAXWUGKL.js"}
package/dist/index.cjs CHANGED
@@ -142,7 +142,6 @@ async function cleanupFiles(...paths) {
142
142
  async function generateKeyPair(options = {}) {
143
143
  await ensureOpenSSLAvailable();
144
144
  const {
145
- algorithm = "ed25519",
146
145
  privatePath = getDefaultPrivateKeyPath(),
147
146
  publicPath = getDefaultPublicKeyPath(),
148
147
  force = false
@@ -160,7 +159,15 @@ async function generateKeyPair(options = {}) {
160
159
  await ensureDir(path2__namespace.dirname(privatePath));
161
160
  await ensureDir(path2__namespace.dirname(publicPath));
162
161
  try {
163
- const genArgs = algorithm === "ed25519" ? ["genpkey", "-algorithm", "Ed25519", "-out", privatePath] : ["genpkey", "-algorithm", "RSA", "-pkeyopt", "rsa_keygen_bits:2048", "-out", privatePath];
162
+ const genArgs = [
163
+ "genpkey",
164
+ "-algorithm",
165
+ "RSA",
166
+ "-pkeyopt",
167
+ "rsa_keygen_bits:2048",
168
+ "-out",
169
+ privatePath
170
+ ];
164
171
  const genResult = await runOpenSSL(genArgs);
165
172
  if (genResult.exitCode !== 0) {
166
173
  throw new Error(`Failed to generate private key: ${genResult.stderr}`);
@@ -192,16 +199,8 @@ async function sign(options) {
192
199
  const sigFile = path2__namespace.join(tmpDir, "sig.bin");
193
200
  try {
194
201
  await fs2__namespace.writeFile(dataFile, processBuffer);
195
- const result = await runOpenSSL([
196
- "pkeyutl",
197
- "-sign",
198
- "-inkey",
199
- privateKeyPath,
200
- "-in",
201
- dataFile,
202
- "-out",
203
- sigFile
204
- ]);
202
+ const signArgs = ["dgst", "-sha256", "-sign", privateKeyPath, "-out", sigFile, dataFile];
203
+ const result = await runOpenSSL(signArgs);
205
204
  if (result.exitCode !== 0) {
206
205
  throw new Error(`Failed to sign data: ${result.stderr}`);
207
206
  }
@@ -229,21 +228,17 @@ async function verify(options) {
229
228
  try {
230
229
  await fs2__namespace.writeFile(dataFile, processBuffer);
231
230
  await fs2__namespace.writeFile(sigFile, sigBuffer);
232
- const result = await runOpenSSL([
233
- "pkeyutl",
231
+ const verifyArgs = [
232
+ "dgst",
233
+ "-sha256",
234
234
  "-verify",
235
- "-pubin",
236
- "-inkey",
237
235
  publicKeyPath,
238
- "-sigfile",
236
+ "-signature",
239
237
  sigFile,
240
- "-in",
241
238
  dataFile
242
- ]);
243
- if (result.exitCode !== 0 && result.exitCode !== 1) {
244
- throw new Error(`Verification error: ${result.stderr}`);
245
- }
246
- return result.exitCode === 0;
239
+ ];
240
+ const result = await runOpenSSL(verifyArgs);
241
+ return result.exitCode === 0 && result.stdout.toString().includes("Verified OK");
247
242
  } finally {
248
243
  try {
249
244
  await fs2__namespace.rm(tmpDir, { recursive: true, force: true });
@@ -268,23 +263,25 @@ var settingsSchema = zod.z.object({
268
263
  maxAgeDays: zod.z.number().int().positive().default(30),
269
264
  publicKeyPath: zod.z.string().default(".attest-it/pubkey.pem"),
270
265
  attestationsPath: zod.z.string().default(".attest-it/attestations.json"),
271
- defaultCommand: zod.z.string().optional(),
272
- algorithm: zod.z.enum(["ed25519", "rsa"]).default("ed25519")
273
- }).strict();
266
+ defaultCommand: zod.z.string().optional()
267
+ // Note: algorithm field was removed - RSA is the only supported algorithm
268
+ }).passthrough();
274
269
  var suiteSchema = zod.z.object({
275
270
  description: zod.z.string().optional(),
276
271
  packages: zod.z.array(zod.z.string().min(1, "Package path cannot be empty")).min(1, "At least one package pattern is required"),
277
272
  files: zod.z.array(zod.z.string().min(1, "File path cannot be empty")).optional(),
278
273
  ignore: zod.z.array(zod.z.string().min(1, "Ignore pattern cannot be empty")).optional(),
279
274
  command: zod.z.string().optional(),
280
- invalidates: zod.z.array(zod.z.string().min(1, "Invalidated suite name cannot be empty")).optional()
275
+ invalidates: zod.z.array(zod.z.string().min(1, "Invalidated suite name cannot be empty")).optional(),
276
+ depends_on: zod.z.array(zod.z.string().min(1, "Dependency suite name cannot be empty")).optional()
281
277
  }).strict();
282
278
  var configSchema = zod.z.object({
283
279
  version: zod.z.literal(1),
284
280
  settings: settingsSchema.default({}),
285
281
  suites: zod.z.record(zod.z.string(), suiteSchema).refine((suites) => Object.keys(suites).length >= 1, {
286
282
  message: "At least one suite must be defined"
287
- })
283
+ }),
284
+ groups: zod.z.record(zod.z.string(), zod.z.array(zod.z.string().min(1, "Suite name in group cannot be empty"))).optional()
288
285
  }).strict();
289
286
  var ConfigValidationError = class extends Error {
290
287
  constructor(message, issues) {
@@ -403,7 +400,6 @@ function toAttestItConfig(config) {
403
400
  maxAgeDays: config.settings.maxAgeDays,
404
401
  publicKeyPath: config.settings.publicKeyPath,
405
402
  attestationsPath: config.settings.attestationsPath,
406
- algorithm: config.settings.algorithm,
407
403
  ...config.settings.defaultCommand !== void 0 && {
408
404
  defaultCommand: config.settings.defaultCommand
409
405
  }
@@ -417,10 +413,12 @@ function toAttestItConfig(config) {
417
413
  ...suite.files !== void 0 && { files: suite.files },
418
414
  ...suite.ignore !== void 0 && { ignore: suite.ignore },
419
415
  ...suite.command !== void 0 && { command: suite.command },
420
- ...suite.invalidates !== void 0 && { invalidates: suite.invalidates }
416
+ ...suite.invalidates !== void 0 && { invalidates: suite.invalidates },
417
+ ...suite.depends_on !== void 0 && { depends_on: suite.depends_on }
421
418
  }
422
419
  ])
423
- )
420
+ ),
421
+ ...config.groups !== void 0 && { groups: config.groups }
424
422
  };
425
423
  }
426
424
  var LARGE_FILE_THRESHOLD = 50 * 1024 * 1024;