@lambda-kata/licensing 0.1.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/LICENSE ADDED
@@ -0,0 +1,100 @@
1
+ Elastic License 2.0
2
+
3
+ URL: https://www.elastic.co/licensing/elastic-license
4
+
5
+ Licensed Work: Work Target Insight Function (Work TIF Platform, including all associated components)
6
+ Licensor: Raman Marozau <raman@worktif.com>
7
+
8
+ ## Acceptance
9
+
10
+ By using the software, you agree to all of the terms and conditions below.
11
+
12
+ ## Copyright License
13
+
14
+ The licensor grants you a non-exclusive, royalty-free, worldwide,
15
+ non-sublicensable, non-transferable license to use, copy, distribute, make
16
+ available, and prepare derivative works of the software, in each case subject to
17
+ the limitations and conditions below.
18
+
19
+ ## Limitations
20
+
21
+ You may not provide the software to third parties as a hosted or managed
22
+ service, where the service provides users with access to any substantial set of
23
+ the features or functionality of the software.
24
+
25
+ You may not move, change, disable, or circumvent the license key functionality
26
+ in the software, and you may not remove or obscure any functionality in the
27
+ software that is protected by the license key.
28
+
29
+ You may not alter, remove, or obscure any licensing, copyright, or other notices
30
+ of the licensor in the software. Any use of the licensor’s trademarks is subject
31
+ to applicable law.
32
+
33
+ ## Patents
34
+
35
+ The licensor grants you a license, under any patent claims the licensor can
36
+ license, or becomes able to license, to make, have made, use, sell, offer for
37
+ sale, import and have imported the software, in each case subject to the
38
+ limitations and conditions in this license. This license does not cover any
39
+ patent claims that you cause to be infringed by modifications or additions to
40
+ the software. If you or your company make any written claim that the software
41
+ infringes or contributes to infringement of any patent, your patent license for
42
+ the software granted under these terms ends immediately. If your company makes
43
+ such a claim, your patent license ends immediately for work on behalf of your
44
+ company.
45
+
46
+ ## Notices
47
+
48
+ You must ensure that anyone who gets a copy of any part of the software from you
49
+ also gets a copy of these terms.
50
+
51
+ If you modify the software, you must include in any modified copies of the
52
+ software prominent notices stating that you have modified the software.
53
+
54
+ ## No Other Rights
55
+
56
+ These terms do not imply any licenses other than those expressly granted in
57
+ these terms.
58
+
59
+ ## Termination
60
+
61
+ If you use the software in violation of these terms, such use is not licensed,
62
+ and your licenses will automatically terminate. If the licensor provides you
63
+ with a notice of your violation, and you cease all violation of this license no
64
+ later than 30 days after you receive that notice, your licenses will be
65
+ reinstated retroactively. However, if you violate these terms after such
66
+ reinstatement, any additional violation of these terms will cause your licenses
67
+ to terminate automatically and permanently.
68
+
69
+ ## No Liability
70
+
71
+ *As far as the law allows, the software comes as is, without any warranty or
72
+ condition, and the licensor will not be liable to you for any damages arising
73
+ out of these terms or the use or nature of the software, under any kind of
74
+ legal claim.*
75
+
76
+ ## Definitions
77
+
78
+ The **licensor** is the entity offering these terms, and the **software** is the
79
+ software the licensor makes available under these terms, including any portion
80
+ of it.
81
+
82
+ **you** refers to the individual or entity agreeing to these terms.
83
+
84
+ **your company** is any legal entity, sole proprietorship, or other kind of
85
+ organization that you work for, plus all organizations that have control over,
86
+ are under the control of, or are under common control with that
87
+ organization. **control** means ownership of substantially all the assets of an
88
+ entity, or the power to direct its management and policies by vote, contract, or
89
+ otherwise. Control can be direct or indirect.
90
+
91
+ **your licenses** are all the licenses granted to you for the software under
92
+ these terms.
93
+
94
+ **use** means anything you do with the software requiring one of your licenses.
95
+
96
+ **trademark** means trademarks, service marks, and similar rights.
97
+
98
+ Additional Notices:
99
+ For attribution notices and full license texts of included third-party dependencies,
100
+ see THIRD_PARTY_LICENSES.txt.
package/README.md ADDED
@@ -0,0 +1,315 @@
1
+ # Lambda Kata Licensing
2
+
3
+ A tamper-resistant native licensing validator for the Lambda Kata SST Integration workspace. This package provides enhanced security through a native C implementation that replaces the existing TypeScript-based licensing validation.
4
+
5
+ ## Features
6
+
7
+ - **Tamper-Resistant**: Native C implementation prevents JavaScript-based tampering
8
+ - **Fail-Closed Security**: All error conditions result in denying access
9
+ - **Hardened Network**: Compile-time hardcoded endpoints with strict TLS validation
10
+ - **AWS Lambda Compatible**: Optimized for Amazon Linux 2023 (x64 and arm64)
11
+ - **Drop-in Replacement**: Compatible with existing `LicensingService` interface
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @lambda-kata/licensing
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Basic Usage
22
+
23
+ ```typescript
24
+ import { NativeLicensingService } from '@lambda-kata/licensing';
25
+
26
+ const service = new NativeLicensingService();
27
+ const result = await service.checkEntitlement('123456789012');
28
+
29
+ if (result.entitled) {
30
+ console.log(`Layer ARN: ${result.layerArn}`);
31
+ } else {
32
+ console.log(`Not entitled: ${result.message}`);
33
+ }
34
+ ```
35
+
36
+ ### Factory Function
37
+
38
+ ```typescript
39
+ import { createLicensingService } from '@lambda-kata/licensing';
40
+
41
+ const service = createLicensingService();
42
+ const result = await service.checkEntitlement('123456789012');
43
+ ```
44
+
45
+ ### Integration with SST Packages
46
+
47
+ The native validator is designed to be a drop-in replacement for the existing HTTP-based licensing service:
48
+
49
+ ```typescript
50
+ // Before (HTTP-based)
51
+ import { HttpLicensingService } from '@lambda-kata/sst-v2';
52
+
53
+ // After (Native-based)
54
+ import { NativeLicensingService } from '@lambda-kata/licensing';
55
+
56
+ // Same interface, enhanced security
57
+ const service = new NativeLicensingService();
58
+ ```
59
+
60
+ ## Security Features
61
+
62
+ ### Fail-Closed Architecture
63
+
64
+ The validator implements a fail-closed security model where any error condition results in denying access:
65
+
66
+ - Network timeouts or connection failures
67
+ - TLS certificate validation failures
68
+ - Invalid response formats
69
+ - Native addon loading failures
70
+ - Invalid input parameters
71
+
72
+ ### Hardened Network Communication
73
+
74
+ - **Compile-time endpoints**: Network destinations cannot be modified at runtime
75
+ - **No proxy support**: Ignores proxy environment variables
76
+ - **Strict TLS**: Requires TLS 1.2+ with certificate validation
77
+ - **No redirects**: HTTP redirects are completely disabled
78
+ - **Response authenticity**: Verifies response signatures or certificate pinning
79
+
80
+ ### Minimal Attack Surface
81
+
82
+ - **Single function interface**: Only `checkEntitlement(accountId: string)` is exposed
83
+ - **Input validation**: Account ID format validated in both JavaScript and native code
84
+ - **No configuration**: All security settings are compile-time constants
85
+
86
+ ## Building
87
+
88
+ ### Prerequisites
89
+
90
+ - Node.js 18+ with npm/yarn
91
+ - C compiler (gcc/clang)
92
+ - libcurl development headers
93
+ - OpenSSL development headers
94
+ - json-c development headers (Linux only)
95
+
96
+ ### Local Development Build
97
+
98
+ ```bash
99
+ # Install dependencies
100
+ yarn install
101
+
102
+ # Build native addon
103
+ yarn build:native
104
+
105
+ # Build TypeScript
106
+ yarn build:ts
107
+
108
+ # Build everything
109
+ yarn build
110
+ ```
111
+
112
+ ### Docker-based Build (Recommended for Lambda)
113
+
114
+ ```bash
115
+ # Build for all architectures
116
+ ./scripts/build-docker.sh
117
+
118
+ # Build for specific architecture
119
+ ./scripts/build-docker.sh x64
120
+ ./scripts/build-docker.sh arm64
121
+ ```
122
+
123
+ The Docker build produces Lambda Layer packages ready for deployment.
124
+
125
+ ## Testing
126
+
127
+ ```bash
128
+ # Run all tests
129
+ yarn test
130
+
131
+ # Run tests with coverage
132
+ yarn test:coverage
133
+
134
+ # Run tests in watch mode
135
+ yarn test:watch
136
+ ```
137
+
138
+ ### Test Categories
139
+
140
+ - **Unit Tests**: Specific examples and edge cases
141
+ - **Property-Based Tests**: Universal properties using fast-check
142
+ - **Integration Tests**: End-to-end validation with mock servers
143
+ - **Security Tests**: Tampering resistance and fail-closed behavior
144
+
145
+ ## API Reference
146
+
147
+ ### NativeLicensingService
148
+
149
+ #### `checkEntitlement(accountId: string): Promise<LicensingResponse>`
150
+
151
+ Validates licensing entitlement for an AWS account.
152
+
153
+ **Parameters:**
154
+ - `accountId` - 12-digit AWS account ID string
155
+
156
+ **Returns:**
157
+ - `Promise<LicensingResponse>` - Licensing validation result
158
+
159
+ **Example:**
160
+ ```typescript
161
+ const result = await service.checkEntitlement('123456789012');
162
+ ```
163
+
164
+ ### LicensingResponse
165
+
166
+ ```typescript
167
+ interface LicensingResponse {
168
+ entitled: boolean; // Entitlement status
169
+ layerArn?: string; // Customer Lambda Layer ARN (if entitled)
170
+ message?: string; // Human-readable status message
171
+ expiresAt?: string; // ISO 8601 expiration timestamp
172
+ }
173
+ ```
174
+
175
+ ## Error Handling
176
+
177
+ The validator never throws exceptions. All errors result in a fail-closed response:
178
+
179
+ ```typescript
180
+ {
181
+ entitled: false,
182
+ message: "Error description"
183
+ }
184
+ ```
185
+
186
+ Common error messages:
187
+ - `"Invalid account ID format"` - Account ID is not a 12-digit string
188
+ - `"Native validator unavailable"` - Native addon failed to load
189
+ - `"Network error"` - Network communication failed
190
+ - `"Security error"` - TLS or authenticity verification failed
191
+ - `"System error"` - Unexpected system error
192
+
193
+ ## Performance
194
+
195
+ - **Validation time**: < 5 seconds under normal conditions
196
+ - **Memory usage**: < 1MB heap usage
197
+ - **Addon loading**: < 100ms in Lambda environment
198
+ - **Caching**: 5-minute TTL for successful responses
199
+ - **Connection reuse**: HTTP connections are pooled and reused
200
+
201
+ ## Deployment
202
+
203
+ ### Lambda Layer
204
+
205
+ The package includes pre-built Lambda Layer packages for both x64 and arm64 architectures:
206
+
207
+ ```bash
208
+ # Extract from build artifacts
209
+ unzip build/native-licensing-validator-amd64.zip -d layer/
210
+ ```
211
+
212
+ Layer structure:
213
+ ```
214
+ nodejs/
215
+ └── node_modules/
216
+ └── @lambda-kata/
217
+ └── native-licensing-validator/
218
+ ├── build/Release/lambda_kata_licensing.node
219
+ ├── out/dist/index.js
220
+ └── package.json
221
+ ```
222
+
223
+ ### npm Package
224
+
225
+ The package includes prebuilt binaries for supported platforms:
226
+
227
+ ```json
228
+ {
229
+ "binary": {
230
+ "napi_versions": [8, 9]
231
+ }
232
+ }
233
+ ```
234
+
235
+ ## Documentation
236
+
237
+ Comprehensive documentation is available in the [docs/](./docs/) directory:
238
+
239
+ ### Quick Links
240
+ - **[API Reference](./docs/API.md)** - Complete API documentation and usage examples
241
+ - **[Build Instructions](./docs/BUILD.md)** - Build procedures for all architectures
242
+ - **[Deployment Guide](./docs/DEPLOYMENT.md)** - Lambda Layer deployment procedures
243
+ - **[Migration Guide](./docs/MIGRATION.md)** - Migration from TypeScript implementation
244
+ - **[Troubleshooting](./docs/TROUBLESHOOTING.md)** - Common issues and solutions
245
+ - **[Security Model](./docs/SECURITY.md)** - Threat model and security considerations
246
+ - **[Performance Benchmarks](./docs/PERFORMANCE.md)** - Performance analysis and optimization
247
+
248
+ ### Documentation Overview
249
+
250
+ | Document | Purpose | Audience |
251
+ |----------|---------|----------|
252
+ | [API Reference](./docs/API.md) | Complete API documentation | Developers |
253
+ | [Build Instructions](./docs/BUILD.md) | Build procedures and requirements | Build Engineers |
254
+ | [Deployment Guide](./docs/DEPLOYMENT.md) | Lambda Layer deployment | DevOps Engineers |
255
+ | [Migration Guide](./docs/MIGRATION.md) | TypeScript to Native migration | Developers |
256
+ | [Troubleshooting](./docs/TROUBLESHOOTING.md) | Issue diagnosis and resolution | All Users |
257
+ | [Security Model](./docs/SECURITY.md) | Security architecture and threats | Security Teams |
258
+ | [Performance](./docs/PERFORMANCE.md) | Benchmarks and optimization | Performance Engineers |
259
+
260
+ ## Quick Troubleshooting
261
+
262
+ ### Common Issues
263
+
264
+ **Native Addon Loading Fails**:
265
+ ```typescript
266
+ // Check if addon loaded successfully
267
+ const service = new NativeLicensingService();
268
+ const result = await service.checkEntitlement('123456789012');
269
+
270
+ if (result.message === 'Native validator unavailable') {
271
+ console.warn('Native addon not available, using fail-closed fallback');
272
+ }
273
+ ```
274
+
275
+ **Build Issues**:
276
+ - Missing dependencies → Install libcurl-devel, openssl-devel
277
+ - Architecture mismatch → Use Docker build for Lambda compatibility
278
+ - Node.js version → Ensure Node.js 18+ is installed
279
+
280
+ **For detailed troubleshooting**, see [Troubleshooting Guide](./docs/TROUBLESHOOTING.md).
281
+
282
+ ## Security Overview
283
+
284
+ The validator implements defense-in-depth security:
285
+
286
+ - **Tamper Resistance**: Core logic in compiled native code
287
+ - **Network Security**: Hardcoded endpoints, strict TLS, certificate pinning
288
+ - **Fail-Closed Design**: All errors result in denial of access
289
+ - **Environment Isolation**: Ignores proxy and environment variables
290
+
291
+ **For complete security analysis**, see [Security Considerations](./docs/SECURITY.md).
292
+
293
+ ## License
294
+
295
+ MIT License - see [LICENSE](LICENSE) file for details.
296
+
297
+ ## Contributing
298
+
299
+ 1. Fork the repository
300
+ 2. Create a feature branch
301
+ 3. Make changes with tests
302
+ 4. Run the full test suite
303
+ 5. Submit a pull request
304
+
305
+ All contributions must maintain the security properties and fail-closed behavior of the validator.
306
+
307
+ ## Support
308
+
309
+ For issues and questions:
310
+
311
+ 1. Check the [troubleshooting guide](#troubleshooting)
312
+ 2. Review existing [GitHub issues](https://github.com/lambda-kata/licensing/issues)
313
+ 3. Create a new issue with detailed reproduction steps
314
+
315
+ Security issues should be reported privately to the maintainers.
@@ -0,0 +1 @@
1
+ "use strict";var a=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var c=(i,t)=>()=>(i&&(t=i(i=0)),t);var f=(i,t)=>{for(var e in t)a(i,e,{get:t[e],enumerable:!0})},m=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of u(t))!v.call(i,s)&&s!==e&&a(i,s,{get:()=>t[s],enumerable:!(r=h(t,s))||r.enumerable});return i};var d=i=>m(a({},"__esModule",{value:!0}),i);function l(){let i=n.y();i.M(),i.L();let t=i.h();console.T(`[PERF] Optimizations applied - Loading: ${t.v}ms, Memory: ${Math._(t.o/1024)}KB`)}var n,p=c(()=>{"use strict";n=class i{static m=null;e;j;d;constructor(){this.j=Date.u(),this.d=process.o().I,this.e={o:0,v:0,g:0,f:0}}static y(){return i.m||(i.m=new i),i.m}M(){global.b&&global.b(),this.V(),this.C(),this.J()}L(){let t=Date.u();this.Q(),this.W(),this.X(),this.Y();let e=Date.u();this.e.v=e-t,this.e.v>100&&console.O(`[PERF] Startup time ${this.e.v}ms exceeds 100ms target`)}h(){let t=process.o().I;return this.e.o=t-this.d,{...this.e}}x(){this.e.g++}r(t){this.e.g=Math.ut(0,this.e.g-1);let e=.1;this.e.f=e*(t?1:0)+(1-e)*this.e.f}V(){process.a.D==="production"&&(process.a.R=process.a.R||"",["--optimize-for-size","--max-old-space-size=64","--gc-interval=100","--expose-gc"].Z(e=>{process.a.R.vt(e)||(process.a.R+=` ${e}`)}))}C(){let t=["Invalid account ID format","Native validator unavailable","System error","Network error","Security error","Memory allocation error"],e=new Map;t.Z(r=>{e.ft(r,r)})}J(){if(process.a.D==="test"||process.a.mt)return;let t=setInterval(()=>{let r=process.o().I-this.d;r>800*1024&&(console.O(`[PERF] Memory usage ${Math._(r/1024)}KB approaching 1MB limit`),global.b&&global.b()),this.e.o=r},3e4);process.dt("exit",()=>{clearInterval(t)})}Q(){let t=/^\d{12}$/;global.k={N:t}}W(){let t=[];for(let e=0;e<5;e++)t.tt({i:!1,s:null,F:null,U:null});global.et={it:t,gt:0}}X(){let t=[];for(let e=0;e<16;e++)t.tt("");global.yt=t}Y(){(global.k?.N||/^\d{12}$/).A("123456789012");let r=global.et;if(r){let s=r.it[0];s.i=!1}process.o()}}});var b={};f(b,{NativeLicensingService:()=>o,createLicensingService:()=>y,default:()=>g});module.exports=d(b);function y(){return new o}var o,g,x=c(()=>{p();l();o=class{p=null;c=!1;t;constructor(){this.t=n.y()}async S(t){this.t.x();try{if(!this.B(t))return this.l("Invalid account ID format provided",{nt:typeof t=="string"?t.H:"not-string",ot:typeof t}),this.t.r(!1),{i:!1,s:"Invalid account ID format"};if(this.c||this.K(),!this.p)return this.l("Native validator unavailable",{c:this.c}),this.t.r(!1),{i:!1,s:"Native validator unavailable"};let e=await this.p.S(t);this.w("Validation completed",{i:e.i,at:!!e.F,ct:!!e.s,lt:!!e.U});let s=this.t.h().f>.3;return this.t.r(s),e}catch(e){return this.l("Unexpected error during validation",{q:e instanceof Error?e.constructor.E:typeof e,G:this.z(e)}),this.t.r(!1),{i:!1,s:"System error"}}}pt(t){this.t.x();try{if(!this.B(t))return this.l("Invalid account ID format provided (sync)",{nt:typeof t=="string"?t.H:"not-string",ot:typeof t}),this.t.r(!1),{i:!1,s:"Invalid account ID format"};if(this.c||this.K(),!this.p)return this.l("Native validator unavailable (sync)",{c:this.c}),this.t.r(!1),{i:!1,s:"Native validator unavailable"};let e=this.p.pt(t);return this.w("Sync validation completed",{i:e.i,at:!!e.F,ct:!!e.s,lt:!!e.U}),this.t.r(!0),e}catch(e){return this.l("Unexpected error during sync validation",{q:e instanceof Error?e.constructor.E:typeof e,G:this.z(e)}),this.t.r(!1),{i:!1,s:"System error"}}}st(){return this.t.h()}B(t){return typeof t!="string"||t.H!==12?!1:/^\d{12}$/.A(t)}K(){this.c=!0;try{this.p=require("../build/Release/lambda_kata_licensing.node"),this.w("Native addon loaded successfully",{})}catch(t){this.l("Failed to load native licensing validator",{q:t instanceof Error?t.constructor.E:typeof t,G:this.z(t)}),this.p=null}}$(){return process.a.D==="production"}z(t){return this.$()?t instanceof Error?`${t.constructor.E} occurred`:"Unknown error occurred":t instanceof Error?t.s:typeof t=="string"?t:String(t)}w(t,e){this.$()?console.T(`[INFO] native-licensing-validator: ${t}`):console.T(`[INFO] native-licensing-validator: ${t}`,e)}l(t,e){this.$()?console.ht("[ERROR] native-licensing-validator: System error occurred"):console.ht(`[ERROR] native-licensing-validator: ${t}`,e)}},g=o});x();0&&(module.exports={NativeLicensingService,createLicensingService});
@@ -0,0 +1,218 @@
1
+ /**
2
+ * @fileoverview Native Licensing Validator
3
+ *
4
+ * This module provides a tamper - resistant native licensing validator
5
+ * for the Lambda Kata SST Integration workspace.It implements the
6
+ * existing LicensingService interface while providing enhanced security
7
+ * through native C implementation.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { NativeLicensingService } from '@lambda-kata/licensing';
12
+ *
13
+ * const service = new NativeLicensingService();
14
+ * const result = await service.checkEntitlement('123456789012');
15
+ * console.log(result.entitled); // true or false
16
+ * ```
17
+ */
18
+ /**
19
+ * @interface LicensingResponse
20
+ *
21
+ * Response format for licensing validation checks.
22
+ * Compatible with existing HttpLicensingService interface.
23
+ */
24
+ export interface LicensingResponse {
25
+ /** Whether the account is entitled to use Lambda Kata */
26
+ entitled: boolean;
27
+ /** Customer-specific Lambda Layer ARN (if entitled) */
28
+ layerArn?: string;
29
+ /** Human-readable status message */
30
+ message?: string;
31
+ /** ISO 8601 expiration timestamp (if applicable) */
32
+ expiresAt?: string;
33
+ }
34
+ /**
35
+ * @interface LicensingService
36
+ *
37
+ * Interface for licensing validation services.
38
+ * Maintains compatibility with existing SST integration packages.
39
+ */
40
+ export interface LicensingService {
41
+ /**
42
+ * Check entitlement for an AWS account (async)
43
+ *
44
+ * @param accountId - 12-digit AWS account ID
45
+ * @returns Promise resolving to licensing response
46
+ */
47
+ checkEntitlement(accountId: string): Promise<LicensingResponse>;
48
+ /**
49
+ * Check entitlement for an AWS account (sync)
50
+ *
51
+ * WARNING: This method blocks the Node.js event loop.
52
+ * Use only when async operations are not possible (e.g., CDK synthesis).
53
+ *
54
+ * This method is optional for backward compatibility with existing
55
+ * implementations that only provide async validation.
56
+ *
57
+ * @param accountId - 12-digit AWS account ID
58
+ * @returns Licensing response (synchronous)
59
+ */
60
+ checkEntitlementSync?(accountId: string): LicensingResponse;
61
+ }
62
+ /**
63
+ * @class NativeLicensingService
64
+ *
65
+ * Tamper-resistant native licensing validator implementation.
66
+ *
67
+ * This class provides a secure implementation of the LicensingService
68
+ * interface using a native C addon. It implements fail-closed security
69
+ * where any error condition results in denying access.
70
+ *
71
+ * @remarks Validates: Requirements 6.1, 6.2, 6.3, 6.4, 6.5
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const service = new NativeLicensingService();
76
+ *
77
+ * // Check entitlement for an account
78
+ * const result = await service.checkEntitlement('123456789012');
79
+ * if (result.entitled) {
80
+ * console.log(`Layer ARN: ${result.layerArn}`);
81
+ * }
82
+ * ```
83
+ */
84
+ export declare class NativeLicensingService implements LicensingService {
85
+ private addon;
86
+ private addonLoadAttempted;
87
+ private performanceOptimizer;
88
+ /**
89
+ * Create a new NativeLicensingService instance
90
+ *
91
+ * The native addon is loaded lazily on first use to avoid
92
+ * blocking the constructor if the addon is unavailable.
93
+ */
94
+ constructor();
95
+ /**
96
+ * Check entitlement for an AWS account
97
+ *
98
+ * This method validates the account ID format and delegates to the
99
+ * native addon for secure validation. If the addon is unavailable,
100
+ * it returns a fail-closed response.
101
+ *
102
+ * @param accountId - 12-digit AWS account ID string
103
+ * @returns Promise resolving to licensing response
104
+ *
105
+ * @throws Never throws - all errors result in fail-closed response
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const service = new NativeLicensingService();
110
+ * const result = await service.checkEntitlement('123456789012');
111
+ * ```
112
+ */
113
+ checkEntitlement(accountId: string): Promise<LicensingResponse>;
114
+ /**
115
+ * Check entitlement for an AWS account SYNCHRONOUSLY
116
+ *
117
+ * WARNING: This method blocks the Node.js event loop.
118
+ * Use only when async operations are not possible (e.g., CDK synthesis).
119
+ *
120
+ * This method validates the account ID format and delegates to the
121
+ * native addon for secure validation. If the addon is unavailable,
122
+ * it returns a fail-closed response.
123
+ *
124
+ * @param accountId - 12-digit AWS account ID string
125
+ * @returns Licensing response (synchronous)
126
+ *
127
+ * @throws Never throws - all errors result in fail-closed response
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * const service = new NativeLicensingService();
132
+ * const result = service.checkEntitlementSync('123456789012');
133
+ * ```
134
+ */
135
+ checkEntitlementSync(accountId: string): LicensingResponse;
136
+ /**
137
+ * Get current performance metrics
138
+ *
139
+ * @returns Current performance metrics including memory usage and timing
140
+ */
141
+ getPerformanceMetrics(): import("./performance-optimizations").PerformanceMetrics;
142
+ /**
143
+ * Validate account ID format
144
+ *
145
+ * Checks that the account ID is a 12-digit string.
146
+ * This validation is performed in JavaScript for fail-fast behavior.
147
+ *
148
+ * @param accountId - Account ID to validate
149
+ * @returns True if valid format, false otherwise
150
+ *
151
+ * @private
152
+ */
153
+ private isValidAccountId;
154
+ /**
155
+ * Load the native addon
156
+ *
157
+ * Attempts to load the native addon module. If loading fails,
158
+ * the addon remains null and all requests will fail closed.
159
+ *
160
+ * @private
161
+ */
162
+ private loadAddon;
163
+ /**
164
+ * Check if running in production mode
165
+ *
166
+ * @returns True if production mode, false otherwise
167
+ * @private
168
+ */
169
+ private isProductionMode;
170
+ /**
171
+ * Sanitize error message for logging
172
+ *
173
+ * Removes potentially sensitive information from error messages
174
+ * in production mode.
175
+ *
176
+ * @param error - Error object or message
177
+ * @returns Sanitized error message
178
+ * @private
179
+ */
180
+ private sanitizeErrorMessage;
181
+ /**
182
+ * Log informational message
183
+ *
184
+ * @param message - Log message
185
+ * @param context - Additional context (will be sanitized)
186
+ * @private
187
+ */
188
+ private logInfo;
189
+ /**
190
+ * Log error message
191
+ *
192
+ * @param message - Error message
193
+ * @param context - Additional context (will be sanitized)
194
+ * @private
195
+ */
196
+ private logError;
197
+ }
198
+ /**
199
+ * Default export for convenience
200
+ */
201
+ export default NativeLicensingService;
202
+ /**
203
+ * Create a new NativeLicensingService instance
204
+ *
205
+ * Factory function for creating licensing service instances.
206
+ *
207
+ * @returns New NativeLicensingService instance
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * import { createLicensingService } from '@lambda-kata/licensing';
212
+ *
213
+ * const service = createLicensingService();
214
+ * const result = await service.checkEntitlement('123456789012');
215
+ * ```
216
+ */
217
+ export declare function createLicensingService(): LicensingService;
218
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEhE;;;;;;;;;;;OAWG;IACH,oBAAoB,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAAC;CAC7D;AAaD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,sBAAuB,YAAW,gBAAgB;IAC7D,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,oBAAoB,CAAuB;IAEnD;;;;;OAKG;;IAQH;;;;;;;;;;;;;;;;;OAiBG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoErE;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB;IAkE1D;;;;OAIG;IACH,qBAAqB;IAIrB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAqBjB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAsB5B;;;;;;OAMG;IACH,OAAO,CAAC,OAAO;IAUf;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;CASjB;AAED;;GAEG;AACH,eAAe,sBAAsB,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @fileoverview Performance optimizations for native licensing validator
3
+ *
4
+ * This module implements memory usage and startup time optimizations
5
+ * to meet the performance requirements (< 1MB memory, 100ms addon loading).
6
+ *
7
+ * @remarks Validates: Requirements 10.2, 10.4
8
+ */
9
+ /**
10
+ * @interface PerformanceMetrics
11
+ *
12
+ * Structure for tracking performance metrics during operation.
13
+ */
14
+ export interface PerformanceMetrics {
15
+ /** Memory usage in bytes */
16
+ memoryUsage: number;
17
+ /** Addon loading time in milliseconds */
18
+ loadingTime: number;
19
+ /** Number of active requests */
20
+ activeRequests: number;
21
+ /** Cache hit rate (0-1) */
22
+ cacheHitRate: number;
23
+ }
24
+ /**
25
+ * @class PerformanceOptimizer
26
+ *
27
+ * Implements performance optimizations for the native licensing validator.
28
+ * Focuses on memory efficiency and fast startup times.
29
+ */
30
+ export declare class PerformanceOptimizer {
31
+ private static instance;
32
+ private metrics;
33
+ private startupTime;
34
+ private memoryBaseline;
35
+ private constructor();
36
+ /**
37
+ * Get singleton instance of performance optimizer
38
+ *
39
+ * @returns PerformanceOptimizer instance
40
+ */
41
+ static getInstance(): PerformanceOptimizer;
42
+ /**
43
+ * Optimize memory usage by implementing lazy loading and resource pooling
44
+ *
45
+ * This method implements several memory optimization strategies:
46
+ * 1. Lazy addon loading to avoid upfront memory allocation
47
+ * 2. String interning for common messages
48
+ * 3. Memory pool for frequently allocated structures
49
+ * 4. Garbage collection hints for V8
50
+ */
51
+ optimizeMemoryUsage(): void;
52
+ /**
53
+ * Optimize startup time by preloading critical resources
54
+ *
55
+ * This method implements startup optimizations:
56
+ * 1. Precompile frequently used regular expressions
57
+ * 2. Pre-allocate small object pools
58
+ * 3. Initialize cache structures
59
+ * 4. Warm up critical code paths
60
+ */
61
+ optimizeStartupTime(): void;
62
+ /**
63
+ * Get current performance metrics
64
+ *
65
+ * @returns Current performance metrics
66
+ */
67
+ getMetrics(): PerformanceMetrics;
68
+ /**
69
+ * Track request start for performance monitoring
70
+ */
71
+ trackRequestStart(): void;
72
+ /**
73
+ * Track request end for performance monitoring
74
+ *
75
+ * @param cacheHit Whether this request was a cache hit
76
+ */
77
+ trackRequestEnd(cacheHit: boolean): void;
78
+ /**
79
+ * Configure V8 memory optimizations
80
+ *
81
+ * @private
82
+ */
83
+ private configureV8MemoryOptimizations;
84
+ /**
85
+ * Initialize string interning for common messages
86
+ *
87
+ * @private
88
+ */
89
+ private initializeStringInterning;
90
+ /**
91
+ * Setup memory monitoring
92
+ *
93
+ * @private
94
+ */
95
+ private setupMemoryMonitoring;
96
+ /**
97
+ * Precompile regex patterns for performance
98
+ *
99
+ * @private
100
+ */
101
+ private precompileRegexPatterns;
102
+ /**
103
+ * Initialize object pools for frequently allocated objects
104
+ *
105
+ * @private
106
+ */
107
+ private initializeObjectPools;
108
+ /**
109
+ * Initialize optimized cache settings
110
+ *
111
+ * @private
112
+ */
113
+ private initializeOptimizedCache;
114
+ /**
115
+ * Warm up critical code paths
116
+ *
117
+ * @private
118
+ */
119
+ private warmupCodePaths;
120
+ }
121
+ /**
122
+ * @class OptimizedNativeLicensingService
123
+ *
124
+ * Performance-optimized version of NativeLicensingService that implements
125
+ * memory and startup time optimizations.
126
+ */
127
+ export declare class OptimizedNativeLicensingService {
128
+ private optimizer;
129
+ private baseService;
130
+ constructor();
131
+ /**
132
+ * Lazy load the base service to minimize startup time
133
+ *
134
+ * @private
135
+ */
136
+ private loadBaseService;
137
+ /**
138
+ * Optimized checkEntitlement method
139
+ *
140
+ * @param accountId Account ID to check
141
+ * @returns Promise resolving to licensing response
142
+ */
143
+ checkEntitlement(accountId: string): Promise<any>;
144
+ /**
145
+ * Get performance metrics
146
+ *
147
+ * @returns Current performance metrics
148
+ */
149
+ getPerformanceMetrics(): PerformanceMetrics;
150
+ }
151
+ /**
152
+ * Factory function for creating optimized licensing service
153
+ *
154
+ * @returns Optimized licensing service instance
155
+ */
156
+ export declare function createOptimizedLicensingService(): OptimizedNativeLicensingService;
157
+ /**
158
+ * Apply global performance optimizations
159
+ *
160
+ * This function should be called once during module initialization
161
+ * to apply system-wide performance optimizations.
162
+ */
163
+ export declare function applyGlobalOptimizations(): void;
164
+ //# sourceMappingURL=performance-optimizations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance-optimizations.d.ts","sourceRoot":"","sources":["../../src/performance-optimizations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAC5D,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO;IAWP;;;;OAIG;WACW,WAAW,IAAI,oBAAoB;IAOjD;;;;;;;;OAQG;IACI,mBAAmB,IAAI,IAAI;IAiBlC;;;;;;;;OAQG;IACI,mBAAmB,IAAI,IAAI;IAwBlC;;;;OAIG;IACI,UAAU,IAAI,kBAAkB;IAOvC;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAIhC;;;;OAIG;IACI,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAQ/C;;;;OAIG;IACH,OAAO,CAAC,8BAA8B;IAwBtC;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAoBjC;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAmB7B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAahC;;;;OAIG;IACH,OAAO,CAAC,eAAe;CAgBxB;AAED;;;;;GAKG;AACH,qBAAa,+BAA+B;IAC1C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAAM;;IAUzB;;;;OAIG;YACW,eAAe;IAgB7B;;;;;OAKG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAkCvD;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB;CAG5C;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,+BAA+B,CAEjF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAQ/C"}
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@lambda-kata/licensing",
3
+ "version": "0.1.0",
4
+ "description": "Tamper-resistant native licensing validator for Lambda Kata Integration",
5
+ "main": "out/dist/index.js",
6
+ "types": "out/tsc/index.d.ts",
7
+ "license": "SEE LICENSE IN LICENSE",
8
+ "author": "Lambda Kata Team",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/lambda-kata/licensing.git"
12
+ },
13
+ "keywords": [
14
+ "lambda-kata",
15
+ "licensing",
16
+ "native",
17
+ "node-api",
18
+ "security",
19
+ "aws-lambda"
20
+ ],
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "os": [
25
+ "linux"
26
+ ],
27
+ "cpu": [
28
+ "x64",
29
+ "arm64"
30
+ ],
31
+ "scripts": {
32
+ "build": "yarn build:clean && yarn build:native && yarn build:ts && yarn build:types",
33
+ "build:clean": "rm -rf out/ build/ prebuilt/",
34
+ "build:native": "node-gyp rebuild || echo 'Native build failed - addon will be unavailable'",
35
+ "build:native:docker": "./scripts/build-docker.sh",
36
+ "build:ts": "esbuild src/index.ts --bundle --platform=node --target=node18 --format=cjs --outfile=out/dist/index.js --tree-shaking=true --minify --mangle-props=^[a-zA-Z_$][a-zA-Z0-9_$]*$ --external:*.node",
37
+ "build:types": "tsc --emitDeclarationOnly --outDir out/tsc",
38
+ "build:all": "./scripts/build-all.sh",
39
+ "build:prebuilt": "./scripts/build-prebuilt.sh",
40
+ "test": "npx jest --runInBand --colors --verbose --testTimeout=15000 --forceExit --detectOpenHandles --no-cache",
41
+ "test:watch": "npx jest --watch --testTimeout=15000 --runInBand --no-cache",
42
+ "test:coverage": "npx jest --coverage --runInBand --colors --verbose --testTimeout=15000 --forceExit --detectOpenHandles --no-cache",
43
+ "test:safe": "npx jest --runInBand --colors --verbose --testTimeout=10000 --forceExit --detectOpenHandles --no-cache --testPathIgnorePatterns='.*\\.property\\.test\\.ts'",
44
+ "test:unit": "npx jest --runInBand --colors --verbose --testTimeout=10000 --forceExit --detectOpenHandles --no-cache --testPathPattern='.*\\.test\\.ts' --testPathIgnorePatterns='.*\\.property\\.test\\.ts'",
45
+ "test:property": "npx jest --runInBand --colors --verbose --testTimeout=20000 --forceExit --detectOpenHandles --no-cache --testPathPattern='.*\\.property\\.test\\.ts'",
46
+ "test:deployment": "./scripts/test-deployment.sh",
47
+ "lint": "eslint src/ test/ --ext .ts",
48
+ "lint:fix": "eslint src/ test/ --ext .ts --fix",
49
+ "docs": "typedoc src/index.ts --out docs/",
50
+ "prepack": "yarn build:prebuilt || echo 'WARNING: Prebuilt binaries not available, package may not work correctly'",
51
+ "install": "node scripts/install.js",
52
+ "postinstall": "node scripts/postinstall.js || echo 'Postinstall script failed, using fallback mode'"
53
+ },
54
+ "files": [
55
+ "out/",
56
+ "prebuilt/",
57
+ "README.md",
58
+ "LICENSE"
59
+ ],
60
+ "dependencies": {
61
+ "node-addon-api": "^7.0.0"
62
+ },
63
+ "devDependencies": {
64
+ "@types/jest": "^29.5.0",
65
+ "@types/node": "^20.0.0",
66
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
67
+ "@typescript-eslint/parser": "^6.0.0",
68
+ "esbuild": "^0.19.0",
69
+ "eslint": "^8.0.0",
70
+ "fast-check": "^3.15.0",
71
+ "jest": "^29.5.0",
72
+ "node-gyp": "^10.0.0",
73
+ "ts-jest": "^29.1.0",
74
+ "typedoc": "^0.25.0",
75
+ "typescript": "^5.0.0"
76
+ },
77
+ "peerDependencies": {
78
+ "aws-cdk-lib": "^2.0.0",
79
+ "constructs": "^10.0.0"
80
+ },
81
+ "peerDependenciesMeta": {
82
+ "aws-cdk-lib": {
83
+ "optional": true
84
+ },
85
+ "constructs": {
86
+ "optional": true
87
+ }
88
+ },
89
+ "gypfile": true,
90
+ "binary": {
91
+ "napi_versions": [
92
+ 8,
93
+ 9
94
+ ]
95
+ }
96
+ }