@nodetool-ai/security 0.7.0-rc.23 → 0.8.1

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 ADDED
@@ -0,0 +1,42 @@
1
+ # @nodetool-ai/security
2
+
3
+ Secret storage and encryption for [NodeTool](https://nodetool.ai) — master-key management and crypto helpers.
4
+
5
+ This package owns encryption at rest for the NodeTool backend. It derives and stores a master key (OS keychain via keytar or environment variable) and encrypts and decrypts secrets, including Fernet-compatible payloads.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @nodetool-ai/security
11
+ ```
12
+
13
+ ## Exported symbols
14
+
15
+ | Symbol | Kind | Description |
16
+ | --- | --- | --- |
17
+ | `generateMasterKey` | function | Generate a new random master key |
18
+ | `deriveKey` | function | Derive an encryption key from a passphrase |
19
+ | `encrypt` / `decrypt` | function | Encrypt and decrypt payloads with the master key |
20
+ | `encryptFernet` / `decryptFernet` | function | Fernet-compatible encryption for cross-runtime secrets |
21
+ | `isValidMasterKey` | function | Validate a master-key string |
22
+ | `getMasterKey` / `initMasterKey` | function | Read or initialize the active master key |
23
+ | `setMasterKey` / `setMasterKeyPersistent` / `deleteMasterKey` | function | Set (optionally persist to keychain) or delete the master key |
24
+ | `clearMasterKeyCache` | function | Clear the in-memory key cache |
25
+ | `isUsingEnvKey` | function | Report whether the env var supplies the key |
26
+ | `setKeytarLoader` / `resetKeytarLoader` | function | Override the keytar loader (for tests) |
27
+ | `KeychainAccessError` | class | Error thrown when the OS keychain is unreachable |
28
+
29
+ ## Usage
30
+
31
+ ```ts
32
+ import { initMasterKey, encrypt, decrypt } from "@nodetool-ai/security";
33
+
34
+ await initMasterKey();
35
+ const sealed = encrypt("sk-secret-value");
36
+ const plain = decrypt(sealed);
37
+ ```
38
+
39
+ ## Links
40
+
41
+ - [NodeTool](https://nodetool.ai)
42
+ - [GitHub](https://github.com/nodetool-ai/nodetool)
@@ -0,0 +1 @@
1
+ 2026-09-28T09:19:03.160Z
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsBH;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAcR;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,MAAM,CA8BR;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,MAAM,CAiDR;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CA+CR;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAOT"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAInE;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAeR;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,MAAM,CA+BR;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,MAAM,CAoDR;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAiDR;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAOT"}
package/dist/crypto.js CHANGED
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import { randomBytes, pbkdf2Sync, createCipheriv, createDecipheriv, createHmac, timingSafeEqual } from "node:crypto";
11
11
  import { createLogger } from "@nodetool-ai/config";
12
+ // Stryker disable next-line StringLiteral: logger name is diagnostic, not behavior
12
13
  const log = createLogger("nodetool.security.crypto");
13
14
  // Fernet token version byte
14
15
  const FERNET_VERSION = 0x80;
@@ -35,6 +36,7 @@ export function generateMasterKey() {
35
36
  * @returns A 32-byte derived key as a Buffer.
36
37
  */
37
38
  export function deriveKey(masterKey, userId) {
39
+ // Stryker disable next-line StringLiteral: encoding arg — Node decodes "" as utf-8, so this mutant is behaviorally equivalent
38
40
  const salt = Buffer.from(userId, "utf-8");
39
41
  return pbkdf2Sync(masterKey, salt, PBKDF2_ITERATIONS, KEY_LENGTH, "sha256");
40
42
  }
@@ -53,6 +55,7 @@ export function encrypt(masterKey, userId, plaintext) {
53
55
  const iv = randomBytes(IV_LENGTH);
54
56
  const cipher = createCipheriv("aes-256-gcm", key, iv);
55
57
  const encrypted = Buffer.concat([
58
+ // Stryker disable next-line StringLiteral: encoding arg — Node decodes "" as utf-8, so this mutant is behaviorally equivalent
56
59
  cipher.update(plaintext, "utf-8"),
57
60
  cipher.final()
58
61
  ]);
@@ -89,6 +92,7 @@ export function decrypt(masterKey, userId, encryptedValue) {
89
92
  return decrypted.toString("utf-8");
90
93
  }
91
94
  catch (err) {
95
+ // Stryker disable next-line all: diagnostic log, not behavior
92
96
  log.debug("AES-GCM decryption failed (may fall back to Fernet)", {
93
97
  error: String(err)
94
98
  });
@@ -107,7 +111,9 @@ export function decrypt(masterKey, userId, encryptedValue) {
107
111
  */
108
112
  export function decryptFernet(masterKey, userId, encryptedValue) {
109
113
  // Python uses master_key.encode() — the UTF-8 bytes of the base64 string itself as PBKDF2 password
114
+ // Stryker disable next-line StringLiteral: encoding arg — Node decodes "" as utf-8, so this mutant is behaviorally equivalent
110
115
  const masterKeyBytes = Buffer.from(masterKey, "utf-8");
116
+ // Stryker disable next-line StringLiteral: encoding arg — Node decodes "" as utf-8, so this mutant is behaviorally equivalent
111
117
  const salt = Buffer.from(userId, "utf-8");
112
118
  const derived = pbkdf2Sync(masterKeyBytes, salt, PBKDF2_ITERATIONS, 32, "sha256");
113
119
  // Fernet splits the 32-byte derived key: first 16 = HMAC key, last 16 = AES-128 key
@@ -115,7 +121,9 @@ export function decryptFernet(masterKey, userId, encryptedValue) {
115
121
  const aesKey = derived.subarray(16, 32);
116
122
  // Decode Fernet token from base64url
117
123
  const b64token = encryptedValue.replace(/-/g, "+").replace(/_/g, "/");
118
- const token = Buffer.from(b64token + "=".repeat((4 - (b64token.length % 4)) % 4), "base64");
124
+ const token = Buffer.from(
125
+ // Stryker disable next-line StringLiteral,ArithmeticOperator: re-padding is a no-op — Node's base64 decoder ignores +/- padding, so these mutants are equivalent
126
+ b64token + "=".repeat((4 - (b64token.length % 4)) % 4), "base64");
119
127
  // Token layout: version(1) + timestamp(8) + iv(16) + ciphertext(N) + hmac(32)
120
128
  if (token.length < 1 + 8 + 16 + 32) {
121
129
  throw new Error("Invalid Fernet token: too short");
@@ -151,7 +159,9 @@ export function decryptFernet(masterKey, userId, encryptedValue) {
151
159
  * @param plaintext - The plaintext to encrypt.
152
160
  */
153
161
  export function encryptFernet(masterKey, userId, plaintext) {
162
+ // Stryker disable next-line StringLiteral: encoding arg — Node decodes "" as utf-8, so this mutant is behaviorally equivalent
154
163
  const masterKeyBytes = Buffer.from(masterKey, "utf-8");
164
+ // Stryker disable next-line StringLiteral: encoding arg — Node decodes "" as utf-8, so this mutant is behaviorally equivalent
155
165
  const salt = Buffer.from(userId, "utf-8");
156
166
  const derived = pbkdf2Sync(masterKeyBytes, salt, PBKDF2_ITERATIONS, 32, "sha256");
157
167
  const hmacKey = derived.subarray(0, 16);
@@ -162,6 +172,7 @@ export function encryptFernet(masterKey, userId, plaintext) {
162
172
  const tsBuf = Buffer.alloc(8);
163
173
  tsBuf.writeBigUInt64BE(timestamp);
164
174
  // Pad plaintext to 16-byte boundary (PKCS7)
175
+ // Stryker disable next-line StringLiteral: encoding arg — Node decodes "" as utf-8, so this mutant is behaviorally equivalent
165
176
  const plaintextBuf = Buffer.from(plaintext, "utf-8");
166
177
  const padLen = 16 - (plaintextBuf.length % 16);
167
178
  const padded = Buffer.concat([plaintextBuf, Buffer.alloc(padLen, padLen)]);
@@ -178,12 +189,11 @@ export function encryptFernet(masterKey, userId, plaintext) {
178
189
  // HMAC-SHA256 over body
179
190
  const hmac = createHmac("sha256", hmacKey).update(body).digest();
180
191
  const token = Buffer.concat([body, hmac]);
181
- // Encode as base64url (no padding)
182
- return token
183
- .toString("base64")
184
- .replace(/\+/g, "-")
185
- .replace(/\//g, "_")
186
- .replace(/=/g, "");
192
+ // Encode as base64url *with* padding. Python's cryptography.Fernet decodes
193
+ // tokens with base64.urlsafe_b64decode, which rejects unpadded input
194
+ // ("Incorrect padding" -> InvalidToken), so the "=" padding must be kept for
195
+ // cross-runtime compatibility.
196
+ return token.toString("base64").replace(/\+/g, "-").replace(/\//g, "_");
187
197
  }
188
198
  /**
189
199
  * Check if a master key is valid by attempting to decrypt a test value.
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,WAAW,EACX,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,GAAG,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAAC;AAErD,4BAA4B;AAC5B,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAClC,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC,uBAAuB;AAC9C,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC,kBAAkB;AACxC,MAAM,eAAe,GAAG,EAAE,CAAC,CAAC,WAAW;AAEvC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAc;IACzD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,OAAO,CACrB,SAAiB,EACjB,MAAc,EACd,SAAiB;IAEjB,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAEtD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC;QACjC,MAAM,CAAC,KAAK,EAAE;KACf,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAEpC,uDAAuD;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CACrB,SAAiB,EACjB,MAAc,EACd,cAAsB;IAEtB,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IAErD,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAChC,SAAS,EACT,MAAM,CAAC,MAAM,GAAG,eAAe,CAChC,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QAC1D,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAE7B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAC9B,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;YAC3B,QAAQ,CAAC,KAAK,EAAE;SACjB,CAAC,CAAC;QACH,OAAO,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,qDAAqD,EAAE;YAC/D,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;SACnB,CAAC,CAAC;QACH,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAiB,EACjB,MAAc,EACd,cAAsB;IAEtB,mGAAmG;IACnG,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,UAAU,CACxB,cAAc,EACd,IAAI,EACJ,iBAAiB,EACjB,EAAE,EACF,QAAQ,CACT,CAAC;IAEF,oFAAoF;IACpF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAExC,qCAAqC;IACrC,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CACvB,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACtD,QAAQ,CACT,CAAC;IAEF,8EAA8E;IAC9E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAErC,qBAAqB;IACrB,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;IACzE,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;QAC9B,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE;KACjB,CAAC,CAAC;IACH,OAAO,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAiB,EACjB,MAAc,EACd,SAAiB;IAEjB,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,UAAU,CACxB,cAAc,EACd,IAAI,EACJ,iBAAiB,EACjB,EAAE,EACF,QAAQ,CACT,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAExC,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC3B,sDAAsD;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9B,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAElC,4CAA4C;IAC5C,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAE3E,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAE1E,8DAA8D;IAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,CAAC;QAC7B,KAAK;QACL,EAAE;QACF,UAAU;KACX,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;IAEjE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1C,mCAAmC;IACnC,OAAO,KAAK;SACT,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,kBAA0B,EAC1B,MAAc;IAEd,IAAI,CAAC;QACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export { generateMasterKey, deriveKey, encrypt, decrypt, decryptFernet, encryptFernet, isValidMasterKey } from "./crypto.js";
2
- export { getMasterKey, initMasterKey, clearMasterKeyCache, setMasterKey, setMasterKeyPersistent, deleteMasterKey, isUsingEnvKey, isUsingAwsKey, setKeytarLoader, resetKeytarLoader, KeychainAccessError } from "./master-key.js";
3
- export { runStartupChecks, type StartupCheckResult } from "./startup-checks.js";
2
+ export { getMasterKey, initMasterKey, clearMasterKeyCache, setMasterKey, setMasterKeyPersistent, deleteMasterKey, isUsingEnvKey, setKeytarLoader, resetKeytarLoader, KeychainAccessError } from "./master-key.js";
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,OAAO,EACP,OAAO,EACP,aAAa,EACb,aAAa,EACb,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,OAAO,EACP,OAAO,EACP,aAAa,EACb,aAAa,EACb,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
1
  export { generateMasterKey, deriveKey, encrypt, decrypt, decryptFernet, encryptFernet, isValidMasterKey } from "./crypto.js";
2
- export { getMasterKey, initMasterKey, clearMasterKeyCache, setMasterKey, setMasterKeyPersistent, deleteMasterKey, isUsingEnvKey, isUsingAwsKey, setKeytarLoader, resetKeytarLoader, KeychainAccessError } from "./master-key.js";
3
- export { runStartupChecks } from "./startup-checks.js";
2
+ export { getMasterKey, initMasterKey, clearMasterKeyCache, setMasterKey, setMasterKeyPersistent, deleteMasterKey, isUsingEnvKey, setKeytarLoader, resetKeytarLoader, KeychainAccessError } from "./master-key.js";
4
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,OAAO,EACP,OAAO,EACP,aAAa,EACb,aAAa,EACb,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAA2B,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,OAAO,EACP,OAAO,EACP,aAAa,EACb,aAAa,EACb,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC"}
@@ -1,15 +1,13 @@
1
1
  /**
2
- * Master key management with keychain and AWS Secrets Manager support.
2
+ * Master key management with keychain support.
3
3
  *
4
4
  * This module manages the master encryption key for secrets, storing it securely
5
- * in the system keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
6
- * or AWS Secrets Manager.
5
+ * in the system keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service).
7
6
  *
8
7
  * Key sources (in order of precedence):
9
8
  * 1. SECRETS_MASTER_KEY environment variable
10
- * 2. AWS Secrets Manager (if AWS_SECRETS_MASTER_KEY_NAME env var set)
11
- * 3. System keychain via keytar
12
- * 4. Auto-generated key (persisted to keychain when available)
9
+ * 2. System keychain via keytar
10
+ * 3. Auto-generated key (persisted to keychain when available)
13
11
  *
14
12
  * NOTE on encryption compatibility: TS uses AES-256-GCM while Python uses Fernet.
15
13
  * Secrets encrypted in one runtime cannot be decrypted in the other.
@@ -41,27 +39,32 @@ export declare function resetKeytarLoader(): void;
41
39
  * Get the master encryption key (synchronous).
42
40
  *
43
41
  * Checks sources in order:
44
- * 1. Cached key (if previously retrieved, e.g. via initMasterKey)
45
- * 2. SECRETS_MASTER_KEY environment variable
46
- * 3. Auto-generates a new key (will not persist unless initMasterKey was called)
42
+ * 1. Cached key (set previously by initMasterKey, setMasterKey, or a prior
43
+ * getMasterKey hit on SECRETS_MASTER_KEY).
44
+ * 2. SECRETS_MASTER_KEY environment variable.
47
45
  *
48
- * For full resolution including keychain and AWS, call initMasterKey() once at startup.
46
+ * Throws if neither is available. Callers MUST call {@link initMasterKey}
47
+ * once at process startup (which loads from keychain / env and
48
+ * persists a fresh key on first run) before the first sync access.
49
+ * Auto-generating an ephemeral key here would silently encrypt secrets
50
+ * with a value that disappears on exit — making them undecryptable on
51
+ * the next launch — so we surface the missing-init explicitly instead.
49
52
  *
50
53
  * @returns The master key as a base64-encoded string.
54
+ * @throws If the key has not been initialized.
51
55
  */
52
56
  export declare function getMasterKey(): string;
53
57
  /**
54
58
  * Initialize the master key from all available sources (async).
55
59
  *
56
60
  * Should be called once at application startup to resolve the master key
57
- * from keychain or AWS Secrets Manager. After this call, getMasterKey()
58
- * will return the resolved key synchronously.
61
+ * from the keychain. After this call, getMasterKey() will return the
62
+ * resolved key synchronously.
59
63
  *
60
64
  * Resolution order:
61
65
  * 1. SECRETS_MASTER_KEY environment variable
62
- * 2. AWS Secrets Manager (if AWS_SECRETS_MASTER_KEY_NAME is set)
63
- * 3. System keychain via keytar
64
- * 4. Auto-generate and persist to keychain
66
+ * 2. System keychain via keytar
67
+ * 3. Auto-generate and persist to keychain
65
68
  *
66
69
  * @returns The master key as a base64-encoded string.
67
70
  */
@@ -70,7 +73,7 @@ export declare function initMasterKey(): Promise<string>;
70
73
  * Clear the cached master key.
71
74
  *
72
75
  * Forces the next call to getMasterKey() or initMasterKey() to
73
- * re-read from environment, AWS, or keychain.
76
+ * re-read from environment or keychain.
74
77
  */
75
78
  export declare function clearMasterKeyCache(): void;
76
79
  /**
@@ -101,11 +104,5 @@ export declare function deleteMasterKey(): Promise<boolean>;
101
104
  * @returns True if SECRETS_MASTER_KEY environment variable is set.
102
105
  */
103
106
  export declare function isUsingEnvKey(): boolean;
104
- /**
105
- * Check if the master key should be sourced from AWS Secrets Manager.
106
- *
107
- * @returns True if AWS_SECRETS_MASTER_KEY_NAME environment variable is set.
108
- */
109
- export declare function isUsingAwsKey(): boolean;
110
107
  export {};
111
108
  //# sourceMappingURL=master-key.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"master-key.d.ts","sourceRoot":"","sources":["../src/master-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAgBH,uDAAuD;AACvD,UAAU,YAAY;IACpB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtE,WAAW,CACT,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAkCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAG9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAiCD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAkBrC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAuDrD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7E;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAQxD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
1
+ {"version":3,"file":"master-key.d.ts","sourceRoot":"","sources":["../src/master-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,uDAAuD;AACvD,UAAU,YAAY;IACpB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtE,WAAW,CACT,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAoCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAG9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAmBrC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAmBrD;AA0DD;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7E;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAQxD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
@@ -1,27 +1,27 @@
1
1
  /**
2
- * Master key management with keychain and AWS Secrets Manager support.
2
+ * Master key management with keychain support.
3
3
  *
4
4
  * This module manages the master encryption key for secrets, storing it securely
5
- * in the system keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
6
- * or AWS Secrets Manager.
5
+ * in the system keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service).
7
6
  *
8
7
  * Key sources (in order of precedence):
9
8
  * 1. SECRETS_MASTER_KEY environment variable
10
- * 2. AWS Secrets Manager (if AWS_SECRETS_MASTER_KEY_NAME env var set)
11
- * 3. System keychain via keytar
12
- * 4. Auto-generated key (persisted to keychain when available)
9
+ * 2. System keychain via keytar
10
+ * 3. Auto-generated key (persisted to keychain when available)
13
11
  *
14
12
  * NOTE on encryption compatibility: TS uses AES-256-GCM while Python uses Fernet.
15
13
  * Secrets encrypted in one runtime cannot be decrypted in the other.
16
14
  * New secrets must be created via the appropriate runtime's endpoints.
17
15
  */
18
- import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
19
16
  import { generateMasterKey } from "./crypto.js";
20
17
  import { createLogger } from "@nodetool-ai/config";
18
+ // Stryker disable next-line StringLiteral: logger name is diagnostic, not behavior
21
19
  const log = createLogger("nodetool.security.master-key");
22
20
  const KEYRING_SERVICE = "nodetool";
23
21
  const KEYRING_ACCOUNT = "secrets_master_key";
24
22
  let cachedMasterKey = null;
23
+ /** In-flight resolution promise, used to de-duplicate concurrent first-run inits. */
24
+ let initInFlight = null;
25
25
  /**
26
26
  * Thrown when the system keychain cannot be accessed. Callers can detect this
27
27
  * specifically (vs other startup failures) to decide whether re-prompting the
@@ -39,6 +39,7 @@ function keychainAccessError(message) {
39
39
  /** Lazy-load keytar. Keychain failures are fatal: no generated fallback key. */
40
40
  let _keytarResolved = null;
41
41
  async function loadKeytar() {
42
+ // Stryker disable next-line ConditionalExpression,BlockStatement: cache fast-path — re-importing yields the same module, so this mutant is behaviorally equivalent
42
43
  if (_keytarResolved) {
43
44
  return _keytarResolved;
44
45
  }
@@ -49,10 +50,11 @@ async function loadKeytar() {
49
50
  }
50
51
  catch (err) {
51
52
  const message = err instanceof Error ? err.message : String(err);
53
+ // Stryker disable all: diagnostic log, not behavior
52
54
  log.error("keytar native module failed to load. For headless deployments " +
53
55
  "(Docker, CI, Linux servers without libsecret) set the SECRETS_MASTER_KEY " +
54
- "environment variable to a base64-encoded 32-byte key, or set " +
55
- "AWS_SECRETS_MASTER_KEY_NAME to source the key from AWS Secrets Manager.", { error: message });
56
+ "environment variable to a base64-encoded 32-byte key.", { error: message });
57
+ // Stryker restore all
56
58
  throw keychainAccessError(`Unable to load system keychain backend: ${message}`);
57
59
  }
58
60
  }
@@ -72,104 +74,97 @@ export function resetKeytarLoader() {
72
74
  _keytar = null;
73
75
  _keytarResolved = null;
74
76
  }
75
- /**
76
- * Retrieve master key from AWS Secrets Manager.
77
- *
78
- * Only attempted if AWS_SECRETS_MASTER_KEY_NAME environment variable is set.
79
- */
80
- async function getFromAwsSecrets(secretName) {
81
- try {
82
- const region = process.env["AWS_REGION"] ?? "us-east-1";
83
- const client = new SecretsManagerClient({ region });
84
- const response = await client.send(new GetSecretValueCommand({ SecretId: secretName }));
85
- if (response.SecretString) {
86
- return response.SecretString;
87
- }
88
- if (response.SecretBinary) {
89
- return Buffer.from(response.SecretBinary).toString("utf-8");
90
- }
91
- return null;
92
- }
93
- catch (err) {
94
- const message = err instanceof Error ? err.message : String(err);
95
- log.warn("Master key source failed, trying next", {
96
- source: "aws",
97
- error: message
98
- });
99
- return null;
100
- }
101
- }
102
77
  /**
103
78
  * Get the master encryption key (synchronous).
104
79
  *
105
80
  * Checks sources in order:
106
- * 1. Cached key (if previously retrieved, e.g. via initMasterKey)
107
- * 2. SECRETS_MASTER_KEY environment variable
108
- * 3. Auto-generates a new key (will not persist unless initMasterKey was called)
81
+ * 1. Cached key (set previously by initMasterKey, setMasterKey, or a prior
82
+ * getMasterKey hit on SECRETS_MASTER_KEY).
83
+ * 2. SECRETS_MASTER_KEY environment variable.
109
84
  *
110
- * For full resolution including keychain and AWS, call initMasterKey() once at startup.
85
+ * Throws if neither is available. Callers MUST call {@link initMasterKey}
86
+ * once at process startup (which loads from keychain / env and
87
+ * persists a fresh key on first run) before the first sync access.
88
+ * Auto-generating an ephemeral key here would silently encrypt secrets
89
+ * with a value that disappears on exit — making them undecryptable on
90
+ * the next launch — so we surface the missing-init explicitly instead.
111
91
  *
112
92
  * @returns The master key as a base64-encoded string.
93
+ * @throws If the key has not been initialized.
113
94
  */
114
95
  export function getMasterKey() {
115
96
  if (cachedMasterKey !== null) {
116
97
  return cachedMasterKey;
117
98
  }
118
- // 1. Check environment variable
119
99
  const envKey = process.env["SECRETS_MASTER_KEY"];
120
100
  if (envKey) {
101
+ // Stryker disable next-line all: diagnostic log, not behavior
121
102
  log.debug("Master key source", { source: "env" });
122
103
  cachedMasterKey = envKey;
123
104
  return envKey;
124
105
  }
125
- // 2. Auto-generate (not persisted without initMasterKey)
126
- log.debug("Master key source", { source: "generated" });
127
- const newKey = generateMasterKey();
128
- cachedMasterKey = newKey;
129
- return newKey;
106
+ throw new Error("Master key is not initialized. Call `initMasterKey()` once at startup " +
107
+ "(loads from system keychain / SECRETS_MASTER_KEY) " +
108
+ "before any synchronous secret access. Auto-generating a key here would " +
109
+ "silently encrypt secrets with a value that disappears on process exit.");
130
110
  }
131
111
  /**
132
112
  * Initialize the master key from all available sources (async).
133
113
  *
134
114
  * Should be called once at application startup to resolve the master key
135
- * from keychain or AWS Secrets Manager. After this call, getMasterKey()
136
- * will return the resolved key synchronously.
115
+ * from the keychain. After this call, getMasterKey() will return the
116
+ * resolved key synchronously.
137
117
  *
138
118
  * Resolution order:
139
119
  * 1. SECRETS_MASTER_KEY environment variable
140
- * 2. AWS Secrets Manager (if AWS_SECRETS_MASTER_KEY_NAME is set)
141
- * 3. System keychain via keytar
142
- * 4. Auto-generate and persist to keychain
120
+ * 2. System keychain via keytar
121
+ * 3. Auto-generate and persist to keychain
143
122
  *
144
123
  * @returns The master key as a base64-encoded string.
145
124
  */
146
125
  export async function initMasterKey() {
147
- // Return cached key if available
148
126
  if (cachedMasterKey !== null) {
149
127
  return cachedMasterKey;
150
128
  }
129
+ // Single-flight: concurrent first-run callers share one resolution. Without
130
+ // this, each would independently generate a *different* key and race to
131
+ // persist it, leaving the cache and keychain inconsistent and orphaning any
132
+ // secrets encrypted under the losing key.
133
+ if (initInFlight !== null) {
134
+ return initInFlight;
135
+ }
136
+ initInFlight = resolveMasterKey();
137
+ try {
138
+ return await initInFlight;
139
+ }
140
+ finally {
141
+ initInFlight = null;
142
+ }
143
+ }
144
+ /** Resolve the master key from all sources. See {@link initMasterKey}. */
145
+ async function resolveMasterKey() {
151
146
  // 1. Check environment variable
152
147
  const envKey = process.env["SECRETS_MASTER_KEY"];
153
148
  if (envKey) {
149
+ // Stryker disable next-line all: diagnostic log, not behavior
154
150
  log.debug("Master key source", { source: "env" });
155
151
  cachedMasterKey = envKey;
156
152
  return envKey;
157
153
  }
158
- // 2. Check AWS Secrets Manager if configured
159
- const awsSecretName = process.env["AWS_SECRETS_MASTER_KEY_NAME"];
160
- if (awsSecretName) {
161
- const awsKey = await getFromAwsSecrets(awsSecretName);
162
- if (awsKey) {
163
- log.debug("Master key source", { source: "aws" });
164
- cachedMasterKey = awsKey;
165
- return awsKey;
166
- }
154
+ // AWS Secrets Manager support was removed. Fail fast instead of silently
155
+ // ignoring the variable: falling through to a generated key would orphan
156
+ // every secret encrypted under the AWS-sourced key.
157
+ if (process.env["AWS_SECRETS_MASTER_KEY_NAME"]) {
158
+ throw new Error("AWS_SECRETS_MASTER_KEY_NAME is set, but AWS Secrets Manager support " +
159
+ "has been removed. Set SECRETS_MASTER_KEY to the key value that was " +
160
+ "stored in AWS Secrets Manager, then unset AWS_SECRETS_MASTER_KEY_NAME.");
167
161
  }
168
- // 3. Try system keychain via keytar
169
- const keytar = _keytar ?? await loadKeytar();
162
+ // 2. Try system keychain via keytar
163
+ const keytar = _keytar ?? (await loadKeytar());
170
164
  try {
171
165
  const storedKey = await keytar.getPassword(KEYRING_SERVICE, KEYRING_ACCOUNT);
172
166
  if (storedKey) {
167
+ // Stryker disable next-line all: diagnostic log, not behavior
173
168
  log.debug("Master key source", { source: "keychain" });
174
169
  cachedMasterKey = storedKey;
175
170
  return storedKey;
@@ -179,12 +174,13 @@ export async function initMasterKey() {
179
174
  const message = err instanceof Error ? err.message : String(err);
180
175
  throw keychainAccessError(`Unable to read master key from system keychain: ${message}`);
181
176
  }
182
- // 4. Auto-generate and persist to keychain. Persisting is mandatory; using
177
+ // 3. Auto-generate and persist to keychain. Persisting is mandatory; using
183
178
  // an unpersisted generated key would make encrypted secrets unrecoverable on
184
179
  // the next launch.
185
180
  const newKey = generateMasterKey();
186
181
  try {
187
182
  await keytar.setPassword(KEYRING_SERVICE, KEYRING_ACCOUNT, newKey);
183
+ // Stryker disable next-line all: diagnostic log, not behavior
188
184
  log.info("Master key generated and stored");
189
185
  }
190
186
  catch (err) {
@@ -198,7 +194,7 @@ export async function initMasterKey() {
198
194
  * Clear the cached master key.
199
195
  *
200
196
  * Forces the next call to getMasterKey() or initMasterKey() to
201
- * re-read from environment, AWS, or keychain.
197
+ * re-read from environment or keychain.
202
198
  */
203
199
  export function clearMasterKeyCache() {
204
200
  cachedMasterKey = null;
@@ -244,12 +240,4 @@ export async function deleteMasterKey() {
244
240
  export function isUsingEnvKey() {
245
241
  return process.env["SECRETS_MASTER_KEY"] !== undefined;
246
242
  }
247
- /**
248
- * Check if the master key should be sourced from AWS Secrets Manager.
249
- *
250
- * @returns True if AWS_SECRETS_MASTER_KEY_NAME environment variable is set.
251
- */
252
- export function isUsingAwsKey() {
253
- return process.env["AWS_SECRETS_MASTER_KEY_NAME"] !== undefined;
254
- }
255
243
  //# sourceMappingURL=master-key.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"master-key.js","sourceRoot":"","sources":["../src/master-key.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"master-key.js","sourceRoot":"","sources":["../src/master-key.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,22 +1,27 @@
1
1
  {
2
2
  "name": "@nodetool-ai/security",
3
- "version": "0.7.0-rc.23",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
+ "engines": {
6
+ "node": ">=22.0.0"
7
+ },
5
8
  "main": "dist/index.js",
6
9
  "types": "dist/index.d.ts",
7
10
  "scripts": {
8
11
  "build": "node ../../scripts/build-typescript-workspace.mjs",
9
- "test": "vitest run",
10
- "lint": "tsc --noEmit"
12
+ "test": "node ../../scripts/run-vitest.mjs run",
13
+ "test:mutation": "stryker run",
14
+ "lint": "node ../../scripts/run-tsc.mjs --noEmit"
11
15
  },
12
16
  "dependencies": {
13
- "@nodetool-ai/config": "^0.7.0-rc.23",
14
- "@aws-sdk/client-secrets-manager": "^3.1029.0",
17
+ "@nodetool-ai/config": "^0.8.1",
15
18
  "keytar": "^7.9.0"
16
19
  },
17
20
  "devDependencies": {
18
- "vitest": "^4.1.2",
19
- "typescript": "^5.7.2"
21
+ "@stryker-mutator/core": "^9.6.1",
22
+ "@stryker-mutator/vitest-runner": "^9.6.1",
23
+ "typescript": "npm:@typescript/typescript6@6.0.2",
24
+ "vitest": "^5.0.1"
20
25
  },
21
26
  "exports": {
22
27
  ".": {
@@ -42,5 +47,18 @@
42
47
  "files": [
43
48
  "dist",
44
49
  "README.md"
50
+ ],
51
+ "description": "Secret storage and encryption for NodeTool — master-key management, crypto helpers, and startup security checks",
52
+ "keywords": [
53
+ "nodetool",
54
+ "ai",
55
+ "workflow",
56
+ "workflow-automation",
57
+ "typescript",
58
+ "encryption",
59
+ "secrets",
60
+ "secret-storage",
61
+ "crypto",
62
+ "security"
45
63
  ]
46
64
  }
@@ -1,12 +0,0 @@
1
- export interface StartupCheckResult {
2
- errors: string[];
3
- warnings: string[];
4
- }
5
- /**
6
- * Run startup health checks.
7
- *
8
- * - Checks that the master encryption key is loadable.
9
- * - Warns about missing optional API keys.
10
- */
11
- export declare function runStartupChecks(): Promise<StartupCheckResult>;
12
- //# sourceMappingURL=startup-checks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-checks.d.ts","sourceRoot":"","sources":["../src/startup-checks.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAaD;;;;;GAKG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAyBpE"}
@@ -1,45 +0,0 @@
1
- /**
2
- * Startup checks — T-SEC-8.
3
- *
4
- * Validates that the system is properly configured before accepting requests.
5
- */
6
- import { getMasterKey } from "./master-key.js";
7
- /** Well-known optional API keys that should be configured for full functionality. */
8
- const OPTIONAL_API_KEYS = [
9
- "OPENAI_API_KEY",
10
- "ANTHROPIC_API_KEY",
11
- "GEMINI_API_KEY",
12
- "REPLICATE_API_TOKEN",
13
- "HF_TOKEN",
14
- "ELEVENLABS_API_KEY",
15
- "FAL_API_KEY"
16
- ];
17
- /**
18
- * Run startup health checks.
19
- *
20
- * - Checks that the master encryption key is loadable.
21
- * - Warns about missing optional API keys.
22
- */
23
- export async function runStartupChecks() {
24
- const errors = [];
25
- const warnings = [];
26
- // Check master key
27
- try {
28
- const key = getMasterKey();
29
- if (!key) {
30
- errors.push("Master encryption key could not be loaded");
31
- }
32
- }
33
- catch (err) {
34
- const msg = err instanceof Error ? err.message : String(err);
35
- errors.push(`Master key initialization failed: ${msg}`);
36
- }
37
- // Check optional API keys
38
- for (const envVar of OPTIONAL_API_KEYS) {
39
- if (!process.env[envVar]) {
40
- warnings.push(`${envVar} is not set — related features will be unavailable`);
41
- }
42
- }
43
- return { errors, warnings };
44
- }
45
- //# sourceMappingURL=startup-checks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-checks.js","sourceRoot":"","sources":["../src/startup-checks.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAO/C,qFAAqF;AACrF,MAAM,iBAAiB,GAAG;IACxB,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;IAChB,qBAAqB;IACrB,UAAU;IACV,oBAAoB;IACpB,aAAa;CACd,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,mBAAmB;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,0BAA0B;IAC1B,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CACX,GAAG,MAAM,oDAAoD,CAC9D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}