vaultkeeper 0.4.0 → 1.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/dist/index.cjs CHANGED
@@ -5,6 +5,7 @@ var fs5 = require('fs/promises');
5
5
  var path5 = require('path');
6
6
  var os4 = require('os');
7
7
  var crypto4 = require('crypto');
8
+ require('url');
8
9
  var fs4 = require('fs');
9
10
  var jose = require('jose');
10
11
 
@@ -162,6 +163,22 @@ var IdentityMismatchError = class extends VaultError {
162
163
  this.currentHash = currentHash;
163
164
  }
164
165
  };
166
+ var InvalidAlgorithmError = class extends VaultError {
167
+ /**
168
+ * The algorithm that was requested.
169
+ */
170
+ algorithm;
171
+ /**
172
+ * The set of algorithms that are allowed.
173
+ */
174
+ allowed;
175
+ constructor(message, algorithm, allowed) {
176
+ super(message);
177
+ this.name = "InvalidAlgorithmError";
178
+ this.algorithm = algorithm;
179
+ this.allowed = allowed;
180
+ }
181
+ };
165
182
  var SetupError = class extends VaultError {
166
183
  /**
167
184
  * The name of the dependency that caused the setup failure.
@@ -205,6 +222,7 @@ function isListableBackend(backend) {
205
222
  // src/backend/registry.ts
206
223
  var BackendRegistry = class {
207
224
  static backends = /* @__PURE__ */ new Map();
225
+ static setups = /* @__PURE__ */ new Map();
208
226
  /**
209
227
  * Register a backend factory.
210
228
  * @param type - Backend type identifier
@@ -217,7 +235,7 @@ var BackendRegistry = class {
217
235
  * Create a backend instance by type.
218
236
  * @param type - Backend type identifier
219
237
  * @returns A SecretBackend instance
220
- * @throws Error if the backend type is not registered
238
+ * @throws {@link BackendUnavailableError} if the backend type is not registered
221
239
  */
222
240
  static create(type) {
223
241
  const factory = this.backends.get(type);
@@ -264,6 +282,46 @@ var BackendRegistry = class {
264
282
  );
265
283
  return results.filter((type) => type !== null);
266
284
  }
285
+ /**
286
+ * Register a setup factory for a backend type.
287
+ * @param type - Backend type identifier
288
+ * @param factory - Factory function that creates a setup generator
289
+ */
290
+ static registerSetup(type, factory) {
291
+ this.setups.set(type, factory);
292
+ }
293
+ /**
294
+ * Get the setup factory for a backend type, if one is registered.
295
+ * @param type - Backend type identifier
296
+ * @returns The setup factory, or `undefined` if none is registered
297
+ */
298
+ static getSetup(type) {
299
+ return this.setups.get(type);
300
+ }
301
+ /**
302
+ * Check whether a setup factory is registered for the given backend type.
303
+ * @param type - Backend type identifier
304
+ * @returns `true` if a setup factory is registered
305
+ */
306
+ static hasSetup(type) {
307
+ return this.setups.has(type);
308
+ }
309
+ /**
310
+ * Clear all registered backend factories.
311
+ * Intended for use in tests only.
312
+ * @internal
313
+ */
314
+ static clearBackends() {
315
+ this.backends.clear();
316
+ }
317
+ /**
318
+ * Clear all registered setup factories.
319
+ * Intended for use in tests only.
320
+ * @internal
321
+ */
322
+ static clearSetups() {
323
+ this.setups.clear();
324
+ }
267
325
  };
268
326
  async function execCommand(command, args, options) {
269
327
  const result = await execCommandFull(command, args);
@@ -513,6 +571,21 @@ function validateBackendEntry(entry, index) {
513
571
  }
514
572
  result.path = entry.path;
515
573
  }
