@flipboxlabs/aws-audit-sdk 1.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 +21 -0
- package/README.md +30 -0
- package/dist/audits.d.ts +188 -0
- package/dist/audits.d.ts.map +1 -0
- package/dist/audits.js +225 -0
- package/dist/batch/batch-processor.d.ts +81 -0
- package/dist/batch/batch-processor.d.ts.map +1 -0
- package/dist/batch/batch-processor.js +102 -0
- package/dist/batch/index.d.ts +2 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/batch/index.js +1 -0
- package/dist/config.d.ts +65 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +44 -0
- package/dist/constants.d.ts +147 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +191 -0
- package/dist/events/batch-handler.d.ts +62 -0
- package/dist/events/batch-handler.d.ts.map +1 -0
- package/dist/events/batch-handler.js +92 -0
- package/dist/events/bus.d.ts +79 -0
- package/dist/events/bus.d.ts.map +1 -0
- package/dist/events/bus.js +86 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +2 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/middleware/middy.d.ts +66 -0
- package/dist/middleware/middy.d.ts.map +1 -0
- package/dist/middleware/middy.js +105 -0
- package/dist/repository.d.ts +421 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +486 -0
- package/dist/repository.utils.d.ts +37 -0
- package/dist/repository.utils.d.ts.map +1 -0
- package/dist/repository.utils.js +70 -0
- package/dist/schema/audit.d.ts +202 -0
- package/dist/schema/audit.d.ts.map +1 -0
- package/dist/schema/audit.js +48 -0
- package/dist/schema/common.d.ts +128 -0
- package/dist/schema/common.d.ts.map +1 -0
- package/dist/schema/common.js +148 -0
- package/dist/schema/index.d.ts +27 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +26 -0
- package/dist/schema/log.d.ts +211 -0
- package/dist/schema/log.d.ts.map +1 -0
- package/dist/schema/log.js +179 -0
- package/dist/schema/model.d.ts +110 -0
- package/dist/schema/model.d.ts.map +1 -0
- package/dist/schema/model.js +86 -0
- package/dist/schema/service.d.ts +189 -0
- package/dist/schema/service.d.ts.map +1 -0
- package/dist/schema/service.js +89 -0
- package/dist/schema/storage.d.ts +105 -0
- package/dist/schema/storage.d.ts.map +1 -0
- package/dist/schema/storage.js +63 -0
- package/dist/service.d.ts +285 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +237 -0
- package/dist/test-config.d.ts +56 -0
- package/dist/test-config.d.ts.map +1 -0
- package/dist/test-config.js +24 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +231 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +313 -0
- package/package.json +85 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Flipbox Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @flipboxlabs/aws-audit-sdk
|
|
2
|
+
|
|
3
|
+
AWS Audit SDK - Core SDK for audit logging and event management.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @flipboxlabs/aws-audit-sdk
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @flipboxlabs/aws-audit-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { Audits, defineAuditConfig } from '@flipboxlabs/aws-audit-sdk';
|
|
17
|
+
import { logAudits } from '@flipboxlabs/aws-audit-sdk/middleware';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Audit logging with structured data
|
|
23
|
+
- EventBridge integration
|
|
24
|
+
- DynamoDB storage
|
|
25
|
+
- Middy middleware support
|
|
26
|
+
- Batch processing utilities
|
|
27
|
+
|
|
28
|
+
## License
|
|
29
|
+
|
|
30
|
+
MIT
|
package/dist/audits.d.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type { GenericLogger } from "@aws-lambda-powertools/commons/types";
|
|
2
|
+
import type { AuditConfig } from "./config.js";
|
|
3
|
+
import { type LogAuditInput } from "./schema/log.js";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the Audits class.
|
|
6
|
+
*/
|
|
7
|
+
export type AuditsOptions<C extends AuditConfig> = {
|
|
8
|
+
/**
|
|
9
|
+
* Custom logger for debug, warning, and error messages.
|
|
10
|
+
* If not provided, a Console instance is used.
|
|
11
|
+
* Note: Audit logs are always written to stdout regardless of this setting.
|
|
12
|
+
*/
|
|
13
|
+
logger?: GenericLogger;
|
|
14
|
+
/**
|
|
15
|
+
* Audit configuration for strict typing of app and resourceType fields.
|
|
16
|
+
* TypeScript will enforce correct app/type values at compile time and
|
|
17
|
+
* runtime validation occurs against the config schemas.
|
|
18
|
+
*/
|
|
19
|
+
config: C;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Strictly typed audit input based on the provided config.
|
|
23
|
+
* Replaces generic string types with the specific app and resourceType unions.
|
|
24
|
+
*/
|
|
25
|
+
export type StrictLogAuditInput<C extends AuditConfig> = Omit<LogAuditInput, "target" | "source" | "resources"> & {
|
|
26
|
+
target: {
|
|
27
|
+
app: C["_types"]["App"];
|
|
28
|
+
type: C["_types"]["ResourceType"];
|
|
29
|
+
id?: string | number;
|
|
30
|
+
};
|
|
31
|
+
source?: {
|
|
32
|
+
app: C["_types"]["App"];
|
|
33
|
+
type: C["_types"]["ResourceType"];
|
|
34
|
+
id?: string | number;
|
|
35
|
+
};
|
|
36
|
+
resources?: Array<{
|
|
37
|
+
app: C["_types"]["App"];
|
|
38
|
+
type: C["_types"]["ResourceType"];
|
|
39
|
+
id?: string | number;
|
|
40
|
+
}> | Set<{
|
|
41
|
+
app: C["_types"]["App"];
|
|
42
|
+
type: C["_types"]["ResourceType"];
|
|
43
|
+
id?: string | number;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Manages audit log collection and emission for AWS Lambda functions.
|
|
48
|
+
*
|
|
49
|
+
* Buffers audit entries and emits them as structured JSON logs to stdout,
|
|
50
|
+
* which can be captured by CloudWatch Logs and processed by subscription filters.
|
|
51
|
+
*
|
|
52
|
+
* Features:
|
|
53
|
+
* - Automatic buffering with configurable flush threshold
|
|
54
|
+
* - X-Ray trace ID injection for distributed tracing
|
|
55
|
+
* - Environment-based enable/disable control
|
|
56
|
+
* - Schema validation via Zod before emission
|
|
57
|
+
* - Strict typing for app and resourceType via config
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const config = defineAuditConfig({
|
|
62
|
+
* apps: ['Orders', 'Inventory'] as const,
|
|
63
|
+
* resourceTypes: ['Order', 'Product'] as const,
|
|
64
|
+
* });
|
|
65
|
+
*
|
|
66
|
+
* const audits = new Audits({ config });
|
|
67
|
+
*
|
|
68
|
+
* audits.addAudit({
|
|
69
|
+
* operation: 'createOrder',
|
|
70
|
+
* target: { app: 'Orders', type: 'Order', id: '123' }, // Strictly typed!
|
|
71
|
+
* status: Status.SUCCESS,
|
|
72
|
+
* });
|
|
73
|
+
*
|
|
74
|
+
* // Flush at end of Lambda execution
|
|
75
|
+
* audits.publishStoredAudits();
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare class Audits<C extends AuditConfig> {
|
|
79
|
+
#private;
|
|
80
|
+
/**
|
|
81
|
+
* Console instance for emitting audit logs to stdout.
|
|
82
|
+
* Uses a dedicated Console instance in Lambda for isolation from custom loggers.
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
private console;
|
|
86
|
+
/**
|
|
87
|
+
* Logger for debug, warning, and error messages (not audit logs).
|
|
88
|
+
*/
|
|
89
|
+
readonly logger: GenericLogger;
|
|
90
|
+
/**
|
|
91
|
+
* Whether audit emission is disabled.
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
private disabled;
|
|
95
|
+
/**
|
|
96
|
+
* X-Ray trace ID from the Lambda environment, if available.
|
|
97
|
+
* Automatically injected into audit entries that don't have a trace ID.
|
|
98
|
+
*/
|
|
99
|
+
readonly traceId: string | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Buffer of audit entries waiting to be published.
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
private storedAudits;
|
|
105
|
+
/**
|
|
106
|
+
* Audit configuration for strict typing validation.
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
private readonly config;
|
|
110
|
+
/**
|
|
111
|
+
* Creates a new Audits instance.
|
|
112
|
+
*
|
|
113
|
+
* Initializes the console, reads environment configuration, and captures
|
|
114
|
+
* the X-Ray trace ID from the Lambda environment.
|
|
115
|
+
*
|
|
116
|
+
* @param options - Configuration options including the required audit config
|
|
117
|
+
*/
|
|
118
|
+
constructor(options: AuditsOptions<C>);
|
|
119
|
+
/**
|
|
120
|
+
* Checks whether audit emission is currently disabled.
|
|
121
|
+
*
|
|
122
|
+
* @returns True if audits are disabled, false otherwise
|
|
123
|
+
*/
|
|
124
|
+
protected isDisabled(): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Clears all buffered audit entries without publishing them.
|
|
127
|
+
*/
|
|
128
|
+
protected clearAudits(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Adds an audit entry to the buffer.
|
|
131
|
+
*
|
|
132
|
+
* If the buffer reaches MAX_AUDITS_SIZE, automatically triggers
|
|
133
|
+
* a flush to prevent unbounded memory growth.
|
|
134
|
+
*
|
|
135
|
+
* The input is validated against the config's schemas at runtime
|
|
136
|
+
* and TypeScript enforces strict typing at compile time.
|
|
137
|
+
*
|
|
138
|
+
* @param item - The audit entry to buffer
|
|
139
|
+
*/
|
|
140
|
+
addAudit(item: StrictLogAuditInput<C>): void;
|
|
141
|
+
/**
|
|
142
|
+
* Publishes all buffered audit entries to stdout and clears the buffer.
|
|
143
|
+
*
|
|
144
|
+
* Each audit entry is:
|
|
145
|
+
* 1. Injected with the X-Ray trace ID if not already set
|
|
146
|
+
* 2. Validated and transformed through LogAuditSchema (or typed schema if config provided)
|
|
147
|
+
* 3. Emitted as JSON with the AUDIT_LOG_IDENTIFIER wrapper
|
|
148
|
+
*
|
|
149
|
+
* If audits are disabled, the buffer is cleared without emission.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* // Manual flush at end of handler
|
|
154
|
+
* audits.publishStoredAudits();
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
publishStoredAudits(): void;
|
|
158
|
+
/**
|
|
159
|
+
* Initializes the console instance based on environment mode.
|
|
160
|
+
*
|
|
161
|
+
* In production (non-dev mode), creates a dedicated Console instance
|
|
162
|
+
* writing to process.stdout/stderr. In dev mode, uses the global console
|
|
163
|
+
* for better local debugging experience.
|
|
164
|
+
*
|
|
165
|
+
* @internal
|
|
166
|
+
*/
|
|
167
|
+
private setConsole;
|
|
168
|
+
/**
|
|
169
|
+
* Reads and caches environment configuration values.
|
|
170
|
+
*
|
|
171
|
+
* Checks POWERTOOLS_AUDITS_DISABLED and POWERTOOLS_DEV environment
|
|
172
|
+
* variables using AWS Lambda Powertools utilities.
|
|
173
|
+
*
|
|
174
|
+
* @internal
|
|
175
|
+
*/
|
|
176
|
+
private setEnvConfig;
|
|
177
|
+
/**
|
|
178
|
+
* Determines whether audits should be disabled based on environment.
|
|
179
|
+
*
|
|
180
|
+
* Priority:
|
|
181
|
+
* 1. POWERTOOLS_AUDITS_DISABLED takes precedence if explicitly set
|
|
182
|
+
* 2. Otherwise, audits are disabled in dev mode (POWERTOOLS_DEV=true)
|
|
183
|
+
*
|
|
184
|
+
* @internal
|
|
185
|
+
*/
|
|
186
|
+
private setDisabled;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=audits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audits.d.ts","sourceRoot":"","sources":["../src/audits.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAM1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAQhF;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,IAAI;IAClD;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;;;OAIG;IACH,MAAM,EAAE,CAAC,CAAC;CACV,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,WAAW,IAAI,IAAI,CAC5D,aAAa,EACb,QAAQ,GAAG,QAAQ,GAAG,WAAW,CACjC,GAAG;IACH,MAAM,EAAE;QACP,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;QAClC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,CAAC,EAAE;QACR,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;QAClC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACrB,CAAC;IACF,SAAS,CAAC,EACP,KAAK,CAAC;QACN,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;QAClC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACpB,CAAC,GACF,GAAG,CAAC;QACJ,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;QAClC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACpB,CAAC,CAAC;CACN,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,MAAM,CAAC,CAAC,SAAS,WAAW;;IACxC;;;;OAIG;IACH,OAAO,CAAC,OAAO,CAAW;IAE1B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAE/B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAS;IAWzB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC;;;OAGG;IACH,OAAO,CAAC,YAAY,CAA4B;IAEhD;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAI;IAE3B;;;;;;;OAOG;gBACgB,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;IAU5C;;;;OAIG;IACH,SAAS,CAAC,UAAU,IAAI,OAAO;IAI/B;;OAEG;IACH,SAAS,CAAC,WAAW,IAAI,IAAI;IAI7B;;;;;;;;;;OAUG;IACI,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI;IAsBnD;;;;;;;;;;;;;;;OAeG;IACI,mBAAmB,IAAI,IAAI;IAwBlC;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAWlB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;CAUnB"}
|
package/dist/audits.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { Console } from "node:console";
|
|
2
|
+
import { getBooleanFromEnv, getXRayTraceIdFromEnv, isDevMode, } from "@aws-lambda-powertools/commons/utils/env";
|
|
3
|
+
import { AUDIT_LOG_IDENTIFIER } from "./constants.js";
|
|
4
|
+
import { createTypedLogAuditSchema } from "./schema/log.js";
|
|
5
|
+
/**
|
|
6
|
+
* Maximum number of audit entries that can be buffered before automatic flush.
|
|
7
|
+
* When this limit is reached, audits are automatically published to prevent memory issues.
|
|
8
|
+
*/
|
|
9
|
+
const MAX_AUDITS_SIZE = 20;
|
|
10
|
+
/**
|
|
11
|
+
* Manages audit log collection and emission for AWS Lambda functions.
|
|
12
|
+
*
|
|
13
|
+
* Buffers audit entries and emits them as structured JSON logs to stdout,
|
|
14
|
+
* which can be captured by CloudWatch Logs and processed by subscription filters.
|
|
15
|
+
*
|
|
16
|
+
* Features:
|
|
17
|
+
* - Automatic buffering with configurable flush threshold
|
|
18
|
+
* - X-Ray trace ID injection for distributed tracing
|
|
19
|
+
* - Environment-based enable/disable control
|
|
20
|
+
* - Schema validation via Zod before emission
|
|
21
|
+
* - Strict typing for app and resourceType via config
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const config = defineAuditConfig({
|
|
26
|
+
* apps: ['Orders', 'Inventory'] as const,
|
|
27
|
+
* resourceTypes: ['Order', 'Product'] as const,
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* const audits = new Audits({ config });
|
|
31
|
+
*
|
|
32
|
+
* audits.addAudit({
|
|
33
|
+
* operation: 'createOrder',
|
|
34
|
+
* target: { app: 'Orders', type: 'Order', id: '123' }, // Strictly typed!
|
|
35
|
+
* status: Status.SUCCESS,
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Flush at end of Lambda execution
|
|
39
|
+
* audits.publishStoredAudits();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class Audits {
|
|
43
|
+
/**
|
|
44
|
+
* Console instance for emitting audit logs to stdout.
|
|
45
|
+
* Uses a dedicated Console instance in Lambda for isolation from custom loggers.
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
console;
|
|
49
|
+
/**
|
|
50
|
+
* Logger for debug, warning, and error messages (not audit logs).
|
|
51
|
+
*/
|
|
52
|
+
logger;
|
|
53
|
+
/**
|
|
54
|
+
* Whether audit emission is disabled.
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
disabled = false;
|
|
58
|
+
/**
|
|
59
|
+
* Cached environment configuration values.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
#envConfig = {
|
|
63
|
+
disabled: false,
|
|
64
|
+
devMode: false,
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* X-Ray trace ID from the Lambda environment, if available.
|
|
68
|
+
* Automatically injected into audit entries that don't have a trace ID.
|
|
69
|
+
*/
|
|
70
|
+
traceId;
|
|
71
|
+
/**
|
|
72
|
+
* Buffer of audit entries waiting to be published.
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
storedAudits = [];
|
|
76
|
+
/**
|
|
77
|
+
* Audit configuration for strict typing validation.
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
config;
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new Audits instance.
|
|
83
|
+
*
|
|
84
|
+
* Initializes the console, reads environment configuration, and captures
|
|
85
|
+
* the X-Ray trace ID from the Lambda environment.
|
|
86
|
+
*
|
|
87
|
+
* @param options - Configuration options including the required audit config
|
|
88
|
+
*/
|
|
89
|
+
constructor(options) {
|
|
90
|
+
this.setEnvConfig();
|
|
91
|
+
this.setConsole();
|
|
92
|
+
this.setDisabled();
|
|
93
|
+
this.logger = options.logger || this.console;
|
|
94
|
+
this.config = options.config;
|
|
95
|
+
this.traceId = getXRayTraceIdFromEnv();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Checks whether audit emission is currently disabled.
|
|
99
|
+
*
|
|
100
|
+
* @returns True if audits are disabled, false otherwise
|
|
101
|
+
*/
|
|
102
|
+
isDisabled() {
|
|
103
|
+
return this.disabled;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Clears all buffered audit entries without publishing them.
|
|
107
|
+
*/
|
|
108
|
+
clearAudits() {
|
|
109
|
+
this.storedAudits = [];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Adds an audit entry to the buffer.
|
|
113
|
+
*
|
|
114
|
+
* If the buffer reaches MAX_AUDITS_SIZE, automatically triggers
|
|
115
|
+
* a flush to prevent unbounded memory growth.
|
|
116
|
+
*
|
|
117
|
+
* The input is validated against the config's schemas at runtime
|
|
118
|
+
* and TypeScript enforces strict typing at compile time.
|
|
119
|
+
*
|
|
120
|
+
* @param item - The audit entry to buffer
|
|
121
|
+
*/
|
|
122
|
+
addAudit(item) {
|
|
123
|
+
if (Object.keys(this.storedAudits).length >= MAX_AUDITS_SIZE) {
|
|
124
|
+
this.publishStoredAudits();
|
|
125
|
+
}
|
|
126
|
+
this.config.schemas.resourceReference.parse(item.target);
|
|
127
|
+
if (item.source) {
|
|
128
|
+
this.config.schemas.resourceReference.parse(item.source);
|
|
129
|
+
}
|
|
130
|
+
if (item.resources) {
|
|
131
|
+
const resources = item.resources instanceof Set
|
|
132
|
+
? Array.from(item.resources)
|
|
133
|
+
: item.resources;
|
|
134
|
+
for (const resource of resources) {
|
|
135
|
+
this.config.schemas.resourceReference.parse(resource);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
this.storedAudits.push(item);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Publishes all buffered audit entries to stdout and clears the buffer.
|
|
142
|
+
*
|
|
143
|
+
* Each audit entry is:
|
|
144
|
+
* 1. Injected with the X-Ray trace ID if not already set
|
|
145
|
+
* 2. Validated and transformed through LogAuditSchema (or typed schema if config provided)
|
|
146
|
+
* 3. Emitted as JSON with the AUDIT_LOG_IDENTIFIER wrapper
|
|
147
|
+
*
|
|
148
|
+
* If audits are disabled, the buffer is cleared without emission.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* // Manual flush at end of handler
|
|
153
|
+
* audits.publishStoredAudits();
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
publishStoredAudits() {
|
|
157
|
+
if (!this.disabled) {
|
|
158
|
+
const schema = createTypedLogAuditSchema(this.config.schemas.resourceReference);
|
|
159
|
+
this.storedAudits.forEach((item) => {
|
|
160
|
+
if (!item.trace) {
|
|
161
|
+
item.trace = this.traceId;
|
|
162
|
+
}
|
|
163
|
+
this.console.log(JSON.stringify({
|
|
164
|
+
[AUDIT_LOG_IDENTIFIER]: {
|
|
165
|
+
...schema.parse(item),
|
|
166
|
+
},
|
|
167
|
+
}));
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
this.clearAudits();
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Initializes the console instance based on environment mode.
|
|
174
|
+
*
|
|
175
|
+
* In production (non-dev mode), creates a dedicated Console instance
|
|
176
|
+
* writing to process.stdout/stderr. In dev mode, uses the global console
|
|
177
|
+
* for better local debugging experience.
|
|
178
|
+
*
|
|
179
|
+
* @internal
|
|
180
|
+
*/
|
|
181
|
+
setConsole() {
|
|
182
|
+
if (!this.#envConfig.devMode) {
|
|
183
|
+
this.console = new Console({
|
|
184
|
+
stdout: process.stdout,
|
|
185
|
+
stderr: process.stderr,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
this.console = console;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Reads and caches environment configuration values.
|
|
194
|
+
*
|
|
195
|
+
* Checks POWERTOOLS_AUDITS_DISABLED and POWERTOOLS_DEV environment
|
|
196
|
+
* variables using AWS Lambda Powertools utilities.
|
|
197
|
+
*
|
|
198
|
+
* @internal
|
|
199
|
+
*/
|
|
200
|
+
setEnvConfig() {
|
|
201
|
+
this.#envConfig.disabled = getBooleanFromEnv({
|
|
202
|
+
key: "POWERTOOLS_AUDITS_DISABLED",
|
|
203
|
+
defaultValue: false,
|
|
204
|
+
extendedParsing: true,
|
|
205
|
+
});
|
|
206
|
+
this.#envConfig.devMode = isDevMode();
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Determines whether audits should be disabled based on environment.
|
|
210
|
+
*
|
|
211
|
+
* Priority:
|
|
212
|
+
* 1. POWERTOOLS_AUDITS_DISABLED takes precedence if explicitly set
|
|
213
|
+
* 2. Otherwise, audits are disabled in dev mode (POWERTOOLS_DEV=true)
|
|
214
|
+
*
|
|
215
|
+
* @internal
|
|
216
|
+
*/
|
|
217
|
+
setDisabled() {
|
|
218
|
+
if ("POWERTOOLS_AUDITS_DISABLED" in process.env &&
|
|
219
|
+
process.env.POWERTOOLS_AUDITS_DISABLED !== undefined) {
|
|
220
|
+
this.disabled = this.#envConfig.disabled;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this.disabled = this.#envConfig.devMode;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BatchProcessor, type EventType } from "@aws-lambda-powertools/batch";
|
|
2
|
+
import type { EventSourceDataClassTypes, FailureResponse, SuccessResponse } from "@aws-lambda-powertools/batch/types";
|
|
3
|
+
import type { Audits } from "../audits.js";
|
|
4
|
+
import type { AuditConfig } from "../config.js";
|
|
5
|
+
import { type LogAuditInput } from "../schema/log.js";
|
|
6
|
+
/**
|
|
7
|
+
* Result type that can include optional audit overrides.
|
|
8
|
+
* When a batch processor handler returns this type, the _audit field
|
|
9
|
+
* can be used to customize the audit log entry.
|
|
10
|
+
*/
|
|
11
|
+
export type MessageWithAuditOverride = {
|
|
12
|
+
/** Human-readable message describing the result */
|
|
13
|
+
message: string;
|
|
14
|
+
/** Optional overrides to apply to the audit log entry */
|
|
15
|
+
_audit?: Partial<LogAuditInput>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Extended batch processor that automatically creates audit log entries
|
|
19
|
+
* for each record processed in a batch operation.
|
|
20
|
+
*
|
|
21
|
+
* Integrates with AWS Lambda Powertools BatchProcessor to provide
|
|
22
|
+
* automatic audit logging for SQS, Kinesis, and DynamoDB Streams events.
|
|
23
|
+
*
|
|
24
|
+
* @template Record - The type of event source record being processed
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const processor = new AuditBatchProcessor(
|
|
29
|
+
* EventType.SQS,
|
|
30
|
+
* audits,
|
|
31
|
+
* (record, overrides) => ({
|
|
32
|
+
* operation: 'processMessage',
|
|
33
|
+
* target: { app: 'MyApp', type: 'Message' },
|
|
34
|
+
* ...overrides,
|
|
35
|
+
* })
|
|
36
|
+
* );
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare class AuditBatchProcessor<Record extends EventSourceDataClassTypes> extends BatchProcessor {
|
|
40
|
+
readonly audit: Audits<AuditConfig>;
|
|
41
|
+
readonly createAuditItem: (record: Record, overrides?: Partial<LogAuditInput>) => LogAuditInput;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new AuditBatchProcessor instance.
|
|
44
|
+
*
|
|
45
|
+
* @param eventType - The type of event source (SQS, Kinesis, or DynamoDB)
|
|
46
|
+
* @param audit - The Audits instance used to collect and publish audit logs
|
|
47
|
+
* @param createAuditItem - Factory function that creates an audit log entry from a record
|
|
48
|
+
*/
|
|
49
|
+
constructor(eventType: keyof typeof EventType, audit: Audits<AuditConfig>, createAuditItem: (record: Record, overrides?: Partial<LogAuditInput>) => LogAuditInput);
|
|
50
|
+
/**
|
|
51
|
+
* Handles successful record processing by creating a success audit entry.
|
|
52
|
+
*
|
|
53
|
+
* Called automatically by the batch processor when a record is processed
|
|
54
|
+
* without throwing an error. Creates an audit entry with SUCCESS status
|
|
55
|
+
* and excludes the original event data to reduce storage costs.
|
|
56
|
+
*
|
|
57
|
+
* The audit ID is automatically set from the record's unique identifier
|
|
58
|
+
* (messageId for SQS, eventID for Kinesis/DynamoDB) to enable retry correlation.
|
|
59
|
+
*
|
|
60
|
+
* @param record - The successfully processed record
|
|
61
|
+
* @param result - The result returned by the record handler, may include audit overrides
|
|
62
|
+
* @returns The success response from the parent BatchProcessor
|
|
63
|
+
*/
|
|
64
|
+
successHandler(record: Record, result: unknown | MessageWithAuditOverride): SuccessResponse;
|
|
65
|
+
/**
|
|
66
|
+
* Handles failed record processing by creating a failure audit entry.
|
|
67
|
+
*
|
|
68
|
+
* Called automatically by the batch processor when a record handler
|
|
69
|
+
* throws an error. Creates an audit entry with FAIL status, includes
|
|
70
|
+
* the original event data for debugging, and captures the error details.
|
|
71
|
+
*
|
|
72
|
+
* The audit ID is automatically set from the record's unique identifier
|
|
73
|
+
* (messageId for SQS, eventID for Kinesis/DynamoDB) to enable retry correlation.
|
|
74
|
+
*
|
|
75
|
+
* @param record - The record that failed processing
|
|
76
|
+
* @param error - The error thrown during processing
|
|
77
|
+
* @returns The failure response from the parent BatchProcessor
|
|
78
|
+
*/
|
|
79
|
+
failureHandler(record: Record, error: Error): FailureResponse;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=batch-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-processor.d.ts","sourceRoot":"","sources":["../../src/batch/batch-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EACX,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,MAAM,oCAAoC,CAAC;AAM5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,aAAa,EAAU,MAAM,kBAAkB,CAAC;AAO9D;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACtC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAChC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,mBAAmB,CAC/B,MAAM,SAAS,yBAAyB,CACvC,SAAQ,cAAc;IAUtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,CACzB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,KAC9B,aAAa;IAbnB;;;;;;OAMG;gBAEF,SAAS,EAAE,MAAM,OAAO,SAAS,EACxB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,EAC1B,eAAe,EAAE,CACzB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,KAC9B,aAAa;IAKnB;;;;;;;;;;;;;OAaG;IACI,cAAc,CACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,GAAG,wBAAwB,GACxC,eAAe;IAuBlB;;;;;;;;;;;;;OAaG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,eAAe;CAuBpE"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { BatchProcessor } from "@aws-lambda-powertools/batch";
|
|
2
|
+
import { Status } from "../schema/log.js";
|
|
3
|
+
import { extractOverridesFromBatchProcessor, getRecordId, normalizeEventBridgetEventBody, } from "../utils.js";
|
|
4
|
+
/**
|
|
5
|
+
* Extended batch processor that automatically creates audit log entries
|
|
6
|
+
* for each record processed in a batch operation.
|
|
7
|
+
*
|
|
8
|
+
* Integrates with AWS Lambda Powertools BatchProcessor to provide
|
|
9
|
+
* automatic audit logging for SQS, Kinesis, and DynamoDB Streams events.
|
|
10
|
+
*
|
|
11
|
+
* @template Record - The type of event source record being processed
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const processor = new AuditBatchProcessor(
|
|
16
|
+
* EventType.SQS,
|
|
17
|
+
* audits,
|
|
18
|
+
* (record, overrides) => ({
|
|
19
|
+
* operation: 'processMessage',
|
|
20
|
+
* target: { app: 'MyApp', type: 'Message' },
|
|
21
|
+
* ...overrides,
|
|
22
|
+
* })
|
|
23
|
+
* );
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class AuditBatchProcessor extends BatchProcessor {
|
|
27
|
+
audit;
|
|
28
|
+
createAuditItem;
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new AuditBatchProcessor instance.
|
|
31
|
+
*
|
|
32
|
+
* @param eventType - The type of event source (SQS, Kinesis, or DynamoDB)
|
|
33
|
+
* @param audit - The Audits instance used to collect and publish audit logs
|
|
34
|
+
* @param createAuditItem - Factory function that creates an audit log entry from a record
|
|
35
|
+
*/
|
|
36
|
+
constructor(eventType, audit, createAuditItem) {
|
|
37
|
+
super(eventType);
|
|
38
|
+
this.audit = audit;
|
|
39
|
+
this.createAuditItem = createAuditItem;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handles successful record processing by creating a success audit entry.
|
|
43
|
+
*
|
|
44
|
+
* Called automatically by the batch processor when a record is processed
|
|
45
|
+
* without throwing an error. Creates an audit entry with SUCCESS status
|
|
46
|
+
* and excludes the original event data to reduce storage costs.
|
|
47
|
+
*
|
|
48
|
+
* The audit ID is automatically set from the record's unique identifier
|
|
49
|
+
* (messageId for SQS, eventID for Kinesis/DynamoDB) to enable retry correlation.
|
|
50
|
+
*
|
|
51
|
+
* @param record - The successfully processed record
|
|
52
|
+
* @param result - The result returned by the record handler, may include audit overrides
|
|
53
|
+
* @returns The success response from the parent BatchProcessor
|
|
54
|
+
*/
|
|
55
|
+
successHandler(record, result) {
|
|
56
|
+
const auditItem = this.createAuditItem(record, {
|
|
57
|
+
status: Status.SUCCESS,
|
|
58
|
+
...extractOverridesFromBatchProcessor(result),
|
|
59
|
+
});
|
|
60
|
+
// Auto-set ID for retry correlation using event record ID
|
|
61
|
+
const recordId = getRecordId(this.eventType, record);
|
|
62
|
+
if (recordId && !auditItem.id) {
|
|
63
|
+
auditItem.id = recordId;
|
|
64
|
+
}
|
|
65
|
+
this.audit.addAudit({
|
|
66
|
+
...auditItem,
|
|
67
|
+
event: undefined, // Don't store event when successful
|
|
68
|
+
});
|
|
69
|
+
return super.successHandler(record, result);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handles failed record processing by creating a failure audit entry.
|
|
73
|
+
*
|
|
74
|
+
* Called automatically by the batch processor when a record handler
|
|
75
|
+
* throws an error. Creates an audit entry with FAIL status, includes
|
|
76
|
+
* the original event data for debugging, and captures the error details.
|
|
77
|
+
*
|
|
78
|
+
* The audit ID is automatically set from the record's unique identifier
|
|
79
|
+
* (messageId for SQS, eventID for Kinesis/DynamoDB) to enable retry correlation.
|
|
80
|
+
*
|
|
81
|
+
* @param record - The record that failed processing
|
|
82
|
+
* @param error - The error thrown during processing
|
|
83
|
+
* @returns The failure response from the parent BatchProcessor
|
|
84
|
+
*/
|
|
85
|
+
failureHandler(record, error) {
|
|
86
|
+
const auditItem = this.createAuditItem(record, {
|
|
87
|
+
status: Status.FAIL,
|
|
88
|
+
event: normalizeEventBridgetEventBody(this.eventType, record),
|
|
89
|
+
message: error.message,
|
|
90
|
+
});
|
|
91
|
+
// Auto-set ID for retry correlation using event record ID
|
|
92
|
+
const recordId = getRecordId(this.eventType, record);
|
|
93
|
+
if (recordId && !auditItem.id) {
|
|
94
|
+
auditItem.id = recordId;
|
|
95
|
+
}
|
|
96
|
+
this.audit.addAudit({
|
|
97
|
+
...auditItem,
|
|
98
|
+
error,
|
|
99
|
+
});
|
|
100
|
+
return super.failureHandler(record, error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/batch/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./batch-processor.js";
|