cdk-insights 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -172,6 +172,75 @@ Aspects.of(app).add(createCdkInsightsAspect());
172
172
  app.synth();
173
173
  ```
174
174
 
175
+ The aspect runs `cdk-nag`'s `AwsSolutionsChecks` rule pack alongside cdk-insights' own rules. As of 1.17.0, those findings are emitted as **non-blocking Info annotations** (`cdk-insights::nagFinding::*`) instead of cdk-nag's default Error/Warning annotations — the Validations Plugin (below) remains the actual deploy gate, configured per severity.
176
+
177
+ ##### Auto-suppress CDK / AWS boilerplate
178
+
179
+ cdk-nag's `AwsSolutionsChecks` rule pack flags two patterns that are universally noisy for CDK consumers — they're either AWS-recommended defaults or stale rule heuristics:
180
+
181
+ - **`AwsSolutions-IAM4`** flags any AWS-managed policy attached to a role, including the standard Lambda execution policies CDK auto-attaches based on event sources or tracing configuration. Each is narrowly scoped to a single AWS service — replacing them with customer-managed copies is busywork with no security gain.
182
+ - **`AwsSolutions-L1`** asserts that Lambda runtimes match cdk-nag's known "latest" list, which lags actual AWS LTS releases. Node 20.x / 22.x, Python 3.11–3.13, Java 17/21, .NET 8, Ruby 3.3/3.4, and `provided.al2023` are all current AWS LTS at time of writing but get flagged depending on how recent your `aws-cdk-lib` version is.
183
+
184
+ Pass `cdkBoilerplateSuppressions: true` to short-circuit both:
185
+
186
+ ```ts
187
+ Aspects.of(app).add(createCdkInsightsAspect({
188
+ cdkBoilerplateSuppressions: true,
189
+ }));
190
+ ```
191
+
192
+ This attaches `NagSuppressions` (with named justifications and `appliesTo` filters) before cdk-nag evaluates each construct, so the matching findings are never emitted. Anything outside the boilerplate set continues to surface — if a role has `AWSLambdaBasicExecutionRole` *and* a custom managed policy, only the boilerplate one is suppressed; the custom policy still produces a finding.
193
+
194
+ | Rule | What's suppressed | What still fires |
195
+ |---|---|---|
196
+ | `AwsSolutions-IAM4` | 11 AWS-managed Lambda execution policy ARNs: `AWSLambdaBasicExecutionRole`, `AWSLambdaVPCAccessExecutionRole`, `AWSLambdaENIManagementAccess`, `AWSLambdaSQSQueueExecutionRole`, `AWSLambdaDynamoDBExecutionRole`, `AWSLambdaKinesisExecutionRole`, `AWSLambdaMSKExecutionRole`, `AWSLambdaAMQExecutionRole`, `AWSLambdaSelfManagedKafkaExecutionRole`, `AWSLambdaInvocation-DynamoDB`, `AWSXRayDaemonWriteAccess` | Any other managed policy attached to the same role |
197
+ | `AwsSolutions-L1` | `nodejs18.x` / `nodejs20.x` / `nodejs22.x`, `python3.11` / `python3.12` / `python3.13`, `java17` / `java21`, `dotnet8`, `ruby3.3` / `ruby3.4`, `provided.al2023` | Anything outside the LTS allowlist (older runtimes, unsupported ones, custom families) |
198
+
199
+ Default is `false` — opt-in is conservative and additive.
200
+
201
+ ##### Suppress arbitrary cdk-nag rules
202
+
203
+ For rules outside the boilerplate set — context-dependent ones like `AwsSolutions-COG2` (MFA), `AwsSolutions-DDB3` (PITR), or any rule the project has reviewed and consciously accepted — pass `suppressNagRules`:
204
+
205
+ ```ts
206
+ Aspects.of(app).add(createCdkInsightsAspect({
207
+ cdkBoilerplateSuppressions: true,
208
+ suppressNagRules: [
209
+ // String shorthand — gets a generic auto-reason. Fine for triage.
210
+ 'AwsSolutions-APIG2',
211
+ // Object form — written justification. **Recommended for prod code.**
212
+ {
213
+ id: 'AwsSolutions-COG2',
214
+ reason: 'MFA opt-in by product policy; mandatory MFA blocks onboarding for new users. See RFC-0042.',
215
+ },
216
+ ],
217
+ }));
218
+ ```
219
+
220
+ Both options compose. The aspect walks up to the construct-tree root on the first visit and applies the suppressions with `applyToChildren: true`, so the rule is honoured for every descendant resource regardless of stack.
221
+
222
+ For finer-grained control (per-resource, per-`appliesTo`-pattern), use `NagSuppressions.addResourceSuppressions(...)` from `cdk-nag` directly after constructing your stacks. Common patterns we don't auto-suppress because they need consumer context:
223
+
224
+ ```ts
225
+ import { NagSuppressions } from 'cdk-nag';
226
+
227
+ // DDB grant{Read,Write}Data auto-attaches Resource::<TableArn>/index/*
228
+ // for GSI access. DynamoDB IAM has no index-level scope distinct from
229
+ // the table; the wildcard is unavoidable. Apply per-stack with reason.
230
+ NagSuppressions.addStackSuppressions(myStack, [
231
+ {
232
+ id: 'AwsSolutions-IAM5',
233
+ reason: 'DDB grantRead/Write expands to <TableArn>/index/* for GSI access — DynamoDB IAM has no index-level scope.',
234
+ },
235
+ ]);
236
+
237
+ // COG2 (mandatory MFA) — product-policy decision, not a defect
238
+ NagSuppressions.addResourceSuppressionsByPath(myStack,
239
+ '/MyStack/MyUserPool/Resource',
240
+ [{ id: 'AwsSolutions-COG2', reason: 'MFA opt-in by product policy.' }],
241
+ );
242
+ ```
243
+
175
244
  For accurate `file:line` source attribution, CDK needs to record per-construct stack traces during synth. Three ways to enable this, easiest first:
176
245
 
177
246
  - **`npx cdk-insights setup`** writes `"@aws-cdk/core:stackTrace": true` into your `cdk.json` `context` block — durable across every `cdk synth` invocation, no env-var dance. Recommended.
@@ -154,6 +154,77 @@ export interface CdkInsightsAspectOptions {
154
154
  * around the construct definition for quick reference.
155
155
  */
156
156
  includeCodeSnippets?: boolean;
157
+ /**
158
+ * Auto-suppress cdk-nag findings for well-known CDK / AWS boilerplate
159
+ * patterns (default: false). When `true`, the aspect attaches
160
+ * `NagSuppressions` to matching constructs **before** cdk-nag evaluates
161
+ * its rules, so the suppressed findings disappear from scan output
162
+ * entirely. Each suppression carries a named justification.
163
+ *
164
+ * Currently covers two universally-noisy rules:
165
+ *
166
+ * - **`AwsSolutions-IAM4`** for the AWS-managed Lambda execution
167
+ * policies CDK auto-attaches based on event sources
168
+ * (`AWSLambdaBasicExecutionRole`, `AWSLambdaVPCAccessExecutionRole`,
169
+ * `AWSLambdaSQSQueueExecutionRole`, `AWSLambdaDynamoDBExecutionRole`,
170
+ * `AWSLambdaKinesisExecutionRole`). Each is narrowly scoped to a
171
+ * single AWS service; replacing them with customer-managed copies is
172
+ * busywork with no security gain. The suppression uses `appliesTo`
173
+ * so any *other* managed policy attached to the same role still
174
+ * surfaces a finding.
175
+ *
176
+ * - **`AwsSolutions-L1`** for current AWS Lambda LTS runtimes
177
+ * (Node 18/20/22, Python 3.11/3.12/3.13, Java 17/21, .NET 8).
178
+ * cdk-nag's "latest runtime" check is heuristic and lags new LTS
179
+ * releases; this allowlist updates with cdk-insights releases.
180
+ *
181
+ * Anything not in the lists above continues to surface normally — opt-in
182
+ * is conservative and additive.
183
+ *
184
+ * Recommended for any project that uses cdk-insights' aspect. To
185
+ * extend with project-specific suppressions, call
186
+ * `NagSuppressions.addResourceSuppressions(...)` from `cdk-nag` after
187
+ * constructing your stacks.
188
+ */
189
+ cdkBoilerplateSuppressions?: boolean;
190
+ /**
191
+ * Additional cdk-nag rule IDs to suppress globally across the construct
192
+ * tree. Applied via `NagSuppressions` on the App root with
193
+ * `applyToChildren: true`, so the suppression is honoured for every
194
+ * descendant resource regardless of stack.
195
+ *
196
+ * Two entry forms:
197
+ *
198
+ * - **String shorthand** (`'AwsSolutions-APIG2'`) — gets a generic
199
+ * auto-reason. Use for quick experiments / triage.
200
+ * - **Object form** (`{ id: '...', reason: '...' }`) — carries an
201
+ * explicit written justification. **Recommended for checked-in
202
+ * code** so suppressions are auditable.
203
+ *
204
+ * Composes with `cdkBoilerplateSuppressions`; both can be enabled
205
+ * simultaneously. For finer-grained control (per-resource, per-
206
+ * `appliesTo`-pattern), use `NagSuppressions.addResourceSuppressions(...)`
207
+ * from `cdk-nag` directly after constructing your stacks.
208
+ *
209
+ * @example
210
+ * ```ts
211
+ * Aspects.of(app).add(createCdkInsightsAspect({
212
+ * suppressNagRules: [
213
+ * // String shorthand — generic auto-reason, fine for triage
214
+ * 'AwsSolutions-APIG2',
215
+ * // Object form — written justification, recommended for prod code
216
+ * {
217
+ * id: 'AwsSolutions-COG2',
218
+ * reason: 'MFA is opt-in by product policy; see RFC-0042.',
219
+ * },
220
+ * ],
221
+ * }));
222
+ * ```
223
+ */
224
+ suppressNagRules?: Array<string | {
225
+ id: string;
226
+ reason: string;
227
+ }>;
157
228
  }
158
229
  /**
159
230
  * Helper function to check if CDK stack traces are enabled.
@@ -265,6 +336,7 @@ export declare class ExtremelyHelpfulConsoleLogger implements INagLogger {
265
336
  export declare class CdkInsightsAspect extends NagPack implements IAspect {
266
337
  private readonly delegate;
267
338
  private readonly options;
339
+ private readonly userSuppressionsApplied;
268
340
  constructor(props?: NagPackProps & CdkInsightsAspectOptions);
269
341
  visit(node: IConstruct): void;
270
342
  }