@btravstack/keys 0.45.0 → 0.46.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 +3 -1
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +2 -1
- package/dist/{keys-DpvmIcWy.d.cts → keys-B_EdZt6c.d.cts} +2 -1
- package/dist/{keys-DpvmIcWy.d.mts → keys-B_EdZt6c.d.mts} +2 -1
- package/dist/kms.cjs +2 -1
- package/dist/kms.d.cts +1 -1
- package/dist/kms.d.mts +1 -1
- package/dist/kms.mjs +2 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -27,6 +27,8 @@ A port that seals a tenant's payloads under a key of that tenant's own, and
|
|
|
27
27
|
the composition that provides the keys:
|
|
28
28
|
|
|
29
29
|
```ts
|
|
30
|
+
import type { webcrypto } from "node:crypto";
|
|
31
|
+
|
|
30
32
|
import {
|
|
31
33
|
EnvelopeKeys,
|
|
32
34
|
deriveKey,
|
|
@@ -40,7 +42,7 @@ import { kmsKeys } from "@btravstack/keys/kms";
|
|
|
40
42
|
class PayloadKeys extends Port("ReadmePayloadKeys")<{
|
|
41
43
|
readonly key: (
|
|
42
44
|
generation: KeyGeneration,
|
|
43
|
-
) => AsyncResult<CryptoKey, KeyErased | KeysUnavailable | InvalidKeyPurpose>;
|
|
45
|
+
) => AsyncResult<webcrypto.CryptoKey, KeyErased | KeysUnavailable | InvalidKeyPurpose>;
|
|
44
46
|
}> {}
|
|
45
47
|
|
|
46
48
|
export const payloadKeys = Provider(PayloadKeys)({
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_keys = require("./keys-DtMnWJHq.cjs");
|
|
3
|
+
let node_crypto = require("node:crypto");
|
|
3
4
|
let unthrown = require("unthrown");
|
|
4
5
|
//#region src/derive.ts
|
|
5
6
|
/** A purpose whose `info` would be ambiguous: a segment outside the alphabet, or a version that is not a positive integer. */
|
|
@@ -24,7 +25,7 @@ const SEGMENT = /^[A-Za-z0-9._-]+$/;
|
|
|
24
25
|
* random 96-bit AES-GCM nonces never draw from one key. The salt is empty
|
|
25
26
|
* because the root is already uniformly random (RFC 5869, section 3.1).
|
|
26
27
|
*/
|
|
27
|
-
const deriveKey = (root, purpose, derived) => SEGMENT.test(purpose.namespace) && SEGMENT.test(purpose.purpose) && Number.isSafeInteger(purpose.version) && purpose.version > 0 ? (0, unthrown.fromSafePromise)(
|
|
28
|
+
const deriveKey = (root, purpose, derived) => SEGMENT.test(purpose.namespace) && SEGMENT.test(purpose.purpose) && Number.isSafeInteger(purpose.version) && purpose.version > 0 ? (0, unthrown.fromSafePromise)(node_crypto.webcrypto.subtle.deriveKey({
|
|
28
29
|
name: "HKDF",
|
|
29
30
|
hash: "SHA-256",
|
|
30
31
|
salt: /* @__PURE__ */ new Uint8Array(0),
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as KeysUnavailable, i as KeyGeneration, n as EnvelopeKeysService, r as KeyErased, t as EnvelopeKeys } from "./keys-
|
|
1
|
+
import { a as KeysUnavailable, i as KeyGeneration, n as EnvelopeKeysService, r as KeyErased, t as EnvelopeKeys } from "./keys-B_EdZt6c.cjs";
|
|
2
2
|
import { webcrypto } from "node:crypto";
|
|
3
3
|
import { AsyncResult } from "unthrown";
|
|
4
4
|
//#region src/derive.d.ts
|
|
@@ -44,6 +44,6 @@ export declare class InvalidKeyPurpose extends InvalidKeyPurpose_base<{
|
|
|
44
44
|
* random 96-bit AES-GCM nonces never draw from one key. The salt is empty
|
|
45
45
|
* because the root is already uniformly random (RFC 5869, section 3.1).
|
|
46
46
|
*/
|
|
47
|
-
export declare const deriveKey: (root: CryptoKey, purpose: KeyPurpose, derived: DerivedKey) => AsyncResult<CryptoKey, InvalidKeyPurpose>;
|
|
47
|
+
export declare const deriveKey: (root: webcrypto.CryptoKey, purpose: KeyPurpose, derived: DerivedKey) => AsyncResult<webcrypto.CryptoKey, InvalidKeyPurpose>;
|
|
48
48
|
//#endregion
|
|
49
49
|
export { type DerivedKey, EnvelopeKeys, type EnvelopeKeysService, KeyErased, type KeyGeneration, type KeyPurpose, KeysUnavailable };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as KeysUnavailable, i as KeyGeneration, n as EnvelopeKeysService, r as KeyErased, t as EnvelopeKeys } from "./keys-
|
|
2
|
-
import { AsyncResult } from "unthrown";
|
|
1
|
+
import { a as KeysUnavailable, i as KeyGeneration, n as EnvelopeKeysService, r as KeyErased, t as EnvelopeKeys } from "./keys-B_EdZt6c.mjs";
|
|
3
2
|
import { webcrypto } from "node:crypto";
|
|
3
|
+
import { AsyncResult } from "unthrown";
|
|
4
4
|
//#region src/derive.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* What a derived key is for, spelled into HKDF's `info` as
|
|
@@ -44,6 +44,6 @@ export declare class InvalidKeyPurpose extends InvalidKeyPurpose_base<{
|
|
|
44
44
|
* random 96-bit AES-GCM nonces never draw from one key. The salt is empty
|
|
45
45
|
* because the root is already uniformly random (RFC 5869, section 3.1).
|
|
46
46
|
*/
|
|
47
|
-
export declare const deriveKey: (root: CryptoKey, purpose: KeyPurpose, derived: DerivedKey) => AsyncResult<CryptoKey, InvalidKeyPurpose>;
|
|
47
|
+
export declare const deriveKey: (root: webcrypto.CryptoKey, purpose: KeyPurpose, derived: DerivedKey) => AsyncResult<webcrypto.CryptoKey, InvalidKeyPurpose>;
|
|
48
48
|
//#endregion
|
|
49
49
|
export { type DerivedKey, EnvelopeKeys, type EnvelopeKeysService, KeyErased, type KeyGeneration, type KeyPurpose, KeysUnavailable };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { n as KeyErased, r as KeysUnavailable, t as EnvelopeKeys } from "./keys-CGbVjuu3.mjs";
|
|
2
|
+
import { webcrypto } from "node:crypto";
|
|
2
3
|
import { ErrAsync, TaggedError, fromSafePromise } from "unthrown";
|
|
3
4
|
//#region src/derive.ts
|
|
4
5
|
/** A purpose whose `info` would be ambiguous: a segment outside the alphabet, or a version that is not a positive integer. */
|
|
@@ -23,7 +24,7 @@ const SEGMENT = /^[A-Za-z0-9._-]+$/;
|
|
|
23
24
|
* random 96-bit AES-GCM nonces never draw from one key. The salt is empty
|
|
24
25
|
* because the root is already uniformly random (RFC 5869, section 3.1).
|
|
25
26
|
*/
|
|
26
|
-
const deriveKey = (root, purpose, derived) => SEGMENT.test(purpose.namespace) && SEGMENT.test(purpose.purpose) && Number.isSafeInteger(purpose.version) && purpose.version > 0 ? fromSafePromise(
|
|
27
|
+
const deriveKey = (root, purpose, derived) => SEGMENT.test(purpose.namespace) && SEGMENT.test(purpose.purpose) && Number.isSafeInteger(purpose.version) && purpose.version > 0 ? fromSafePromise(webcrypto.subtle.deriveKey({
|
|
27
28
|
name: "HKDF",
|
|
28
29
|
hash: "SHA-256",
|
|
29
30
|
salt: /* @__PURE__ */ new Uint8Array(0),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { webcrypto } from "node:crypto";
|
|
1
2
|
import { AsyncResult } from "unthrown";
|
|
2
3
|
//#region src/keys.d.ts
|
|
3
4
|
/**
|
|
@@ -50,7 +51,7 @@ type EnvelopeKeysService = {
|
|
|
50
51
|
* key, to derive a key per purpose from with `deriveKey`. Kept for the
|
|
51
52
|
* cache's TTL; callers asking while it is being unwrapped share one request.
|
|
52
53
|
*/
|
|
53
|
-
readonly rootKey: (generation: KeyGeneration) => AsyncResult<CryptoKey, KeyErased | KeysUnavailable>;
|
|
54
|
+
readonly rootKey: (generation: KeyGeneration) => AsyncResult<webcrypto.CryptoKey, KeyErased | KeysUnavailable>;
|
|
54
55
|
/**
|
|
55
56
|
* A new generation under the owner's key, for the application to keep.
|
|
56
57
|
* Rotation is provisioning another key id; the old generations stay
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { webcrypto } from "node:crypto";
|
|
1
2
|
import { AsyncResult } from "unthrown";
|
|
2
3
|
//#region src/keys.d.ts
|
|
3
4
|
/**
|
|
@@ -50,7 +51,7 @@ type EnvelopeKeysService = {
|
|
|
50
51
|
* key, to derive a key per purpose from with `deriveKey`. Kept for the
|
|
51
52
|
* cache's TTL; callers asking while it is being unwrapped share one request.
|
|
52
53
|
*/
|
|
53
|
-
readonly rootKey: (generation: KeyGeneration) => AsyncResult<CryptoKey, KeyErased | KeysUnavailable>;
|
|
54
|
+
readonly rootKey: (generation: KeyGeneration) => AsyncResult<webcrypto.CryptoKey, KeyErased | KeysUnavailable>;
|
|
54
55
|
/**
|
|
55
56
|
* A new generation under the owner's key, for the application to keep.
|
|
56
57
|
* Rotation is provisioning another key id; the old generations stay
|
package/dist/kms.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_keys = require("./keys-DtMnWJHq.cjs");
|
|
3
|
+
let node_crypto = require("node:crypto");
|
|
3
4
|
let unthrown = require("unthrown");
|
|
4
5
|
let _btravstack_di = require("@btravstack/di");
|
|
5
6
|
let _aws_sdk_client_kms = require("@aws-sdk/client-kms");
|
|
@@ -134,7 +135,7 @@ const kmsEnvelopeKeys = (client, config, observers, clock) => {
|
|
|
134
135
|
}
|
|
135
136
|
}))).flatMap(({ Plaintext }) => {
|
|
136
137
|
const plaintext = Plaintext;
|
|
137
|
-
return (0, unthrown.fromSafePromise)(
|
|
138
|
+
return (0, unthrown.fromSafePromise)(node_crypto.webcrypto.subtle.importKey("raw", plaintext, "HKDF", false, ["deriveKey", "deriveBits"]).finally(() => plaintext.fill(0)));
|
|
138
139
|
})).tap((root) => {
|
|
139
140
|
inFlight.delete(entry);
|
|
140
141
|
const now = clock.now();
|
package/dist/kms.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as EnvelopeKeys } from "./keys-
|
|
1
|
+
import { t as EnvelopeKeys } from "./keys-B_EdZt6c.cjs";
|
|
2
2
|
import { ConfigInvalid, EnvReading } from "@btravstack/config";
|
|
3
3
|
import { Clock } from "@btravstack/core";
|
|
4
4
|
import { Module, Scope } from "@btravstack/di";
|
package/dist/kms.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as EnvelopeKeys } from "./keys-
|
|
1
|
+
import { t as EnvelopeKeys } from "./keys-B_EdZt6c.mjs";
|
|
2
2
|
import { Module, Scope } from "@btravstack/di";
|
|
3
3
|
import { ConfigInvalid, EnvReading } from "@btravstack/config";
|
|
4
4
|
import { Clock } from "@btravstack/core";
|
package/dist/kms.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { n as KeyErased, r as KeysUnavailable, t as EnvelopeKeys } from "./keys-CGbVjuu3.mjs";
|
|
2
|
+
import { webcrypto } from "node:crypto";
|
|
2
3
|
import { Err, Ok, OkAsync, P, fromPromise, fromSafePromise } from "unthrown";
|
|
3
4
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
4
5
|
import { DecryptCommand, DescribeKeyCommand, GenerateDataKeyWithoutPlaintextCommand, KMSClient, ScheduleKeyDeletionCommand } from "@aws-sdk/client-kms";
|
|
@@ -133,7 +134,7 @@ const kmsEnvelopeKeys = (client, config, observers, clock) => {
|
|
|
133
134
|
}
|
|
134
135
|
}))).flatMap(({ Plaintext }) => {
|
|
135
136
|
const plaintext = Plaintext;
|
|
136
|
-
return fromSafePromise(
|
|
137
|
+
return fromSafePromise(webcrypto.subtle.importKey("raw", plaintext, "HKDF", false, ["deriveKey", "deriveBits"]).finally(() => plaintext.fill(0)));
|
|
137
138
|
})).tap((root) => {
|
|
138
139
|
inFlight.delete(entry);
|
|
139
140
|
const now = clock.now();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/keys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "An EnvelopeKeys port for @btravstack/core: per-owner root keys wrapped by an AWS KMS key of that owner, unwrapped in memory and cached for a TTL, erased with one key deletion, and an HKDF helper giving each purpose its own key",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"crypto-shredding",
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@aws-sdk/client-kms": "3.1152.0",
|
|
58
|
-
"@btravstack/config": "0.
|
|
59
|
-
"@btravstack/core": "0.
|
|
60
|
-
"@btravstack/di": "0.
|
|
58
|
+
"@btravstack/config": "0.46.0",
|
|
59
|
+
"@btravstack/core": "0.46.0",
|
|
60
|
+
"@btravstack/di": "0.46.0",
|
|
61
61
|
"@btravstack/internal-test-infra": "0.0.0",
|
|
62
|
-
"@btravstack/testing": "0.
|
|
62
|
+
"@btravstack/testing": "0.46.0",
|
|
63
63
|
"@btravstack/tsconfig": "0.4.0",
|
|
64
64
|
"@types/node": "26.6.5",
|
|
65
65
|
"@unthrown/vitest": "5.12.1",
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"@aws-sdk/client-kms": "^3.1000.0",
|
|
74
|
-
"@btravstack/config": "^0.
|
|
75
|
-
"@btravstack/core": "^0.
|
|
76
|
-
"@btravstack/di": "^0.
|
|
74
|
+
"@btravstack/config": "^0.46.0",
|
|
75
|
+
"@btravstack/core": "^0.46.0",
|
|
76
|
+
"@btravstack/di": "^0.46.0",
|
|
77
77
|
"unthrown": "^5.0.0"
|
|
78
78
|
},
|
|
79
79
|
"peerDependenciesMeta": {
|