574
+ if (entry.options !== void 0) {
575
+ if (!isObject(entry.options)) {
576
+ throw new Error(`backends[${String(index)}].options must be an object`);
577
+ }
578
+ const opts = {};
579
+ for (const [k, v] of Object.entries(entry.options)) {
580
+ if (typeof v !== "string") {
581
+ throw new Error(
582
+ `backends[${String(index)}].options["${k}"] must be a string`
583
+ );
584
+ }
585
+ opts[k] = v;
586
+ }
587
+ result.options = opts;
588
+ }
516
589
  return result;
517
590
  }
518
591
  function validateConfig(config) {
@@ -1023,10 +1096,12 @@ function resolveAlgorithmForKey(key, override) {
1023
1096
  if (keyType === "ed25519" || keyType === "ed448") {
1024
1097
  return { signAlg: null, label: keyType };
1025
1098
  }
1026
- const alg = override ?? "sha256";
1099
+ const alg = (override ?? "sha256").toLowerCase();
1027
1100
  if (!ALLOWED_ALGORITHMS.has(alg)) {
1028
- throw new VaultError(
1029
- `Unsupported signing algorithm '${alg}'. Allowed: ${[...ALLOWED_ALGORITHMS].join(", ")}`
1101
+ throw new InvalidAlgorithmError(
1102
+ `Unsupported algorithm '${alg}'. Allowed: ${[...ALLOWED_ALGORITHMS].join(", ")}`,
1103
+ alg,
1104
+ [...ALLOWED_ALGORITHMS]
1030
1105
  );
1031
1106
  }
1032
1107
  return { signAlg: alg, label: alg };
@@ -1050,6 +1125,9 @@ function delegatedVerify(request) {
1050
1125
  } catch {
1051
1126
  return false;
1052
1127
  }
1128
+ if (typeof request.publicKey === "string" && request.publicKey.includes("PRIVATE KEY")) {
1129
+ return false;
1130
+ }
1053
1131
  const { signAlg } = resolveAlgorithmForKey(key, request.algorithm);
1054
1132
  const sig = Buffer.from(request.signature, "base64");
1055
1133
  try {
@@ -1431,6 +1509,8 @@ var VaultKeeper = class _VaultKeeper {
1431
1509
  * with the vault metadata (`vaultResponse`).
1432
1510
  * @throws {VaultError} If `token` is invalid or was not created by this
1433
1511
  * vault instance.
1512
+ * @throws {InvalidAlgorithmError} If `request.algorithm` is not in the
1513
+ * allowed set (e.g. `'md5'`).
1434
1514
  */
1435
1515
  async sign(token, request) {
1436
1516
  const claims = validateCapabilityToken(token);
@@ -1448,8 +1528,11 @@ var VaultKeeper = class _VaultKeeper {
1448
1528
  * capability tokens are required. It is safe to call from CI or any
1449
1529
  * context that has access to public key material.
1450
1530
  *
1451
- * Never throws. Returns `false` for invalid key material, malformed
1452
- * signatures, or any verification failure.
1531
+ * Returns `false` for invalid key material, malformed signatures, or
1532
+ * any verification failure (except disallowed algorithms, which throw).
1533
+ *
1534
+ * @throws {InvalidAlgorithmError} If `request.algorithm` is not in the
1535
+ * allowed set (e.g. `'md5'`).
1453
1536
  *
1454
1537
  * @param request - The data, signature, public key, and optional
1455
1538
  * algorithm override.
@@ -1582,6 +1665,7 @@ exports.CapabilityToken = CapabilityToken;
1582
1665
  exports.DeviceNotPresentError = DeviceNotPresentError;
1583
1666
  exports.FilesystemError = FilesystemError;
1584
1667
  exports.IdentityMismatchError = IdentityMismatchError;
1668
+ exports.InvalidAlgorithmError = InvalidAlgorithmError;
1585
1669
  exports.KeyRevokedError = KeyRevokedError;
1586
1670
  exports.KeyRotatedError = KeyRotatedError;
1587
1671
  exports.PluginNotFoundError = PluginNotFoundError;