@memberjunction/encryption 0.0.1 → 2.130.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.
Files changed (46) hide show
  1. package/README.md +391 -28
  2. package/dist/EncryptionEngine.d.ts +351 -0
  3. package/dist/EncryptionEngine.d.ts.map +1 -0
  4. package/dist/EncryptionEngine.js +683 -0
  5. package/dist/EncryptionEngine.js.map +1 -0
  6. package/dist/EncryptionKeySourceBase.d.ts +203 -0
  7. package/dist/EncryptionKeySourceBase.d.ts.map +1 -0
  8. package/dist/EncryptionKeySourceBase.js +133 -0
  9. package/dist/EncryptionKeySourceBase.js.map +1 -0
  10. package/dist/actions/EnableFieldEncryptionAction.d.ts +87 -0
  11. package/dist/actions/EnableFieldEncryptionAction.d.ts.map +1 -0
  12. package/dist/actions/EnableFieldEncryptionAction.js +308 -0
  13. package/dist/actions/EnableFieldEncryptionAction.js.map +1 -0
  14. package/dist/actions/RotateEncryptionKeyAction.d.ts +79 -0
  15. package/dist/actions/RotateEncryptionKeyAction.d.ts.map +1 -0
  16. package/dist/actions/RotateEncryptionKeyAction.js +343 -0
  17. package/dist/actions/RotateEncryptionKeyAction.js.map +1 -0
  18. package/dist/actions/index.d.ts +12 -0
  19. package/dist/actions/index.d.ts.map +1 -0
  20. package/dist/actions/index.js +17 -0
  21. package/dist/actions/index.js.map +1 -0
  22. package/dist/index.d.ts +66 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +81 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/interfaces.d.ts +216 -0
  27. package/dist/interfaces.d.ts.map +1 -0
  28. package/dist/interfaces.js +15 -0
  29. package/dist/interfaces.js.map +1 -0
  30. package/dist/providers/AWSKMSKeySource.d.ts +110 -0
  31. package/dist/providers/AWSKMSKeySource.d.ts.map +1 -0
  32. package/dist/providers/AWSKMSKeySource.js +245 -0
  33. package/dist/providers/AWSKMSKeySource.js.map +1 -0
  34. package/dist/providers/AzureKeyVaultKeySource.d.ts +109 -0
  35. package/dist/providers/AzureKeyVaultKeySource.d.ts.map +1 -0
  36. package/dist/providers/AzureKeyVaultKeySource.js +268 -0
  37. package/dist/providers/AzureKeyVaultKeySource.js.map +1 -0
  38. package/dist/providers/ConfigFileKeySource.d.ts +173 -0
  39. package/dist/providers/ConfigFileKeySource.d.ts.map +1 -0
  40. package/dist/providers/ConfigFileKeySource.js +310 -0
  41. package/dist/providers/ConfigFileKeySource.js.map +1 -0
  42. package/dist/providers/EnvVarKeySource.d.ts +152 -0
  43. package/dist/providers/EnvVarKeySource.d.ts.map +1 -0
  44. package/dist/providers/EnvVarKeySource.js +251 -0
  45. package/dist/providers/EnvVarKeySource.js.map +1 -0
  46. package/package.json +65 -6
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @fileoverview Type definitions and interfaces for the MemberJunction encryption system.
3
+ *
4
+ * This module defines the core types used throughout the encryption package:
5
+ * - Configuration interfaces for key sources
6
+ * - Parsed encrypted value structure
7
+ * - Key configuration for runtime operations
8
+ *
9
+ * @module @memberjunction/encryption
10
+ * @see {@link EncryptionEngine} for the main encryption/decryption API
11
+ * @see {@link EncryptionKeySourceBase} for implementing custom key sources
12
+ */
13
+ /**
14
+ * Configuration passed to encryption key source providers during instantiation.
15
+ *
16
+ * Key sources use this configuration to understand how to retrieve key material.
17
+ * The specific properties used depend on the key source implementation.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Environment variable source config
22
+ * const envConfig: EncryptionKeySourceConfig = {
23
+ * lookupValue: 'MJ_ENCRYPTION_KEY_PII'
24
+ * };
25
+ *
26
+ * // Config file source config
27
+ * const fileConfig: EncryptionKeySourceConfig = {
28
+ * lookupValue: 'pii_master_key'
29
+ * };
30
+ * ```
31
+ */
32
+ export interface EncryptionKeySourceConfig {
33
+ /**
34
+ * The identifier used to look up the key from the source.
35
+ * - For env vars: the environment variable name
36
+ * - For config files: the key name in the encryptionKeys section
37
+ * - For vaults: the secret path
38
+ */
39
+ lookupValue?: string;
40
+ /**
41
+ * Optional additional configuration specific to the key source.
42
+ * Providers can cast this to their specific config type.
43
+ */
44
+ additionalConfig?: Record<string, unknown>;
45
+ }
46
+ /**
47
+ * Represents the parsed components of an encrypted value string.
48
+ *
49
+ * Encrypted values follow the format:
50
+ * `$ENC$<keyId>$<algorithm>$<iv>$<ciphertext>[$<authTag>]`
51
+ *
52
+ * This structure allows the encryption engine to:
53
+ * 1. Identify which key was used for encryption
54
+ * 2. Determine the algorithm for decryption
55
+ * 3. Extract the IV and ciphertext for the crypto operation
56
+ * 4. Verify authenticity with the auth tag (for AEAD algorithms)
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const parts = engine.ParseEncryptedValue(encryptedValue);
61
+ * console.log(parts.keyId); // UUID of the encryption key
62
+ * console.log(parts.algorithm); // 'AES-256-GCM'
63
+ * ```
64
+ */
65
+ export interface EncryptedValueParts {
66
+ /**
67
+ * The encryption marker prefix (always '$ENC$').
68
+ * Used for quick detection of encrypted values.
69
+ */
70
+ marker: string;
71
+ /**
72
+ * The UUID of the encryption key used.
73
+ * References the EncryptionKey entity in the database.
74
+ */
75
+ keyId: string;
76
+ /**
77
+ * The algorithm name used for encryption.
78
+ * Matches the Name field in the EncryptionAlgorithm entity.
79
+ * @example 'AES-256-GCM', 'AES-256-CBC'
80
+ */
81
+ algorithm: string;
82
+ /**
83
+ * Base64-encoded initialization vector.
84
+ * Randomly generated for each encryption operation.
85
+ */
86
+ iv: string;
87
+ /**
88
+ * Base64-encoded encrypted data.
89
+ */
90
+ ciphertext: string;
91
+ /**
92
+ * Base64-encoded authentication tag for AEAD algorithms.
93
+ * Only present for algorithms like AES-GCM that provide authentication.
94
+ * Undefined for non-AEAD algorithms like AES-CBC.
95
+ */
96
+ authTag?: string;
97
+ }
98
+ /**
99
+ * Complete key configuration loaded from the database.
100
+ *
101
+ * This structure contains everything needed to perform encryption
102
+ * or decryption operations, cached for performance.
103
+ *
104
+ * @internal Used by EncryptionEngine for key management
105
+ */
106
+ export interface KeyConfiguration {
107
+ /** The encryption key's unique identifier (UUID) */
108
+ keyId: string;
109
+ /**
110
+ * Current version of the key for this configuration.
111
+ * Incremented during key rotation operations.
112
+ */
113
+ keyVersion: string;
114
+ /**
115
+ * Prefix marker for encrypted values.
116
+ * Defaults to '$ENC$' but can be customized per key.
117
+ */
118
+ marker: string;
119
+ /** Algorithm configuration */
120
+ algorithm: {
121
+ /** Display name of the algorithm (e.g., 'AES-256-GCM') */
122
+ name: string;
123
+ /** Node.js crypto module algorithm identifier (e.g., 'aes-256-gcm') */
124
+ nodeCryptoName: string;
125
+ /** Required key length in bits (e.g., 256 for AES-256) */
126
+ keyLengthBits: number;
127
+ /** Required IV length in bytes (e.g., 12 for GCM, 16 for CBC) */
128
+ ivLengthBytes: number;
129
+ /**
130
+ * Whether the algorithm provides Authenticated Encryption with Associated Data.
131
+ * AEAD algorithms (like AES-GCM) provide both confidentiality and integrity.
132
+ */
133
+ isAEAD: boolean;
134
+ };
135
+ /** Key source configuration for retrieving key material */
136
+ source: {
137
+ /**
138
+ * The registered class name of the key source provider.
139
+ * Used with ClassFactory to instantiate the provider.
140
+ */
141
+ driverClass: string;
142
+ /**
143
+ * The lookup value passed to the key source.
144
+ * Interpretation depends on the source type.
145
+ */
146
+ lookupValue: string;
147
+ };
148
+ }
149
+ /**
150
+ * Result structure returned by key rotation operations.
151
+ *
152
+ * @see {@link RotateEncryptionKeyAction} for the rotation action
153
+ */
154
+ export interface RotateKeyResult {
155
+ /** Whether the rotation completed successfully */
156
+ success: boolean;
157
+ /** Total number of records that were re-encrypted */
158
+ recordsProcessed: number;
159
+ /**
160
+ * List of fields that were processed.
161
+ * Format: 'EntityName.FieldName'
162
+ */
163
+ fieldsProcessed: string[];
164
+ /** Error message if rotation failed */
165
+ error?: string;
166
+ }
167
+ /**
168
+ * Parameters for key rotation operations.
169
+ *
170
+ * @see {@link RotateEncryptionKeyAction} for the rotation action
171
+ */
172
+ export interface RotateKeyParams {
173
+ /** UUID of the encryption key to rotate */
174
+ encryptionKeyId: string;
175
+ /**
176
+ * Lookup value for the new key material.
177
+ * The new key must be accessible via the key source before rotation.
178
+ */
179
+ newKeyLookupValue: string;
180
+ /**
181
+ * Number of records to process per batch.
182
+ * Larger batches are faster but use more memory.
183
+ * @default 100
184
+ */
185
+ batchSize?: number;
186
+ }
187
+ /**
188
+ * Result structure for field encryption operations.
189
+ *
190
+ * @see {@link EnableFieldEncryptionAction}
191
+ */
192
+ export interface EnableFieldEncryptionResult {
193
+ /** Whether the operation completed successfully */
194
+ success: boolean;
195
+ /** Number of records that were encrypted */
196
+ recordsEncrypted: number;
197
+ /** Number of records that were already encrypted (skipped) */
198
+ recordsSkipped: number;
199
+ /** Error message if the operation failed */
200
+ error?: string;
201
+ }
202
+ /**
203
+ * Parameters for enabling encryption on existing data.
204
+ *
205
+ * @see {@link EnableFieldEncryptionAction}
206
+ */
207
+ export interface EnableFieldEncryptionParams {
208
+ /** UUID of the EntityField to encrypt */
209
+ entityFieldId: string;
210
+ /**
211
+ * Number of records to process per batch.
212
+ * @default 100
213
+ */
214
+ batchSize?: number;
215
+ }
216
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,yBAAyB;IACtC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC7B,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf,8BAA8B;IAC9B,SAAS,EAAE;QACP,0DAA0D;QAC1D,IAAI,EAAE,MAAM,CAAC;QAEb,uEAAuE;QACvE,cAAc,EAAE,MAAM,CAAC;QAEvB,0DAA0D;QAC1D,aAAa,EAAE,MAAM,CAAC;QAEtB,iEAAiE;QACjE,aAAa,EAAE,MAAM,CAAC;QAEtB;;;WAGG;QACH,MAAM,EAAE,OAAO,CAAC;KACnB,CAAC;IAEF,2DAA2D;IAC3D,MAAM,EAAE;QACJ;;;WAGG;QACH,WAAW,EAAE,MAAM,CAAC;QAEpB;;;WAGG;QACH,WAAW,EAAE,MAAM,CAAC;KACvB,CAAC;CACL;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC5B,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC;IAEjB,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;IAE1B,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC5B,2CAA2C;IAC3C,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IACxC,mDAAmD;IACnD,OAAO,EAAE,OAAO,CAAC;IAEjB,4CAA4C;IAC5C,gBAAgB,EAAE,MAAM,CAAC;IAEzB,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAC;IAEvB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IACxC,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Type definitions and interfaces for the MemberJunction encryption system.
4
+ *
5
+ * This module defines the core types used throughout the encryption package:
6
+ * - Configuration interfaces for key sources
7
+ * - Parsed encrypted value structure
8
+ * - Key configuration for runtime operations
9
+ *
10
+ * @module @memberjunction/encryption
11
+ * @see {@link EncryptionEngine} for the main encryption/decryption API
12
+ * @see {@link EncryptionKeySourceBase} for implementing custom key sources
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @fileoverview AWS KMS encryption key source provider.
3
+ *
4
+ * This provider retrieves encryption keys from AWS Key Management Service (KMS).
5
+ * It supports both symmetric keys and data key encryption using envelope encryption.
6
+ *
7
+ * ## Configuration
8
+ *
9
+ * The provider uses the standard AWS credential chain:
10
+ * - Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
11
+ * - Shared credentials file (~/.aws/credentials)
12
+ * - IAM role (when running on EC2, ECS, Lambda, etc.)
13
+ *
14
+ * ## Usage
15
+ *
16
+ * 1. Create a symmetric key in AWS KMS
17
+ * 2. Store the key ARN or alias as the KeyLookupValue in MemberJunction
18
+ * 3. Ensure the application has kms:Decrypt permission for the key
19
+ *
20
+ * ## Lookup Value Format
21
+ *
22
+ * The KeyLookupValue should be in one of these formats:
23
+ * - Full ARN: `arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012`
24
+ * - Alias ARN: `arn:aws:kms:us-east-1:123456789012:alias/my-key`
25
+ * - Alias name: `alias/my-key` (uses default region)
26
+ *
27
+ * ## Environment Variables
28
+ *
29
+ * - `AWS_REGION` or `AWS_DEFAULT_REGION`: AWS region (required if not in ARN)
30
+ * - `AWS_ACCESS_KEY_ID`: Access key (optional if using IAM role)
31
+ * - `AWS_SECRET_ACCESS_KEY`: Secret key (optional if using IAM role)
32
+ *
33
+ * @module @memberjunction/encryption
34
+ */
35
+ /// <reference types="node" />
36
+ import { EncryptionKeySourceBase } from '../EncryptionKeySourceBase';
37
+ /**
38
+ * AWS KMS key source provider.
39
+ *
40
+ * Retrieves encryption keys from AWS Key Management Service.
41
+ * The key material is stored encrypted in KMS and decrypted on retrieval.
42
+ *
43
+ * ## Security Notes
44
+ *
45
+ * - Key material never leaves AWS in plaintext until decryption
46
+ * - All operations are logged in CloudTrail
47
+ * - IAM policies control access to keys
48
+ * - Supports key rotation managed by AWS
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * // In database: KeyLookupValue = 'alias/mj-encryption-key'
53
+ * // The provider will call KMS to decrypt the data key
54
+ * ```
55
+ */
56
+ export declare class AWSKMSKeySource extends EncryptionKeySourceBase {
57
+ private _client;
58
+ private _initialized;
59
+ /**
60
+ * Human-readable name for this key source.
61
+ */
62
+ get SourceName(): string;
63
+ /**
64
+ * Initializes the AWS KMS client.
65
+ *
66
+ * Lazy-loads the AWS SDK to avoid requiring it when not used.
67
+ * Uses the default credential chain for authentication.
68
+ */
69
+ Initialize(): Promise<void>;
70
+ /**
71
+ * Validates that the AWS KMS client is properly configured.
72
+ *
73
+ * @returns true if the client is initialized and region is configured
74
+ */
75
+ ValidateConfiguration(): boolean;
76
+ /**
77
+ * Checks if a key exists in AWS KMS.
78
+ *
79
+ * Note: This only checks if the key ARN/alias format is valid.
80
+ * Actual key existence is verified on GetKey().
81
+ *
82
+ * @param lookupValue - The KMS key ARN or alias
83
+ * @returns true if the lookup value appears to be a valid KMS key reference
84
+ */
85
+ KeyExists(lookupValue: string): Promise<boolean>;
86
+ /**
87
+ * Retrieves encryption key material from AWS KMS.
88
+ *
89
+ * This method expects the lookupValue to contain a base64-encoded
90
+ * encrypted data key (ciphertext blob) that was encrypted using
91
+ * a KMS customer master key (CMK).
92
+ *
93
+ * For envelope encryption pattern:
94
+ * 1. Generate a data key using KMS GenerateDataKey
95
+ * 2. Store the encrypted data key (CiphertextBlob) as base64 in lookupValue
96
+ * 3. This method decrypts it to get the plaintext key
97
+ *
98
+ * @param lookupValue - Base64-encoded encrypted data key
99
+ * @param _keyVersion - Not used for KMS (versioning handled by KMS)
100
+ * @returns Buffer containing the decrypted key material
101
+ *
102
+ * @throws Error if the key cannot be decrypted
103
+ */
104
+ GetKey(lookupValue: string, _keyVersion?: string): Promise<Buffer>;
105
+ /**
106
+ * Cleans up the AWS KMS client.
107
+ */
108
+ Dispose(): Promise<void>;
109
+ }
110
+ //# sourceMappingURL=AWSKMSKeySource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AWSKMSKeySource.d.ts","sourceRoot":"","sources":["../../src/providers/AWSKMSKeySource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;AAIH,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAMrE;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBACa,eAAgB,SAAQ,uBAAuB;IACxD,OAAO,CAAC,OAAO,CAA6E;IAC5F,OAAO,CAAC,YAAY,CAAS;IAE7B;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BjC;;;;OAIG;IACH,qBAAqB,IAAI,OAAO;IAkBhC;;;;;;;;OAQG;IACG,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAetD;;;;;;;;;;;;;;;;;OAiBG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgExE;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAOjC"}
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview AWS KMS encryption key source provider.
4
+ *
5
+ * This provider retrieves encryption keys from AWS Key Management Service (KMS).
6
+ * It supports both symmetric keys and data key encryption using envelope encryption.
7
+ *
8
+ * ## Configuration
9
+ *
10
+ * The provider uses the standard AWS credential chain:
11
+ * - Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
12
+ * - Shared credentials file (~/.aws/credentials)
13
+ * - IAM role (when running on EC2, ECS, Lambda, etc.)
14
+ *
15
+ * ## Usage
16
+ *
17
+ * 1. Create a symmetric key in AWS KMS
18
+ * 2. Store the key ARN or alias as the KeyLookupValue in MemberJunction
19
+ * 3. Ensure the application has kms:Decrypt permission for the key
20
+ *
21
+ * ## Lookup Value Format
22
+ *
23
+ * The KeyLookupValue should be in one of these formats:
24
+ * - Full ARN: `arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012`
25
+ * - Alias ARN: `arn:aws:kms:us-east-1:123456789012:alias/my-key`
26
+ * - Alias name: `alias/my-key` (uses default region)
27
+ *
28
+ * ## Environment Variables
29
+ *
30
+ * - `AWS_REGION` or `AWS_DEFAULT_REGION`: AWS region (required if not in ARN)
31
+ * - `AWS_ACCESS_KEY_ID`: Access key (optional if using IAM role)
32
+ * - `AWS_SECRET_ACCESS_KEY`: Secret key (optional if using IAM role)
33
+ *
34
+ * @module @memberjunction/encryption
35
+ */
36
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
37
+ if (k2 === undefined) k2 = k;
38
+ var desc = Object.getOwnPropertyDescriptor(m, k);
39
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
40
+ desc = { enumerable: true, get: function() { return m[k]; } };
41
+ }
42
+ Object.defineProperty(o, k2, desc);
43
+ }) : (function(o, m, k, k2) {
44
+ if (k2 === undefined) k2 = k;
45
+ o[k2] = m[k];
46
+ }));
47
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
48
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
49
+ }) : function(o, v) {
50
+ o["default"] = v;
51
+ });
52
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
53
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
54
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
55
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
56
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
57
+ };
58
+ var __importStar = (this && this.__importStar) || function (mod) {
59
+ if (mod && mod.__esModule) return mod;
60
+ var result = {};
61
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
62
+ __setModuleDefault(result, mod);
63
+ return result;
64
+ };
65
+ Object.defineProperty(exports, "__esModule", { value: true });
66
+ exports.AWSKMSKeySource = void 0;
67
+ const global_1 = require("@memberjunction/global");
68
+ const core_1 = require("@memberjunction/core");
69
+ const EncryptionKeySourceBase_1 = require("../EncryptionKeySourceBase");
70
+ // Lazy-load AWS SDK to avoid requiring it when not used
71
+ let KMSClient = null;
72
+ let DecryptCommand = null;
73
+ /**
74
+ * AWS KMS key source provider.
75
+ *
76
+ * Retrieves encryption keys from AWS Key Management Service.
77
+ * The key material is stored encrypted in KMS and decrypted on retrieval.
78
+ *
79
+ * ## Security Notes
80
+ *
81
+ * - Key material never leaves AWS in plaintext until decryption
82
+ * - All operations are logged in CloudTrail
83
+ * - IAM policies control access to keys
84
+ * - Supports key rotation managed by AWS
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * // In database: KeyLookupValue = 'alias/mj-encryption-key'
89
+ * // The provider will call KMS to decrypt the data key
90
+ * ```
91
+ */
92
+ let AWSKMSKeySource = class AWSKMSKeySource extends EncryptionKeySourceBase_1.EncryptionKeySourceBase {
93
+ _client = null;
94
+ _initialized = false;
95
+ /**
96
+ * Human-readable name for this key source.
97
+ */
98
+ get SourceName() {
99
+ return 'AWS KMS';
100
+ }
101
+ /**
102
+ * Initializes the AWS KMS client.
103
+ *
104
+ * Lazy-loads the AWS SDK to avoid requiring it when not used.
105
+ * Uses the default credential chain for authentication.
106
+ */
107
+ async Initialize() {
108
+ if (this._initialized) {
109
+ return;
110
+ }
111
+ try {
112
+ // Lazy-load AWS SDK
113
+ const kmsModule = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-kms')));
114
+ KMSClient = kmsModule.KMSClient;
115
+ DecryptCommand = kmsModule.DecryptCommand;
116
+ // Create client with default credential chain
117
+ const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
118
+ this._client = new KMSClient({
119
+ region: region || undefined
120
+ });
121
+ this._initialized = true;
122
+ }
123
+ catch (err) {
124
+ const message = err instanceof Error ? err.message : String(err);
125
+ throw new Error(`Failed to initialize AWS KMS client: ${message}. ` +
126
+ 'Ensure @aws-sdk/client-kms is installed: npm install @aws-sdk/client-kms');
127
+ }
128
+ }
129
+ /**
130
+ * Validates that the AWS KMS client is properly configured.
131
+ *
132
+ * @returns true if the client is initialized and region is configured
133
+ */
134
+ ValidateConfiguration() {
135
+ if (!this._initialized || !this._client) {
136
+ return false;
137
+ }
138
+ // Check that we have a region configured
139
+ const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;
140
+ if (!region) {
141
+ (0, core_1.LogError)('AWS KMS key source: No AWS region configured. ' +
142
+ 'Set AWS_REGION or AWS_DEFAULT_REGION environment variable.');
143
+ return false;
144
+ }
145
+ return true;
146
+ }
147
+ /**
148
+ * Checks if a key exists in AWS KMS.
149
+ *
150
+ * Note: This only checks if the key ARN/alias format is valid.
151
+ * Actual key existence is verified on GetKey().
152
+ *
153
+ * @param lookupValue - The KMS key ARN or alias
154
+ * @returns true if the lookup value appears to be a valid KMS key reference
155
+ */
156
+ async KeyExists(lookupValue) {
157
+ if (!lookupValue) {
158
+ return false;
159
+ }
160
+ // Check for valid KMS key reference formats
161
+ // ARN: arn:aws:kms:region:account:key/key-id
162
+ // Alias ARN: arn:aws:kms:region:account:alias/alias-name
163
+ // Alias: alias/alias-name
164
+ const arnPattern = /^arn:aws:kms:[a-z0-9-]+:[0-9]+:(key|alias)\/.+$/;
165
+ const aliasPattern = /^alias\/.+$/;
166
+ return arnPattern.test(lookupValue) || aliasPattern.test(lookupValue);
167
+ }
168
+ /**
169
+ * Retrieves encryption key material from AWS KMS.
170
+ *
171
+ * This method expects the lookupValue to contain a base64-encoded
172
+ * encrypted data key (ciphertext blob) that was encrypted using
173
+ * a KMS customer master key (CMK).
174
+ *
175
+ * For envelope encryption pattern:
176
+ * 1. Generate a data key using KMS GenerateDataKey
177
+ * 2. Store the encrypted data key (CiphertextBlob) as base64 in lookupValue
178
+ * 3. This method decrypts it to get the plaintext key
179
+ *
180
+ * @param lookupValue - Base64-encoded encrypted data key
181
+ * @param _keyVersion - Not used for KMS (versioning handled by KMS)
182
+ * @returns Buffer containing the decrypted key material
183
+ *
184
+ * @throws Error if the key cannot be decrypted
185
+ */
186
+ async GetKey(lookupValue, _keyVersion) {
187
+ if (!this._initialized || !this._client) {
188
+ await this.Initialize();
189
+ }
190
+ if (!this._client || !DecryptCommand) {
191
+ throw new Error('AWS KMS client not initialized');
192
+ }
193
+ if (!lookupValue) {
194
+ throw new Error('AWS KMS key source requires a lookup value. ' +
195
+ 'Provide the base64-encoded encrypted data key (CiphertextBlob).');
196
+ }
197
+ try {
198
+ // The lookupValue should be a base64-encoded encrypted data key
199
+ // This is the CiphertextBlob from GenerateDataKey
200
+ const ciphertextBlob = Buffer.from(lookupValue, 'base64');
201
+ // Decrypt the data key using KMS
202
+ const command = new DecryptCommand({
203
+ CiphertextBlob: ciphertextBlob
204
+ });
205
+ const response = await this._client.send(command);
206
+ if (!response.Plaintext) {
207
+ throw new Error('KMS returned empty plaintext');
208
+ }
209
+ // Convert Uint8Array to Buffer
210
+ return Buffer.from(response.Plaintext);
211
+ }
212
+ catch (err) {
213
+ const message = err instanceof Error ? err.message : String(err);
214
+ // Provide helpful error messages for common issues
215
+ if (message.includes('InvalidCiphertextException')) {
216
+ throw new Error(`AWS KMS decryption failed: Invalid ciphertext. ` +
217
+ `Ensure the lookup value contains a valid base64-encoded encrypted data key.`);
218
+ }
219
+ if (message.includes('AccessDeniedException')) {
220
+ throw new Error(`AWS KMS access denied. ` +
221
+ `Ensure the application has kms:Decrypt permission for the key.`);
222
+ }
223
+ if (message.includes('NotFoundException')) {
224
+ throw new Error(`AWS KMS key not found. ` +
225
+ `Verify the key ARN/alias exists and is in the correct region.`);
226
+ }
227
+ throw new Error(`AWS KMS key retrieval failed: ${message}`);
228
+ }
229
+ }
230
+ /**
231
+ * Cleans up the AWS KMS client.
232
+ */
233
+ async Dispose() {
234
+ if (this._client) {
235
+ this._client.destroy();
236
+ this._client = null;
237
+ }
238
+ this._initialized = false;
239
+ }
240
+ };
241
+ exports.AWSKMSKeySource = AWSKMSKeySource;
242
+ exports.AWSKMSKeySource = AWSKMSKeySource = __decorate([
243
+ (0, global_1.RegisterClass)(EncryptionKeySourceBase_1.EncryptionKeySourceBase, 'AWSKMSKeySource')
244
+ ], AWSKMSKeySource);
245
+ //# sourceMappingURL=AWSKMSKeySource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AWSKMSKeySource.js","sourceRoot":"","sources":["../../src/providers/AWSKMSKeySource.ts"],"names":[],"mappings":"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"}