vaultkeeper 0.7.0 → 0.8.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 +5 -1
- package/dist/index.cjs +127 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +127 -24
- package/dist/index.js.map +1 -1
- package/dist/one-password-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -527,6 +527,34 @@ declare class FilesystemError extends VaultError {
|
|
|
527
527
|
declare class RotationInProgressError extends VaultError {
|
|
528
528
|
constructor(message: string);
|
|
529
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Thrown when a test-only double — a class built purely to fabricate a
|
|
532
|
+
* vaultkeeper-internal signal (e.g. a granted presence check, an unlocked
|
|
533
|
+
* backend) for driving negative test cases — refuses to construct because it
|
|
534
|
+
* detected it is running outside a test environment.
|
|
535
|
+
*
|
|
536
|
+
* @remarks
|
|
537
|
+
* A fabricated signal is, by construction, exactly the thing a real
|
|
538
|
+
* deployment must never be able to forge. A loud, typed refusal at
|
|
539
|
+
* construction time is the last of several stacked guards keeping such a
|
|
540
|
+
* double unreachable from production — see, for example,
|
|
541
|
+
* `PresenceSimulatorBackend` in `@vaultkeeper/test-helpers`. Inspect
|
|
542
|
+
* {@link TestDoubleMisuseError.doubleName} for which class refused to
|
|
543
|
+
* construct and {@link TestDoubleMisuseError.detectedEnvironment} for the
|
|
544
|
+
* environment value that triggered the refusal.
|
|
545
|
+
*
|
|
546
|
+
* @public
|
|
547
|
+
*/
|
|
548
|
+
declare class TestDoubleMisuseError extends VaultError {
|
|
549
|
+
/** The name of the test double class that refused to construct. */
|
|
550
|
+
readonly doubleName: string;
|
|
551
|
+
/**
|
|
552
|
+
* The environment value (e.g. `process.env.NODE_ENV`) that triggered the
|
|
553
|
+
* refusal.
|
|
554
|
+
*/
|
|
555
|
+
readonly detectedEnvironment: string;
|
|
556
|
+
constructor(message: string, doubleName: string, detectedEnvironment: string);
|
|
557
|
+
}
|
|
530
558
|
|
|
531
559
|
/**
|
|
532
560
|
* Shared types and interfaces for vaultkeeper.
|
|
@@ -2128,4 +2156,4 @@ declare function platformNativeBackendType(): string;
|
|
|
2128
2156
|
*/
|
|
2129
2157
|
declare function loadConfig(configDir?: string): Promise<VaultConfig>;
|
|
2130
2158
|
|
|
2131
|
-
export { AccessorConsumedError, AuthorizationDeniedError, type BackendCapabilities, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, type BackendSetupFactory, BackendUnavailableError, CapabilityToken, ConfigParseError, ConfigValidationError, DecryptionError, DeviceNotPresentError, ExecError, type ExecRequest, type ExecResult, ExecutableTrustRequiredError, type ExecutableTrustStatus, FetchError, type FetchRequest, FilesystemError, IdentityMismatchError, InvalidAlgorithmError, InvalidKeyMaterialError, InvalidTokenError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, NotCapableError, type Platform, PluginNotFoundError, type PreflightCheck, type PreflightCheckError, type PreflightCheckErrorKind, type PreflightCheckStatus, type PreflightResult, type PresenceCapableBackend, PresenceDeclinedError, type PresenceOperation, type PresenceRequirementOptions, PresenceTimeoutError, REDACTED, RotationInProgressError, type RunDoctorOptions, type ScopedPreflightCheck, type SecretAccessor, type SecretBackend, SecretNotFoundError, type SecretTokenMap, type SetupChoice, SetupError, type SetupOptions, type SetupOptionsBase, type SetupQuestion, type SetupResult, type SignRequest, type SignResult, type SigningAlgorithm, type SigningBackend, SigningKeyAlreadyExistsError, SigningKeyNotFoundError, SigningNotSupportedError, type SigningPublicKey, TokenExpiredError, TokenRevokedError, type TrustTier, UnknownBackendTypeError, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, type VerifyRequest, defaultBackendType, getBackendCapabilities, getDefaultConfigDir, getPlatformDefaultConfigDir, isListableBackend, isPresenceCapableBackend, isSigningBackend, loadConfig, platformNativeBackendType, redactSecrets, runDoctor };
|
|
2159
|
+
export { AccessorConsumedError, AuthorizationDeniedError, type BackendCapabilities, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, type BackendSetupFactory, BackendUnavailableError, CapabilityToken, ConfigParseError, ConfigValidationError, DecryptionError, DeviceNotPresentError, ExecError, type ExecRequest, type ExecResult, ExecutableTrustRequiredError, type ExecutableTrustStatus, FetchError, type FetchRequest, FilesystemError, IdentityMismatchError, InvalidAlgorithmError, InvalidKeyMaterialError, InvalidTokenError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, NotCapableError, type Platform, PluginNotFoundError, type PreflightCheck, type PreflightCheckError, type PreflightCheckErrorKind, type PreflightCheckStatus, type PreflightResult, type PresenceCapableBackend, PresenceDeclinedError, type PresenceOperation, type PresenceRequirementOptions, PresenceTimeoutError, REDACTED, RotationInProgressError, type RunDoctorOptions, type ScopedPreflightCheck, type SecretAccessor, type SecretBackend, SecretNotFoundError, type SecretTokenMap, type SetupChoice, SetupError, type SetupOptions, type SetupOptionsBase, type SetupQuestion, type SetupResult, type SignRequest, type SignResult, type SigningAlgorithm, type SigningBackend, SigningKeyAlreadyExistsError, SigningKeyNotFoundError, SigningNotSupportedError, type SigningPublicKey, TestDoubleMisuseError, TokenExpiredError, TokenRevokedError, type TrustTier, UnknownBackendTypeError, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, type VerifyRequest, defaultBackendType, getBackendCapabilities, getDefaultConfigDir, getPlatformDefaultConfigDir, isListableBackend, isPresenceCapableBackend, isSigningBackend, loadConfig, platformNativeBackendType, redactSecrets, runDoctor };
|
package/dist/index.d.ts
CHANGED
|
@@ -527,6 +527,34 @@ declare class FilesystemError extends VaultError {
|
|
|
527
527
|
declare class RotationInProgressError extends VaultError {
|
|
528
528
|
constructor(message: string);
|
|
529
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Thrown when a test-only double — a class built purely to fabricate a
|
|
532
|
+
* vaultkeeper-internal signal (e.g. a granted presence check, an unlocked
|
|
533
|
+
* backend) for driving negative test cases — refuses to construct because it
|
|
534
|
+
* detected it is running outside a test environment.
|
|
535
|
+
*
|
|
536
|
+
* @remarks
|
|
537
|
+
* A fabricated signal is, by construction, exactly the thing a real
|
|
538
|
+
* deployment must never be able to forge. A loud, typed refusal at
|
|
539
|
+
* construction time is the last of several stacked guards keeping such a
|
|
540
|
+
* double unreachable from production — see, for example,
|
|
541
|
+
* `PresenceSimulatorBackend` in `@vaultkeeper/test-helpers`. Inspect
|
|
542
|
+
* {@link TestDoubleMisuseError.doubleName} for which class refused to
|
|
543
|
+
* construct and {@link TestDoubleMisuseError.detectedEnvironment} for the
|
|
544
|
+
* environment value that triggered the refusal.
|
|
545
|
+
*
|
|
546
|
+
* @public
|
|
547
|
+
*/
|
|
548
|
+
declare class TestDoubleMisuseError extends VaultError {
|
|
549
|
+
/** The name of the test double class that refused to construct. */
|
|
550
|
+
readonly doubleName: string;
|
|
551
|
+
/**
|
|
552
|
+
* The environment value (e.g. `process.env.NODE_ENV`) that triggered the
|
|
553
|
+
* refusal.
|
|
554
|
+
*/
|
|
555
|
+
readonly detectedEnvironment: string;
|
|
556
|
+
constructor(message: string, doubleName: string, detectedEnvironment: string);
|
|
557
|
+
}
|
|
530
558
|
|
|
531
559
|
/**
|
|
532
560
|
* Shared types and interfaces for vaultkeeper.
|
|
@@ -2128,4 +2156,4 @@ declare function platformNativeBackendType(): string;
|
|
|
2128
2156
|
*/
|
|
2129
2157
|
declare function loadConfig(configDir?: string): Promise<VaultConfig>;
|
|
2130
2158
|
|
|
2131
|
-
export { AccessorConsumedError, AuthorizationDeniedError, type BackendCapabilities, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, type BackendSetupFactory, BackendUnavailableError, CapabilityToken, ConfigParseError, ConfigValidationError, DecryptionError, DeviceNotPresentError, ExecError, type ExecRequest, type ExecResult, ExecutableTrustRequiredError, type ExecutableTrustStatus, FetchError, type FetchRequest, FilesystemError, IdentityMismatchError, InvalidAlgorithmError, InvalidKeyMaterialError, InvalidTokenError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, NotCapableError, type Platform, PluginNotFoundError, type PreflightCheck, type PreflightCheckError, type PreflightCheckErrorKind, type PreflightCheckStatus, type PreflightResult, type PresenceCapableBackend, PresenceDeclinedError, type PresenceOperation, type PresenceRequirementOptions, PresenceTimeoutError, REDACTED, RotationInProgressError, type RunDoctorOptions, type ScopedPreflightCheck, type SecretAccessor, type SecretBackend, SecretNotFoundError, type SecretTokenMap, type SetupChoice, SetupError, type SetupOptions, type SetupOptionsBase, type SetupQuestion, type SetupResult, type SignRequest, type SignResult, type SigningAlgorithm, type SigningBackend, SigningKeyAlreadyExistsError, SigningKeyNotFoundError, SigningNotSupportedError, type SigningPublicKey, TokenExpiredError, TokenRevokedError, type TrustTier, UnknownBackendTypeError, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, type VerifyRequest, defaultBackendType, getBackendCapabilities, getDefaultConfigDir, getPlatformDefaultConfigDir, isListableBackend, isPresenceCapableBackend, isSigningBackend, loadConfig, platformNativeBackendType, redactSecrets, runDoctor };
|
|
2159
|
+
export { AccessorConsumedError, AuthorizationDeniedError, type BackendCapabilities, type BackendConfig, type BackendFactory, BackendLockedError, BackendRegistry, type BackendSetupFactory, BackendUnavailableError, CapabilityToken, ConfigParseError, ConfigValidationError, DecryptionError, DeviceNotPresentError, ExecError, type ExecRequest, type ExecResult, ExecutableTrustRequiredError, type ExecutableTrustStatus, FetchError, type FetchRequest, FilesystemError, IdentityMismatchError, InvalidAlgorithmError, InvalidKeyMaterialError, InvalidTokenError, KeyRevokedError, KeyRotatedError, type KeyStatus, type ListableBackend, NotCapableError, type Platform, PluginNotFoundError, type PreflightCheck, type PreflightCheckError, type PreflightCheckErrorKind, type PreflightCheckStatus, type PreflightResult, type PresenceCapableBackend, PresenceDeclinedError, type PresenceOperation, type PresenceRequirementOptions, PresenceTimeoutError, REDACTED, RotationInProgressError, type RunDoctorOptions, type ScopedPreflightCheck, type SecretAccessor, type SecretBackend, SecretNotFoundError, type SecretTokenMap, type SetupChoice, SetupError, type SetupOptions, type SetupOptionsBase, type SetupQuestion, type SetupResult, type SignRequest, type SignResult, type SigningAlgorithm, type SigningBackend, SigningKeyAlreadyExistsError, SigningKeyNotFoundError, SigningNotSupportedError, type SigningPublicKey, TestDoubleMisuseError, TokenExpiredError, TokenRevokedError, type TrustTier, UnknownBackendTypeError, UsageLimitExceededError, type VaultConfig, VaultError, VaultKeeper, type VaultKeeperOptions, type VaultResponse, type VerifyRequest, defaultBackendType, getBackendCapabilities, getDefaultConfigDir, getPlatformDefaultConfigDir, isListableBackend, isPresenceCapableBackend, isSigningBackend, loadConfig, platformNativeBackendType, redactSecrets, runDoctor };
|
package/dist/index.js
CHANGED
|
@@ -448,6 +448,21 @@ var RotationInProgressError = class extends VaultError {
|
|
|
448
448
|
this.name = "RotationInProgressError";
|
|
449
449
|
}
|
|
450
450
|
};
|
|
451
|
+
var TestDoubleMisuseError = class extends VaultError {
|
|
452
|
+
/** The name of the test double class that refused to construct. */
|
|
453
|
+
doubleName;
|
|
454
|
+
/**
|
|
455
|
+
* The environment value (e.g. `process.env.NODE_ENV`) that triggered the
|
|
456
|
+
* refusal.
|
|
457
|
+
*/
|
|
458
|
+
detectedEnvironment;
|
|
459
|
+
constructor(message, doubleName, detectedEnvironment) {
|
|
460
|
+
super(message);
|
|
461
|
+
this.name = "TestDoubleMisuseError";
|
|
462
|
+
this.doubleName = doubleName;
|
|
463
|
+
this.detectedEnvironment = detectedEnvironment;
|
|
464
|
+
}
|
|
465
|
+
};
|
|
451
466
|
|
|
452
467
|
// src/backend/registry.ts
|
|
453
468
|
var BackendRegistry = class {
|
|
@@ -1366,13 +1381,19 @@ var DpapiBackend = class {
|
|
|
1366
1381
|
const entryPath = getEntryPath2(storageDir, id);
|
|
1367
1382
|
const script = [
|
|
1368
1383
|
"Add-Type -AssemblyName System.Security",
|
|
1369
|
-
|
|
1384
|
+
"$b64 = [Console]::In.ReadToEnd()",
|
|
1385
|
+
"$bytes = [System.Convert]::FromBase64String($b64.Trim())",
|
|
1370
1386
|
"$entropy = $null",
|
|
1371
1387
|
"$scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser",
|
|
1372
1388
|
"$encrypted = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $entropy, $scope)",
|
|
1373
1389
|
`[System.IO.File]::WriteAllBytes(${JSON.stringify(entryPath)}, $encrypted)`
|
|
1374
1390
|
].join("; ");
|
|
1375
|
-
|
|
1391
|
+
const secretBuf = Buffer.from(secret, "utf8");
|
|
1392
|
+
const stdinPayload = secretBuf.toString("base64");
|
|
1393
|
+
secretBuf.fill(0);
|
|
1394
|
+
await execCommand("powershell", ["-NoProfile", "-Command", script], {
|
|
1395
|
+
stdin: stdinPayload
|
|
1396
|
+
});
|
|
1376
1397
|
}
|
|
1377
1398
|
async retrieve(id) {
|
|
1378
1399
|
const storageDir = this.#storageDir;
|
|
@@ -1429,6 +1450,9 @@ var DpapiBackend = class {
|
|
|
1429
1450
|
// src/backend/secret-tool-backend.ts
|
|
1430
1451
|
var ATTRIBUTE_KEY = "vaultkeeper-id";
|
|
1431
1452
|
var LABEL_PREFIX = "vaultkeeper: ";
|
|
1453
|
+
function stripSecretToolTrailingNewline(stdout) {
|
|
1454
|
+
return stdout.endsWith("\n") ? stdout.slice(0, -1) : stdout;
|
|
1455
|
+
}
|
|
1432
1456
|
var SecretToolBackend = class {
|
|
1433
1457
|
type = "secret-tool";
|
|
1434
1458
|
displayName = "Linux Secret Service (secret-tool)";
|
|
@@ -1445,29 +1469,29 @@ var SecretToolBackend = class {
|
|
|
1445
1469
|
}
|
|
1446
1470
|
async store(id, secret) {
|
|
1447
1471
|
const label = `${LABEL_PREFIX}${id}`;
|
|
1448
|
-
await execCommand("secret-tool", ["store", "--label", label, ATTRIBUTE_KEY, id], {
|
|
1472
|
+
await execCommand("secret-tool", ["store", "--label", label, "--", ATTRIBUTE_KEY, id], {
|
|
1449
1473
|
stdin: secret
|
|
1450
1474
|
});
|
|
1451
1475
|
}
|
|
1452
1476
|
async retrieve(id) {
|
|
1453
|
-
const result = await execCommandFull("secret-tool", ["lookup", ATTRIBUTE_KEY, id]);
|
|
1454
|
-
if (result.exitCode !== 0
|
|
1477
|
+
const result = await execCommandFull("secret-tool", ["lookup", "--", ATTRIBUTE_KEY, id]);
|
|
1478
|
+
if (result.exitCode !== 0) {
|
|
1455
1479
|
throw new SecretNotFoundError(`Secret not found in Secret Service: ${id}`);
|
|
1456
1480
|
}
|
|
1457
|
-
return result.stdout
|
|
1481
|
+
return stripSecretToolTrailingNewline(result.stdout);
|
|
1458
1482
|
}
|
|
1459
1483
|
async delete(id) {
|
|
1460
|
-
const result = await execCommandFull("secret-tool", ["clear", ATTRIBUTE_KEY, id]);
|
|
1484
|
+
const result = await execCommandFull("secret-tool", ["clear", "--", ATTRIBUTE_KEY, id]);
|
|
1461
1485
|
if (result.exitCode !== 0) {
|
|
1462
1486
|
throw new SecretNotFoundError(`Secret not found in Secret Service: ${id}`);
|
|
1463
1487
|
}
|
|
1464
1488
|
}
|
|
1465
1489
|
async exists(id) {
|
|
1466
|
-
const result = await execCommandFull("secret-tool", ["lookup", ATTRIBUTE_KEY, id]);
|
|
1467
|
-
return result.exitCode === 0
|
|
1490
|
+
const result = await execCommandFull("secret-tool", ["lookup", "--", ATTRIBUTE_KEY, id]);
|
|
1491
|
+
return result.exitCode === 0;
|
|
1468
1492
|
}
|
|
1469
1493
|
async list() {
|
|
1470
|
-
const result = await execCommandFull("secret-tool", ["search", ATTRIBUTE_KEY, ""]);
|
|
1494
|
+
const result = await execCommandFull("secret-tool", ["search", "--", ATTRIBUTE_KEY, ""]);
|
|
1471
1495
|
if (result.exitCode !== 0) {
|
|
1472
1496
|
return [];
|
|
1473
1497
|
}
|
|
@@ -2925,11 +2949,16 @@ async function createToken(key, claims, options) {
|
|
|
2925
2949
|
function isObject2(value) {
|
|
2926
2950
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2927
2951
|
}
|
|
2952
|
+
function isLeasePresence(value) {
|
|
2953
|
+
if (!isObject2(value)) return false;
|
|
2954
|
+
const { op, at, method, backend } = value;
|
|
2955
|
+
return typeof op === "string" && typeof at === "number" && typeof method === "string" && typeof backend === "string";
|
|
2956
|
+
}
|
|
2928
2957
|
function parseVaultClaims(raw) {
|
|
2929
2958
|
if (!isObject2(raw)) {
|
|
2930
2959
|
return void 0;
|
|
2931
2960
|
}
|
|
2932
|
-
const { jti, exp, iat, sub, exe, use, tid, bkd, val, ref } = raw;
|
|
2961
|
+
const { jti, exp, iat, sub, exe, use, tid, bkd, val, ref, kty, kid, kgen, pres } = raw;
|
|
2933
2962
|
if (typeof jti !== "string") return void 0;
|
|
2934
2963
|
if (typeof exp !== "number") return void 0;
|
|
2935
2964
|
if (typeof iat !== "number") return void 0;
|
|
@@ -2937,10 +2966,29 @@ function parseVaultClaims(raw) {
|
|
|
2937
2966
|
if (typeof exe !== "string") return void 0;
|
|
2938
2967
|
if (use !== null && typeof use !== "number") return void 0;
|
|
2939
2968
|
if (tid !== 1 && tid !== 2 && tid !== 3) return void 0;
|
|
2940
|
-
if (typeof bkd !== "string") return void 0;
|
|
2941
|
-
if (typeof val !== "string") return void 0;
|
|
2969
|
+
if (bkd !== void 0 && typeof bkd !== "string") return void 0;
|
|
2970
|
+
if (val !== void 0 && typeof val !== "string") return void 0;
|
|
2942
2971
|
if (typeof ref !== "string") return void 0;
|
|
2943
|
-
|
|
2972
|
+
if (kty !== void 0 && kty !== "secret" && kty !== "signing-key") return void 0;
|
|
2973
|
+
if (kid !== void 0 && typeof kid !== "string") return void 0;
|
|
2974
|
+
if (kgen !== void 0 && typeof kgen !== "number") return void 0;
|
|
2975
|
+
if (pres !== void 0 && !isLeasePresence(pres)) return void 0;
|
|
2976
|
+
return {
|
|
2977
|
+
jti,
|
|
2978
|
+
exp,
|
|
2979
|
+
iat,
|
|
2980
|
+
sub,
|
|
2981
|
+
exe,
|
|
2982
|
+
use: use ?? null,
|
|
2983
|
+
tid,
|
|
2984
|
+
bkd,
|
|
2985
|
+
val,
|
|
2986
|
+
ref,
|
|
2987
|
+
kty,
|
|
2988
|
+
kid,
|
|
2989
|
+
kgen,
|
|
2990
|
+
pres
|
|
2991
|
+
};
|
|
2944
2992
|
}
|
|
2945
2993
|
async function decryptToken(key, jwe) {
|
|
2946
2994
|
let plaintext;
|
|
@@ -3021,15 +3069,44 @@ function validateClaims(claims, usedCount = 0) {
|
|
|
3021
3069
|
if (claims.exe.trim() === "") {
|
|
3022
3070
|
throw new VaultError("Invalid token: exe must not be empty");
|
|
3023
3071
|
}
|
|
3024
|
-
if (claims.bkd.trim() === "") {
|
|
3025
|
-
throw new VaultError("Invalid token: bkd must not be empty");
|
|
3026
|
-
}
|
|
3027
|
-
if (claims.val.trim() === "") {
|
|
3028
|
-
throw new VaultError("Invalid token: val must not be empty");
|
|
3029
|
-
}
|
|
3030
3072
|
if (claims.ref.trim() === "") {
|
|
3031
3073
|
throw new VaultError("Invalid token: ref must not be empty");
|
|
3032
3074
|
}
|
|
3075
|
+
switch (claims.kty) {
|
|
3076
|
+
case "signing-key": {
|
|
3077
|
+
if (claims.val !== void 0) {
|
|
3078
|
+
throw new VaultError("Invalid token: signing lease must not carry a val");
|
|
3079
|
+
}
|
|
3080
|
+
if (claims.kid === void 0 || claims.kid.trim() === "") {
|
|
3081
|
+
throw new VaultError("Invalid token: kid must not be empty");
|
|
3082
|
+
}
|
|
3083
|
+
if (claims.kgen === void 0) {
|
|
3084
|
+
throw new VaultError("Invalid token: kgen is required for a signing lease");
|
|
3085
|
+
}
|
|
3086
|
+
if (!Number.isSafeInteger(claims.kgen) || claims.kgen < 0) {
|
|
3087
|
+
throw new VaultError("Invalid token: kgen must be a non-negative integer");
|
|
3088
|
+
}
|
|
3089
|
+
break;
|
|
3090
|
+
}
|
|
3091
|
+
case "secret":
|
|
3092
|
+
case void 0: {
|
|
3093
|
+
if (claims.bkd === void 0 || claims.bkd.trim() === "") {
|
|
3094
|
+
throw new VaultError("Invalid token: bkd must not be empty");
|
|
3095
|
+
}
|
|
3096
|
+
if (claims.val === void 0 || claims.val.trim() === "") {
|
|
3097
|
+
throw new VaultError("Invalid token: val must not be empty");
|
|
3098
|
+
}
|
|
3099
|
+
if (claims.kid !== void 0 || claims.kgen !== void 0 || claims.pres !== void 0) {
|
|
3100
|
+
throw new VaultError(
|
|
3101
|
+
"Invalid token: secret claim must not carry signing-lease fields (kid/kgen/pres)"
|
|
3102
|
+
);
|
|
3103
|
+
}
|
|
3104
|
+
break;
|
|
3105
|
+
}
|
|
3106
|
+
default: {
|
|
3107
|
+
throw new VaultError(`Invalid token: unrecognized claim kind kty=${String(claims.kty)}`);
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3033
3110
|
if (claims.iat > claims.exp) {
|
|
3034
3111
|
throw new VaultError("Invalid token: iat must not be after exp");
|
|
3035
3112
|
}
|
|
@@ -4044,6 +4121,16 @@ var VaultKeeper = class _VaultKeeper {
|
|
|
4044
4121
|
"This capability token authorizes a signing key, not a secret \u2014 it cannot be read with getSecret(). Use sign() instead."
|
|
4045
4122
|
);
|
|
4046
4123
|
}
|
|
4124
|
+
if (claims.kty === "signing-key") {
|
|
4125
|
+
throw new AuthorizationDeniedError(
|
|
4126
|
+
"This capability token authorizes a signing key, not a secret \u2014 it cannot be read with getSecret(). Use sign() instead."
|
|
4127
|
+
);
|
|
4128
|
+
}
|
|
4129
|
+
if (claims.val === void 0) {
|
|
4130
|
+
throw new AuthorizationDeniedError(
|
|
4131
|
+
"This capability token does not carry a secret value \u2014 it is malformed or was not minted as a secret token."
|
|
4132
|
+
);
|
|
4133
|
+
}
|
|
4047
4134
|
return createSecretAccessor(claims.val);
|
|
4048
4135
|
}
|
|
4049
4136
|
/**
|
|
@@ -4386,7 +4473,7 @@ var VaultKeeper = class _VaultKeeper {
|
|
|
4386
4473
|
// ---------------------------------------------------------------------------
|
|
4387
4474
|
static #resolveSecrets(token) {
|
|
4388
4475
|
if (token instanceof CapabilityToken) {
|
|
4389
|
-
return _VaultKeeper.#
|
|
4476
|
+
return _VaultKeeper.#requireSecretValue(token);
|
|
4390
4477
|
}
|
|
4391
4478
|
const result = {};
|
|
4392
4479
|
for (const [name, t] of Object.entries(token)) {
|
|
@@ -4395,7 +4482,7 @@ var VaultKeeper = class _VaultKeeper {
|
|
|
4395
4482
|
`Invalid capability token for secret "${name}" \u2014 expected a CapabilityToken from authorize()`
|
|
4396
4483
|
);
|
|
4397
4484
|
}
|
|
4398
|
-
result[name] = _VaultKeeper.#
|
|
4485
|
+
result[name] = _VaultKeeper.#requireSecretValue(t);
|
|
4399
4486
|
}
|
|
4400
4487
|
return result;
|
|
4401
4488
|
}
|
|
@@ -4403,7 +4490,10 @@ var VaultKeeper = class _VaultKeeper {
|
|
|
4403
4490
|
* Resolve a token to its secret claims, rejecting a signing-key token.
|
|
4404
4491
|
*
|
|
4405
4492
|
* Defense in depth: a signing-key capability must never be injectable as a
|
|
4406
|
-
* secret through `fetch()`/`exec()`.
|
|
4493
|
+
* secret through `fetch()`/`exec()`. This rejects both the in-memory
|
|
4494
|
+
* signing-key token (`isSigningClaims`) and a JWE-based signing-key lease
|
|
4495
|
+
* (`kty: 'signing-key'`) — the two capability shapes are discriminated
|
|
4496
|
+
* differently but neither ever carries a secret value.
|
|
4407
4497
|
*/
|
|
4408
4498
|
static #requireSecretClaims(token) {
|
|
4409
4499
|
const claims = validateCapabilityToken(token);
|
|
@@ -4412,8 +4502,21 @@ var VaultKeeper = class _VaultKeeper {
|
|
|
4412
4502
|
"This capability token authorizes a signing key, not a secret \u2014 it cannot be injected into fetch() or exec()."
|
|
4413
4503
|
);
|
|
4414
4504
|
}
|
|
4505
|
+
if (claims.kty === "signing-key") {
|
|
4506
|
+
throw new AuthorizationDeniedError(
|
|
4507
|
+
"This capability token authorizes a signing-key lease, not a secret \u2014 it cannot be injected into fetch() or exec()."
|
|
4508
|
+
);
|
|
4509
|
+
}
|
|
4415
4510
|
return claims;
|
|
4416
4511
|
}
|
|
4512
|
+
/** Resolve a token to its secret value, rejecting a claims shape with no `val`. */
|
|
4513
|
+
static #requireSecretValue(token) {
|
|
4514
|
+
const claims = _VaultKeeper.#requireSecretClaims(token);
|
|
4515
|
+
if (claims.val === void 0 || claims.val.trim() === "") {
|
|
4516
|
+
throw new AuthorizationDeniedError("This capability token does not authorize a secret value.");
|
|
4517
|
+
}
|
|
4518
|
+
return claims.val;
|
|
4519
|
+
}
|
|
4417
4520
|
/**
|
|
4418
4521
|
* Validate a caller-supplied resource name. `kind` names the resource in the
|
|
4419
4522
|
* error so a signing-key caller is not told about a "secret".
|
|
@@ -4575,6 +4678,6 @@ var VaultKeeper = class _VaultKeeper {
|
|
|
4575
4678
|
}
|
|
4576
4679
|
};
|
|
4577
4680
|
|
|
4578
|
-
export { AccessorConsumedError, AuthorizationDeniedError, BackendLockedError, BackendRegistry, BackendUnavailableError, CapabilityToken, ConfigParseError, ConfigValidationError, DecryptionError, DeviceNotPresentError, ExecError, ExecutableTrustRequiredError, FetchError, FilesystemError, IdentityMismatchError, InvalidAlgorithmError, InvalidKeyMaterialError, InvalidTokenError, KeyRevokedError, KeyRotatedError, NotCapableError, PluginNotFoundError, PresenceDeclinedError, PresenceTimeoutError, REDACTED, RotationInProgressError, SecretNotFoundError, SetupError, SigningKeyAlreadyExistsError, SigningKeyNotFoundError, SigningNotSupportedError, TokenExpiredError, TokenRevokedError, UnknownBackendTypeError, UsageLimitExceededError, VaultError, VaultKeeper, defaultBackendType, getBackendCapabilities, getDefaultConfigDir, getPlatformDefaultConfigDir, isListableBackend, isPresenceCapableBackend, isSigningBackend, loadConfig, platformNativeBackendType, redactSecrets, runDoctor };
|
|
4681
|
+
export { AccessorConsumedError, AuthorizationDeniedError, BackendLockedError, BackendRegistry, BackendUnavailableError, CapabilityToken, ConfigParseError, ConfigValidationError, DecryptionError, DeviceNotPresentError, ExecError, ExecutableTrustRequiredError, FetchError, FilesystemError, IdentityMismatchError, InvalidAlgorithmError, InvalidKeyMaterialError, InvalidTokenError, KeyRevokedError, KeyRotatedError, NotCapableError, PluginNotFoundError, PresenceDeclinedError, PresenceTimeoutError, REDACTED, RotationInProgressError, SecretNotFoundError, SetupError, SigningKeyAlreadyExistsError, SigningKeyNotFoundError, SigningNotSupportedError, TestDoubleMisuseError, TokenExpiredError, TokenRevokedError, UnknownBackendTypeError, UsageLimitExceededError, VaultError, VaultKeeper, defaultBackendType, getBackendCapabilities, getDefaultConfigDir, getPlatformDefaultConfigDir, isListableBackend, isPresenceCapableBackend, isSigningBackend, loadConfig, platformNativeBackendType, redactSecrets, runDoctor };
|
|
4579
4682
|
//# sourceMappingURL=index.js.map
|
|
4580
4683
|
//# sourceMappingURL=index.js.map
|