vaultkeeper 0.3.0 → 0.4.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 +85 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -287,6 +287,59 @@ interface SecretAccessor {
|
|
|
287
287
|
*/
|
|
288
288
|
read(callback: (buf: Buffer) => void): void;
|
|
289
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Request for delegated signing.
|
|
292
|
+
*
|
|
293
|
+
* The `data` field is the payload to sign. Strings are UTF-8-encoded
|
|
294
|
+
* before signing.
|
|
295
|
+
*/
|
|
296
|
+
interface SignRequest {
|
|
297
|
+
/** The data to sign. Strings are treated as UTF-8. */
|
|
298
|
+
data: string | Buffer;
|
|
299
|
+
/**
|
|
300
|
+
* Override the hash algorithm (`'sha256'`, `'sha384'`, or `'sha512'`).
|
|
301
|
+
* Ignored for Ed25519/Ed448 keys where the algorithm is implicit.
|
|
302
|
+
* Non-Edwards keys (RSA, EC) default to `'sha256'` when omitted.
|
|
303
|
+
* Weak algorithms (e.g. `'md5'`, `'sha1'`) are rejected.
|
|
304
|
+
*/
|
|
305
|
+
algorithm?: string | undefined;
|
|
306
|
+
}
|
|
307
|
+
/** Result from a delegated signing operation. */
|
|
308
|
+
interface SignResult {
|
|
309
|
+
/** Base64-encoded signature. */
|
|
310
|
+
signature: string;
|
|
311
|
+
/**
|
|
312
|
+
* Algorithm label describing how the signature was produced.
|
|
313
|
+
* For Edwards keys this is the key type (e.g. `'ed25519'`).
|
|
314
|
+
* For other keys this matches the `algorithm` field from the request
|
|
315
|
+
* (or the default `'sha256'`).
|
|
316
|
+
*/
|
|
317
|
+
algorithm: string;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Request for signature verification.
|
|
321
|
+
*
|
|
322
|
+
* This is a static operation that only requires public key material —
|
|
323
|
+
* no VaultKeeper instance or capability token is needed.
|
|
324
|
+
*/
|
|
325
|
+
interface VerifyRequest {
|
|
326
|
+
/** The original data that was signed. Strings are treated as UTF-8. */
|
|
327
|
+
data: string | Buffer;
|
|
328
|
+
/** Base64-encoded signature to verify. */
|
|
329
|
+
signature: string;
|
|
330
|
+
/**
|
|
331
|
+
* PEM-encoded public key (SPKI format) as a string.
|
|
332
|
+
*
|
|
333
|
+
* Other `KeyLike` formats supported by `crypto.createPublicKey()` are not
|
|
334
|
+
* accepted by this interface.
|
|
335
|
+
*/
|
|
336
|
+
publicKey: string;
|
|
337
|
+
/**
|
|
338
|
+
* Override the hash algorithm. Ignored for Ed25519/Ed448 keys.
|
|
339
|
+
* Non-Edwards keys default to `'sha256'` when omitted.
|
|
340
|
+
*/
|
|
341
|
+
algorithm?: string | undefined;
|
|
342
|
+
}
|
|
290
343
|
/** Vaultkeeper configuration file structure. */
|
|
291
344
|
interface VaultConfig {
|
|
292
345
|
/** Config schema version. Currently must be `1`. */
|
|
@@ -578,6 +631,40 @@ declare class VaultKeeper {
|
|
|
578
631
|
* instance.
|
|
579
632
|
*/
|
|
580
633
|
getSecret(token: CapabilityToken): SecretAccessor;
|
|
634
|
+
/**
|
|
635
|
+
* Sign data using the private key embedded in a capability token.
|
|
636
|
+
*
|
|
637
|
+
* The signing key is extracted from the token's encrypted claims, used
|
|
638
|
+
* for a single `crypto.sign()` call, and never exposed to the caller.
|
|
639
|
+
* The algorithm is auto-detected from the key type unless overridden
|
|
640
|
+
* in the request.
|
|
641
|
+
*
|
|
642
|
+
* @param token - A `CapabilityToken` obtained from `authorize()`.
|
|
643
|
+
* @param request - The data to sign and optional algorithm override.
|
|
644
|
+
* @returns The base64-encoded signature and algorithm label, together
|
|
645
|
+
* with the vault metadata (`vaultResponse`).
|
|
646
|
+
* @throws {VaultError} If `token` is invalid or was not created by this
|
|
647
|
+
* vault instance.
|
|
648
|
+
*/
|
|
649
|
+
sign(token: CapabilityToken, request: SignRequest): Promise<{
|
|
650
|
+
result: SignResult;
|
|
651
|
+
vaultResponse: VaultResponse;
|
|
652
|
+
}>;
|
|
653
|
+
/**
|
|
654
|
+
* Verify a signature using a public key.
|
|
655
|
+
*
|
|
656
|
+
* This is a static method — no VaultKeeper instance, secrets, or
|
|
657
|
+
* capability tokens are required. It is safe to call from CI or any
|
|
658
|
+
* context that has access to public key material.
|
|
659
|
+
*
|
|
660
|
+
* Never throws. Returns `false` for invalid key material, malformed
|
|
661
|
+
* signatures, or any verification failure.
|
|
662
|
+
*
|
|
663
|
+
* @param request - The data, signature, public key, and optional
|
|
664
|
+
* algorithm override.
|
|
665
|
+
* @returns `true` if the signature is valid, `false` otherwise.
|
|
666
|
+
*/
|
|
667
|
+
static verify(request: VerifyRequest): boolean;
|
|
581
668
|
/**
|
|
582
669
|
* Rotate the current encryption key.
|
|
583
670
|
*
|
|
@@ -613,4 +700,4 @@ declare class VaultKeeper {
|
|
|
613
700
|
setDevelopmentMode(executablePath: string, enabled: boolean): Promise<void>;
|
|
614
701
|
}
|
|
615
702
|
|
|
616
|
-
export { AuthorizationDeniedError, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, BackendUnavailableError, CapabilityToken, DeviceNotPresentError, type ExecRequest, type ExecResult, type FetchRequest, FilesystemError, IdentityMismatchError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, PluginNotFoundError, type PreflightCheck, type PreflightCheckStatus, type PreflightResult, RotationInProgressError, type SecretAccessor, type SecretBackend, SecretNotFoundError, SetupError, type SetupOptions, TokenExpiredError, TokenRevokedError, type TrustTier, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, isListableBackend };
|
|
703
|
+
export { AuthorizationDeniedError, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, BackendUnavailableError, CapabilityToken, DeviceNotPresentError, type ExecRequest, type ExecResult, type FetchRequest, FilesystemError, IdentityMismatchError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, PluginNotFoundError, type PreflightCheck, type PreflightCheckStatus, type PreflightResult, RotationInProgressError, type SecretAccessor, type SecretBackend, SecretNotFoundError, SetupError, type SetupOptions, type SignRequest, type SignResult, TokenExpiredError, TokenRevokedError, type TrustTier, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, type VerifyRequest, isListableBackend };
|
package/dist/index.d.ts
CHANGED
|
@@ -287,6 +287,59 @@ interface SecretAccessor {
|
|
|
287
287
|
*/
|
|
288
288
|
read(callback: (buf: Buffer) => void): void;
|
|
289
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Request for delegated signing.
|
|
292
|
+
*
|
|
293
|
+
* The `data` field is the payload to sign. Strings are UTF-8-encoded
|
|
294
|
+
* before signing.
|
|
295
|
+
*/
|
|
296
|
+
interface SignRequest {
|
|
297
|
+
/** The data to sign. Strings are treated as UTF-8. */
|
|
298
|
+
data: string | Buffer;
|
|
299
|
+
/**
|
|
300
|
+
* Override the hash algorithm (`'sha256'`, `'sha384'`, or `'sha512'`).
|
|
301
|
+
* Ignored for Ed25519/Ed448 keys where the algorithm is implicit.
|
|
302
|
+
* Non-Edwards keys (RSA, EC) default to `'sha256'` when omitted.
|
|
303
|
+
* Weak algorithms (e.g. `'md5'`, `'sha1'`) are rejected.
|
|
304
|
+
*/
|
|
305
|
+
algorithm?: string | undefined;
|
|
306
|
+
}
|
|
307
|
+
/** Result from a delegated signing operation. */
|
|
308
|
+
interface SignResult {
|
|
309
|
+
/** Base64-encoded signature. */
|
|
310
|
+
signature: string;
|
|
311
|
+
/**
|
|
312
|
+
* Algorithm label describing how the signature was produced.
|
|
313
|
+
* For Edwards keys this is the key type (e.g. `'ed25519'`).
|
|
314
|
+
* For other keys this matches the `algorithm` field from the request
|
|
315
|
+
* (or the default `'sha256'`).
|
|
316
|
+
*/
|
|
317
|
+
algorithm: string;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Request for signature verification.
|
|
321
|
+
*
|
|
322
|
+
* This is a static operation that only requires public key material —
|
|
323
|
+
* no VaultKeeper instance or capability token is needed.
|
|
324
|
+
*/
|
|
325
|
+
interface VerifyRequest {
|
|
326
|
+
/** The original data that was signed. Strings are treated as UTF-8. */
|
|
327
|
+
data: string | Buffer;
|
|
328
|
+
/** Base64-encoded signature to verify. */
|
|
329
|
+
signature: string;
|
|
330
|
+
/**
|
|
331
|
+
* PEM-encoded public key (SPKI format) as a string.
|
|
332
|
+
*
|
|
333
|
+
* Other `KeyLike` formats supported by `crypto.createPublicKey()` are not
|
|
334
|
+
* accepted by this interface.
|
|
335
|
+
*/
|
|
336
|
+
publicKey: string;
|
|
337
|
+
/**
|
|
338
|
+
* Override the hash algorithm. Ignored for Ed25519/Ed448 keys.
|
|
339
|
+
* Non-Edwards keys default to `'sha256'` when omitted.
|
|
340
|
+
*/
|
|
341
|
+
algorithm?: string | undefined;
|
|
342
|
+
}
|
|
290
343
|
/** Vaultkeeper configuration file structure. */
|
|
291
344
|
interface VaultConfig {
|
|
292
345
|
/** Config schema version. Currently must be `1`. */
|
|
@@ -578,6 +631,40 @@ declare class VaultKeeper {
|
|
|
578
631
|
* instance.
|
|
579
632
|
*/
|
|
580
633
|
getSecret(token: CapabilityToken): SecretAccessor;
|
|
634
|
+
/**
|
|
635
|
+
* Sign data using the private key embedded in a capability token.
|
|
636
|
+
*
|
|
637
|
+
* The signing key is extracted from the token's encrypted claims, used
|
|
638
|
+
* for a single `crypto.sign()` call, and never exposed to the caller.
|
|
639
|
+
* The algorithm is auto-detected from the key type unless overridden
|
|
640
|
+
* in the request.
|
|
641
|
+
*
|
|
642
|
+
* @param token - A `CapabilityToken` obtained from `authorize()`.
|
|
643
|
+
* @param request - The data to sign and optional algorithm override.
|
|
644
|
+
* @returns The base64-encoded signature and algorithm label, together
|
|
645
|
+
* with the vault metadata (`vaultResponse`).
|
|
646
|
+
* @throws {VaultError} If `token` is invalid or was not created by this
|
|
647
|
+
* vault instance.
|
|
648
|
+
*/
|
|
649
|
+
sign(token: CapabilityToken, request: SignRequest): Promise<{
|
|
650
|
+
result: SignResult;
|
|
651
|
+
vaultResponse: VaultResponse;
|
|
652
|
+
}>;
|
|
653
|
+
/**
|
|
654
|
+
* Verify a signature using a public key.
|
|
655
|
+
*
|
|
656
|
+
* This is a static method — no VaultKeeper instance, secrets, or
|
|
657
|
+
* capability tokens are required. It is safe to call from CI or any
|
|
658
|
+
* context that has access to public key material.
|
|
659
|
+
*
|
|
660
|
+
* Never throws. Returns `false` for invalid key material, malformed
|
|
661
|
+
* signatures, or any verification failure.
|
|
662
|
+
*
|
|
663
|
+
* @param request - The data, signature, public key, and optional
|
|
664
|
+
* algorithm override.
|
|
665
|
+
* @returns `true` if the signature is valid, `false` otherwise.
|
|
666
|
+
*/
|
|
667
|
+
static verify(request: VerifyRequest): boolean;
|
|
581
668
|
/**
|
|
582
669
|
* Rotate the current encryption key.
|
|
583
670
|
*
|
|
@@ -613,4 +700,4 @@ declare class VaultKeeper {
|
|
|
613
700
|
setDevelopmentMode(executablePath: string, enabled: boolean): Promise<void>;
|
|
614
701
|
}
|
|
615
702
|
|
|
616
|
-
export { AuthorizationDeniedError, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, BackendUnavailableError, CapabilityToken, DeviceNotPresentError, type ExecRequest, type ExecResult, type FetchRequest, FilesystemError, IdentityMismatchError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, PluginNotFoundError, type PreflightCheck, type PreflightCheckStatus, type PreflightResult, RotationInProgressError, type SecretAccessor, type SecretBackend, SecretNotFoundError, SetupError, type SetupOptions, TokenExpiredError, TokenRevokedError, type TrustTier, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, isListableBackend };
|
|
703
|
+
export { AuthorizationDeniedError, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, BackendUnavailableError, CapabilityToken, DeviceNotPresentError, type ExecRequest, type ExecResult, type FetchRequest, FilesystemError, IdentityMismatchError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, PluginNotFoundError, type PreflightCheck, type PreflightCheckStatus, type PreflightResult, RotationInProgressError, type SecretAccessor, type SecretBackend, SecretNotFoundError, SetupError, type SetupOptions, type SignRequest, type SignResult, TokenExpiredError, TokenRevokedError, type TrustTier, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, type VerifyRequest, isListableBackend };
|
package/dist/index.js
CHANGED
|
@@ -990,6 +990,50 @@ function createSecretAccessor(secretValue) {
|
|
|
990
990
|
return proxy;
|
|
991
991
|
}
|
|
992
992
|
|
|
993
|
+
// src/access/sign-util.ts
|
|
994
|
+
var ALLOWED_ALGORITHMS = /* @__PURE__ */ new Set(["sha256", "sha384", "sha512"]);
|
|
995
|
+
function resolveAlgorithmForKey(key, override) {
|
|
996
|
+
const keyType = key.asymmetricKeyType;
|
|
997
|
+
if (keyType === "ed25519" || keyType === "ed448") {
|
|
998
|
+
return { signAlg: null, label: keyType };
|
|
999
|
+
}
|
|
1000
|
+
const alg = override ?? "sha256";
|
|
1001
|
+
if (!ALLOWED_ALGORITHMS.has(alg)) {
|
|
1002
|
+
throw new VaultError(
|
|
1003
|
+
`Unsupported signing algorithm '${alg}'. Allowed: ${[...ALLOWED_ALGORITHMS].join(", ")}`
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
return { signAlg: alg, label: alg };
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// src/access/delegated-sign.ts
|
|
1010
|
+
function delegatedSign(secretPem, request) {
|
|
1011
|
+
const key = crypto4.createPrivateKey(secretPem);
|
|
1012
|
+
const { signAlg, label } = resolveAlgorithmForKey(key, request.algorithm);
|
|
1013
|
+
const data = Buffer.isBuffer(request.data) ? request.data : Buffer.from(request.data);
|
|
1014
|
+
const signature = crypto4.sign(signAlg, data, key);
|
|
1015
|
+
return {
|
|
1016
|
+
signature: signature.toString("base64"),
|
|
1017
|
+
algorithm: label
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
function delegatedVerify(request) {
|
|
1021
|
+
let key;
|
|
1022
|
+
try {
|
|
1023
|
+
key = crypto4.createPublicKey(request.publicKey);
|
|
1024
|
+
} catch {
|
|
1025
|
+
return false;
|
|
1026
|
+
}
|
|
1027
|
+
const { signAlg } = resolveAlgorithmForKey(key, request.algorithm);
|
|
1028
|
+
const sig = Buffer.from(request.signature, "base64");
|
|
1029
|
+
try {
|
|
1030
|
+
const data = Buffer.isBuffer(request.data) ? request.data : Buffer.from(request.data);
|
|
1031
|
+
return crypto4.verify(signAlg, data, key, sig);
|
|
1032
|
+
} catch {
|
|
1033
|
+
return false;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
993
1037
|
// src/doctor/checks.ts
|
|
994
1038
|
function parseVersion(raw) {
|
|
995
1039
|
const match = /(\d+)\.(\d+)\.(\d+)/.exec(raw);
|
|
@@ -1347,6 +1391,47 @@ var VaultKeeper = class _VaultKeeper {
|
|
|
1347
1391
|
const claims = validateCapabilityToken(token);
|
|
1348
1392
|
return createSecretAccessor(claims.val);
|
|
1349
1393
|
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Sign data using the private key embedded in a capability token.
|
|
1396
|
+
*
|
|
1397
|
+
* The signing key is extracted from the token's encrypted claims, used
|
|
1398
|
+
* for a single `crypto.sign()` call, and never exposed to the caller.
|
|
1399
|
+
* The algorithm is auto-detected from the key type unless overridden
|
|
1400
|
+
* in the request.
|
|
1401
|
+
*
|
|
1402
|
+
* @param token - A `CapabilityToken` obtained from `authorize()`.
|
|
1403
|
+
* @param request - The data to sign and optional algorithm override.
|
|
1404
|
+
* @returns The base64-encoded signature and algorithm label, together
|
|
1405
|
+
* with the vault metadata (`vaultResponse`).
|
|
1406
|
+
* @throws {VaultError} If `token` is invalid or was not created by this
|
|
1407
|
+
* vault instance.
|
|
1408
|
+
*/
|
|
1409
|
+
async sign(token, request) {
|
|
1410
|
+
const claims = validateCapabilityToken(token);
|
|
1411
|
+
const result = delegatedSign(claims.val, request);
|
|
1412
|
+
await Promise.resolve();
|
|
1413
|
+
return {
|
|
1414
|
+
result,
|
|
1415
|
+
vaultResponse: { keyStatus: "current" }
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Verify a signature using a public key.
|
|
1420
|
+
*
|
|
1421
|
+
* This is a static method — no VaultKeeper instance, secrets, or
|
|
1422
|
+
* capability tokens are required. It is safe to call from CI or any
|
|
1423
|
+
* context that has access to public key material.
|
|
1424
|
+
*
|
|
1425
|
+
* Never throws. Returns `false` for invalid key material, malformed
|
|
1426
|
+
* signatures, or any verification failure.
|
|
1427
|
+
*
|
|
1428
|
+
* @param request - The data, signature, public key, and optional
|
|
1429
|
+
* algorithm override.
|
|
1430
|
+
* @returns `true` if the signature is valid, `false` otherwise.
|
|
1431
|
+
*/
|
|
1432
|
+
static verify(request) {
|
|
1433
|
+
return delegatedVerify(request);
|
|
1434
|
+
}
|
|
1350
1435
|
/**
|
|
1351
1436
|
* Rotate the current encryption key.
|
|
1352
1437
|
*
|