@sureshgururajan/aws-console-private-access-validator 1.0.6 → 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.
@@ -15,5 +15,6 @@ export declare class ConsolePrivateAccessValidator {
15
15
  private checkNatGateway;
16
16
  private checkNetworkConfiguration;
17
17
  private generateSummary;
18
+ private checkDetectiveControls;
18
19
  }
19
20
  //# sourceMappingURL=validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEpF,qBAAa,6BAA6B;IACxC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAyB;gBAE3B,QAAQ,EAAE,sBAAsB,EAAE,MAAM,GAAE,MAAoB;IAK1E,QAAQ,IAAI,gBAAgB;IAqB5B,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,iBAAiB;IAiDzB,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,uBAAuB;IAuC/B,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,yBAAyB;IAkCjC,OAAO,CAAC,eAAe;CAUxB"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEpF,qBAAa,6BAA6B;IACxC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAyB;gBAE3B,QAAQ,EAAE,sBAAsB,EAAE,MAAM,GAAE,MAAoB;IAK1E,QAAQ,IAAI,gBAAgB;IAsB5B,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,iBAAiB;IAiDzB,OAAO,CAAC,qBAAqB;IAkC7B,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,uBAAuB;IAuC/B,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,yBAAyB;IAkCjC,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,sBAAsB;CAgL/B"}
package/dist/validator.js CHANGED
@@ -15,6 +15,7 @@ export class ConsolePrivateAccessValidator {
15
15
  this.checkEc2Instance();
16
16
  this.checkNatGateway();
17
17
  this.checkNetworkConfiguration();
18
+ this.checkDetectiveControls();
18
19
  const failCount = this.checks.filter(c => c.status === 'fail').length;
19
20
  const valid = failCount === 0;
20
21
  return {
@@ -85,36 +86,30 @@ export class ConsolePrivateAccessValidator {
85
86
  }
86
87
  checkEndpointPolicies() {
87
88
  const resources = this.template.Resources || {};
88
- const consoleEndpoint = Object.entries(resources).find(([_, r]) => {
89
- const serviceName = this.getServiceName(r.Properties?.ServiceName);
90
- return (r.Type === 'AWS::EC2::VPCEndpoint' &&
91
- serviceName &&
92
- serviceName.includes('console'));
93
- });
94
- const signinEndpoint = Object.entries(resources).find(([_, r]) => {
95
- const serviceName = this.getServiceName(r.Properties?.ServiceName);
96
- return (r.Type === 'AWS::EC2::VPCEndpoint' &&
97
- serviceName &&
98
- serviceName.includes('signin'));
99
- });
100
- for (const [name, endpoint] of [
101
- ['Console', consoleEndpoint],
102
- ['Signin', signinEndpoint],
103
- ]) {
104
- if (!endpoint)
105
- continue;
106
- const [_, resource] = endpoint;
89
+ const interfaceEndpoints = Object.entries(resources).filter(([_, r]) => r.Type === 'AWS::EC2::VPCEndpoint' && r.Properties?.VpcEndpointType === 'Interface');
90
+ for (const [name, resource] of interfaceEndpoints) {
91
+ const serviceName = this.getServiceName(resource.Properties?.ServiceName);
107
92
  const hasPolicy = resource.Properties?.PolicyDocument;
93
+ const privateDnsEnabled = resource.Properties?.PrivateDnsEnabled;
94
+ // Check for policy
108
95
  this.checks.push({
109
- name: `Endpoint Policy: ${name}`,
96
+ name: `Endpoint Policy: ${serviceName || name}`,
110
97
  status: hasPolicy ? 'pass' : 'fail',
111
98
  message: hasPolicy
112
- ? `${name} endpoint has a policy attached`
113
- : `${name} endpoint is missing a policy`,
99
+ ? `${serviceName || name} endpoint has a policy attached`
100
+ : `${serviceName || name} endpoint is missing a policy`,
114
101
  details: hasPolicy
115
102
  ? this.validatePolicyContent(resource.Properties.PolicyDocument)
116
103
  : undefined,
117
104
  });
105
+ // Check for private DNS enabled
106
+ this.checks.push({
107
+ name: `Private DNS: ${serviceName || name}`,
108
+ status: privateDnsEnabled ? 'pass' : 'fail',
109
+ message: privateDnsEnabled
110
+ ? `${serviceName || name} endpoint has private DNS enabled`
111
+ : `${serviceName || name} endpoint does not have private DNS enabled`,
112
+ });
118
113
  }
119
114
  }
120
115
  validatePolicyContent(policy) {
@@ -232,5 +227,140 @@ export class ConsolePrivateAccessValidator {
232
227
  }
233
228
  return `✗ Validation failed. ${failCount} check(s) failed, ${passCount} passed, ${warningCount} warnings.`;
234
229
  }
230
+ checkDetectiveControls() {
231
+ const resources = this.template.Resources || {};
232
+ // Check for CloudTrail
233
+ const trail = Object.values(resources).find((r) => r.Type === 'AWS::CloudTrail::Trail');
234
+ this.checks.push({
235
+ name: 'CloudTrail: Trail Configuration',
236
+ status: trail ? 'pass' : 'fail',
237
+ message: trail
238
+ ? 'CloudTrail trail found for logging VPC endpoint activity'
239
+ : 'Missing CloudTrail trail - required for monitoring VPC endpoint policy denials',
240
+ });
241
+ if (trail) {
242
+ const trailProps = trail.Properties;
243
+ // Check for advanced event selectors with network activity
244
+ const hasNetworkActivitySelectors = trailProps?.AdvancedEventSelectors?.some((selector) => selector.FieldSelectors?.some((field) => field.Field === 'eventCategory' && field.Equals?.includes('NetworkActivity')));
245
+ this.checks.push({
246
+ name: 'CloudTrail: Network Activity Monitoring',
247
+ status: hasNetworkActivitySelectors ? 'pass' : 'fail',
248
+ message: hasNetworkActivitySelectors
249
+ ? 'CloudTrail configured to log network activity events (VpceAccessDenied)'
250
+ : 'CloudTrail missing network activity event selectors - cannot detect VPC endpoint policy denials',
251
+ });
252
+ // Check for VpceAccessDenied error code filtering
253
+ const hasVpceAccessDeniedFilter = trailProps?.AdvancedEventSelectors?.some((selector) => selector.FieldSelectors?.some((field) => field.Field === 'errorCode' && field.Equals?.includes('VpceAccessDenied')));
254
+ this.checks.push({
255
+ name: 'CloudTrail: VpceAccessDenied Filter',
256
+ status: hasVpceAccessDeniedFilter ? 'pass' : 'warning',
257
+ message: hasVpceAccessDeniedFilter
258
+ ? 'CloudTrail configured to filter VpceAccessDenied events'
259
+ : 'CloudTrail not filtering by VpceAccessDenied error code - may log unnecessary events',
260
+ });
261
+ // Check for CloudWatch Logs integration
262
+ const hasCloudWatchLogs = trailProps?.CloudWatchLogsLogGroupArn;
263
+ this.checks.push({
264
+ name: 'CloudTrail: CloudWatch Logs Integration',
265
+ status: hasCloudWatchLogs ? 'pass' : 'fail',
266
+ message: hasCloudWatchLogs
267
+ ? 'CloudTrail sending logs to CloudWatch for real-time analysis'
268
+ : 'CloudTrail not integrated with CloudWatch Logs - cannot create real-time alarms',
269
+ });
270
+ }
271
+ // Check for CloudWatch Log Group
272
+ const logGroup = Object.values(resources).find((r) => r.Type === 'AWS::Logs::LogGroup');
273
+ this.checks.push({
274
+ name: 'CloudWatch: Log Group',
275
+ status: logGroup ? 'pass' : 'fail',
276
+ message: logGroup
277
+ ? 'CloudWatch Log Group found for CloudTrail logs'
278
+ : 'Missing CloudWatch Log Group - required for metric filters and alarms',
279
+ });
280
+ // Check for Metric Filters
281
+ const metricFilters = Object.values(resources).filter((r) => r.Type === 'AWS::Logs::MetricFilter');
282
+ // Required: VpceAccessDenied filter
283
+ const hasVpceAccessDeniedFilter = metricFilters.some((mf) => {
284
+ const filterPattern = mf.Properties?.FilterPattern || '';
285
+ return filterPattern.toLowerCase().includes('errorcode') &&
286
+ filterPattern.toLowerCase().includes('vpceaccessdenied');
287
+ });
288
+ this.checks.push({
289
+ name: 'Metric Filter: VpceAccessDenied',
290
+ status: hasVpceAccessDeniedFilter ? 'pass' : 'fail',
291
+ message: hasVpceAccessDeniedFilter
292
+ ? 'Metric filter for VpceAccessDenied found'
293
+ : 'Missing metric filter for VpceAccessDenied - cannot detect VPC endpoint policy denials',
294
+ });
295
+ // Optional: Additional filters for enhanced security monitoring
296
+ const hasCrossAccountFilter = metricFilters.some((mf) => {
297
+ const filterPattern = mf.Properties?.FilterPattern || '';
298
+ return filterPattern.toLowerCase().includes('cross') ||
299
+ filterPattern.toLowerCase().includes('account');
300
+ });
301
+ const hasSuspiciousUserAgentFilter = metricFilters.some((mf) => {
302
+ const filterPattern = mf.Properties?.FilterPattern || '';
303
+ return filterPattern.toLowerCase().includes('useragent') ||
304
+ filterPattern.toLowerCase().includes('data') ||
305
+ filterPattern.toLowerCase().includes('exfil');
306
+ });
307
+ if (hasCrossAccountFilter || hasSuspiciousUserAgentFilter) {
308
+ this.checks.push({
309
+ name: 'Metric Filters: Enhanced Monitoring',
310
+ status: 'pass',
311
+ message: `Additional metric filters found for enhanced security monitoring (${hasCrossAccountFilter ? 'CrossAccountAccess' : ''}${hasCrossAccountFilter && hasSuspiciousUserAgentFilter ? ', ' : ''}${hasSuspiciousUserAgentFilter ? 'SuspiciousUserAgent' : ''})`,
312
+ });
313
+ }
314
+ // Check for CloudWatch Alarms
315
+ const alarms = Object.values(resources).filter((r) => r.Type === 'AWS::CloudWatch::Alarm');
316
+ this.checks.push({
317
+ name: 'CloudWatch: Alarms',
318
+ status: alarms.length >= 1 ? 'pass' : 'fail',
319
+ message: alarms.length >= 1
320
+ ? `Found ${alarms.length} CloudWatch alarm(s) for security monitoring`
321
+ : 'No CloudWatch alarms found - cannot receive real-time security alerts',
322
+ });
323
+ // Check for SNS Topic
324
+ const snsTopic = Object.values(resources).find((r) => r.Type === 'AWS::SNS::Topic');
325
+ this.checks.push({
326
+ name: 'SNS: Alert Topic',
327
+ status: snsTopic ? 'pass' : 'fail',
328
+ message: snsTopic
329
+ ? 'SNS topic found for security alert notifications'
330
+ : 'Missing SNS topic - cannot send security alert notifications',
331
+ });
332
+ // Check that alarms are connected to SNS topic
333
+ if (snsTopic && alarms.length > 0) {
334
+ const alarmsWithActions = alarms.filter((alarm) => alarm.Properties?.AlarmActions && alarm.Properties.AlarmActions.length > 0);
335
+ this.checks.push({
336
+ name: 'CloudWatch: Alarm Actions',
337
+ status: alarmsWithActions.length === alarms.length ? 'pass' : 'warning',
338
+ message: alarmsWithActions.length === alarms.length
339
+ ? 'All alarms configured to send notifications'
340
+ : `${alarmsWithActions.length}/${alarms.length} alarms configured with actions - some alarms may not send notifications`,
341
+ });
342
+ }
343
+ // Check for S3 bucket for CloudTrail logs
344
+ const s3Buckets = Object.values(resources).filter((r) => r.Type === 'AWS::S3::Bucket');
345
+ const hasTrailBucket = s3Buckets.length > 0;
346
+ this.checks.push({
347
+ name: 'S3: CloudTrail Log Bucket',
348
+ status: hasTrailBucket ? 'pass' : 'warning',
349
+ message: hasTrailBucket
350
+ ? 'S3 bucket found for CloudTrail log storage'
351
+ : 'No S3 bucket found - CloudTrail logs may not be persisted long-term',
352
+ });
353
+ // Check for bucket encryption
354
+ if (hasTrailBucket) {
355
+ const hasEncryption = s3Buckets.some((bucket) => bucket.Properties?.BucketEncryption);
356
+ this.checks.push({
357
+ name: 'S3: Bucket Encryption',
358
+ status: hasEncryption ? 'pass' : 'warning',
359
+ message: hasEncryption
360
+ ? 'S3 bucket configured with encryption'
361
+ : 'S3 bucket missing encryption configuration - logs may not be encrypted at rest',
362
+ });
363
+ }
364
+ }
235
365
  }
236
366
  //# sourceMappingURL=validator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sureshgururajan/aws-console-private-access-validator",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "MCP server for validating AWS Console Private Access CloudFormation templates",
6
6
  "main": "dist/index.js",
package/src/validator.ts CHANGED
@@ -20,6 +20,7 @@ export class ConsolePrivateAccessValidator {
20
20
  this.checkEc2Instance();
21
21
  this.checkNatGateway();
22
22
  this.checkNetworkConfiguration();
23
+ this.checkDetectiveControls();
23
24
 
24
25
  const failCount = this.checks.filter(c => c.status === 'fail').length;
25
26
  const valid = failCount === 0;
@@ -106,47 +107,35 @@ export class ConsolePrivateAccessValidator {
106
107
 
107
108
  private checkEndpointPolicies(): void {
108
109
  const resources = this.template.Resources || {};
109
- const consoleEndpoint = Object.entries(resources).find(
110
- ([_, r]: [string, any]) => {
111
- const serviceName = this.getServiceName(r.Properties?.ServiceName);
112
- return (
113
- r.Type === 'AWS::EC2::VPCEndpoint' &&
114
- serviceName &&
115
- serviceName.includes('console')
116
- );
117
- }
110
+ const interfaceEndpoints = Object.entries(resources).filter(
111
+ ([_, r]: [string, any]) => r.Type === 'AWS::EC2::VPCEndpoint' && r.Properties?.VpcEndpointType === 'Interface'
118
112
  );
119
113
 
120
- const signinEndpoint = Object.entries(resources).find(
121
- ([_, r]: [string, any]) => {
122
- const serviceName = this.getServiceName(r.Properties?.ServiceName);
123
- return (
124
- r.Type === 'AWS::EC2::VPCEndpoint' &&
125
- serviceName &&
126
- serviceName.includes('signin')
127
- );
128
- }
129
- );
130
-
131
- for (const [name, endpoint] of [
132
- ['Console', consoleEndpoint],
133
- ['Signin', signinEndpoint],
134
- ]) {
135
- if (!endpoint) continue;
136
-
137
- const [_, resource] = endpoint as [string, any];
138
- const hasPolicy = resource.Properties?.PolicyDocument;
114
+ for (const [name, resource] of interfaceEndpoints) {
115
+ const serviceName = this.getServiceName((resource as any).Properties?.ServiceName);
116
+ const hasPolicy = (resource as any).Properties?.PolicyDocument;
117
+ const privateDnsEnabled = (resource as any).Properties?.PrivateDnsEnabled;
139
118
 
119
+ // Check for policy
140
120
  this.checks.push({
141
- name: `Endpoint Policy: ${name}`,
121
+ name: `Endpoint Policy: ${serviceName || name}`,
142
122
  status: hasPolicy ? 'pass' : 'fail',
143
123
  message: hasPolicy
144
- ? `${name} endpoint has a policy attached`
145
- : `${name} endpoint is missing a policy`,
124
+ ? `${serviceName || name} endpoint has a policy attached`
125
+ : `${serviceName || name} endpoint is missing a policy`,
146
126
  details: hasPolicy
147
- ? this.validatePolicyContent(resource.Properties.PolicyDocument)
127
+ ? this.validatePolicyContent((resource as any).Properties.PolicyDocument)
148
128
  : undefined,
149
129
  });
130
+
131
+ // Check for private DNS enabled
132
+ this.checks.push({
133
+ name: `Private DNS: ${serviceName || name}`,
134
+ status: privateDnsEnabled ? 'pass' : 'fail',
135
+ message: privateDnsEnabled
136
+ ? `${serviceName || name} endpoint has private DNS enabled`
137
+ : `${serviceName || name} endpoint does not have private DNS enabled`,
138
+ });
150
139
  }
151
140
  }
152
141
 
@@ -307,4 +296,181 @@ export class ConsolePrivateAccessValidator {
307
296
 
308
297
  return `✗ Validation failed. ${failCount} check(s) failed, ${passCount} passed, ${warningCount} warnings.`;
309
298
  }
299
+
300
+ private checkDetectiveControls(): void {
301
+ const resources = this.template.Resources || {};
302
+
303
+ // Check for CloudTrail
304
+ const trail = Object.values(resources).find((r: any) => r.Type === 'AWS::CloudTrail::Trail');
305
+
306
+ this.checks.push({
307
+ name: 'CloudTrail: Trail Configuration',
308
+ status: trail ? 'pass' : 'fail',
309
+ message: trail
310
+ ? 'CloudTrail trail found for logging VPC endpoint activity'
311
+ : 'Missing CloudTrail trail - required for monitoring VPC endpoint policy denials',
312
+ });
313
+
314
+ if (trail) {
315
+ const trailProps = (trail as any).Properties;
316
+
317
+ // Check for advanced event selectors with network activity
318
+ const hasNetworkActivitySelectors = trailProps?.AdvancedEventSelectors?.some((selector: any) =>
319
+ selector.FieldSelectors?.some((field: any) =>
320
+ field.Field === 'eventCategory' && field.Equals?.includes('NetworkActivity')
321
+ )
322
+ );
323
+
324
+ this.checks.push({
325
+ name: 'CloudTrail: Network Activity Monitoring',
326
+ status: hasNetworkActivitySelectors ? 'pass' : 'fail',
327
+ message: hasNetworkActivitySelectors
328
+ ? 'CloudTrail configured to log network activity events (VpceAccessDenied)'
329
+ : 'CloudTrail missing network activity event selectors - cannot detect VPC endpoint policy denials',
330
+ });
331
+
332
+ // Check for VpceAccessDenied error code filtering
333
+ const hasVpceAccessDeniedFilter = trailProps?.AdvancedEventSelectors?.some((selector: any) =>
334
+ selector.FieldSelectors?.some((field: any) =>
335
+ field.Field === 'errorCode' && field.Equals?.includes('VpceAccessDenied')
336
+ )
337
+ );
338
+
339
+ this.checks.push({
340
+ name: 'CloudTrail: VpceAccessDenied Filter',
341
+ status: hasVpceAccessDeniedFilter ? 'pass' : 'warning',
342
+ message: hasVpceAccessDeniedFilter
343
+ ? 'CloudTrail configured to filter VpceAccessDenied events'
344
+ : 'CloudTrail not filtering by VpceAccessDenied error code - may log unnecessary events',
345
+ });
346
+
347
+ // Check for CloudWatch Logs integration
348
+ const hasCloudWatchLogs = trailProps?.CloudWatchLogsLogGroupArn;
349
+
350
+ this.checks.push({
351
+ name: 'CloudTrail: CloudWatch Logs Integration',
352
+ status: hasCloudWatchLogs ? 'pass' : 'fail',
353
+ message: hasCloudWatchLogs
354
+ ? 'CloudTrail sending logs to CloudWatch for real-time analysis'
355
+ : 'CloudTrail not integrated with CloudWatch Logs - cannot create real-time alarms',
356
+ });
357
+ }
358
+
359
+ // Check for CloudWatch Log Group
360
+ const logGroup = Object.values(resources).find((r: any) => r.Type === 'AWS::Logs::LogGroup');
361
+
362
+ this.checks.push({
363
+ name: 'CloudWatch: Log Group',
364
+ status: logGroup ? 'pass' : 'fail',
365
+ message: logGroup
366
+ ? 'CloudWatch Log Group found for CloudTrail logs'
367
+ : 'Missing CloudWatch Log Group - required for metric filters and alarms',
368
+ });
369
+
370
+ // Check for Metric Filters
371
+ const metricFilters = Object.values(resources).filter((r: any) => r.Type === 'AWS::Logs::MetricFilter');
372
+
373
+ // Required: VpceAccessDenied filter
374
+ const hasVpceAccessDeniedFilter = metricFilters.some((mf: any) => {
375
+ const filterPattern = mf.Properties?.FilterPattern || '';
376
+ return filterPattern.toLowerCase().includes('errorcode') &&
377
+ filterPattern.toLowerCase().includes('vpceaccessdenied');
378
+ });
379
+
380
+ this.checks.push({
381
+ name: 'Metric Filter: VpceAccessDenied',
382
+ status: hasVpceAccessDeniedFilter ? 'pass' : 'fail',
383
+ message: hasVpceAccessDeniedFilter
384
+ ? 'Metric filter for VpceAccessDenied found'
385
+ : 'Missing metric filter for VpceAccessDenied - cannot detect VPC endpoint policy denials',
386
+ });
387
+
388
+ // Optional: Additional filters for enhanced security monitoring
389
+ const hasCrossAccountFilter = metricFilters.some((mf: any) => {
390
+ const filterPattern = mf.Properties?.FilterPattern || '';
391
+ return filterPattern.toLowerCase().includes('cross') ||
392
+ filterPattern.toLowerCase().includes('account');
393
+ });
394
+
395
+ const hasSuspiciousUserAgentFilter = metricFilters.some((mf: any) => {
396
+ const filterPattern = mf.Properties?.FilterPattern || '';
397
+ return filterPattern.toLowerCase().includes('useragent') ||
398
+ filterPattern.toLowerCase().includes('data') ||
399
+ filterPattern.toLowerCase().includes('exfil');
400
+ });
401
+
402
+ if (hasCrossAccountFilter || hasSuspiciousUserAgentFilter) {
403
+ this.checks.push({
404
+ name: 'Metric Filters: Enhanced Monitoring',
405
+ status: 'pass',
406
+ message: `Additional metric filters found for enhanced security monitoring (${hasCrossAccountFilter ? 'CrossAccountAccess' : ''}${hasCrossAccountFilter && hasSuspiciousUserAgentFilter ? ', ' : ''}${hasSuspiciousUserAgentFilter ? 'SuspiciousUserAgent' : ''})`,
407
+ });
408
+ }
409
+
410
+ // Check for CloudWatch Alarms
411
+ const alarms = Object.values(resources).filter((r: any) => r.Type === 'AWS::CloudWatch::Alarm');
412
+
413
+ this.checks.push({
414
+ name: 'CloudWatch: Alarms',
415
+ status: alarms.length >= 1 ? 'pass' : 'fail',
416
+ message:
417
+ alarms.length >= 1
418
+ ? `Found ${alarms.length} CloudWatch alarm(s) for security monitoring`
419
+ : 'No CloudWatch alarms found - cannot receive real-time security alerts',
420
+ });
421
+
422
+ // Check for SNS Topic
423
+ const snsTopic = Object.values(resources).find((r: any) => r.Type === 'AWS::SNS::Topic');
424
+
425
+ this.checks.push({
426
+ name: 'SNS: Alert Topic',
427
+ status: snsTopic ? 'pass' : 'fail',
428
+ message: snsTopic
429
+ ? 'SNS topic found for security alert notifications'
430
+ : 'Missing SNS topic - cannot send security alert notifications',
431
+ });
432
+
433
+ // Check that alarms are connected to SNS topic
434
+ if (snsTopic && alarms.length > 0) {
435
+ const alarmsWithActions = alarms.filter((alarm: any) =>
436
+ alarm.Properties?.AlarmActions && alarm.Properties.AlarmActions.length > 0
437
+ );
438
+
439
+ this.checks.push({
440
+ name: 'CloudWatch: Alarm Actions',
441
+ status: alarmsWithActions.length === alarms.length ? 'pass' : 'warning',
442
+ message:
443
+ alarmsWithActions.length === alarms.length
444
+ ? 'All alarms configured to send notifications'
445
+ : `${alarmsWithActions.length}/${alarms.length} alarms configured with actions - some alarms may not send notifications`,
446
+ });
447
+ }
448
+
449
+ // Check for S3 bucket for CloudTrail logs
450
+ const s3Buckets = Object.values(resources).filter((r: any) => r.Type === 'AWS::S3::Bucket');
451
+ const hasTrailBucket = s3Buckets.length > 0;
452
+
453
+ this.checks.push({
454
+ name: 'S3: CloudTrail Log Bucket',
455
+ status: hasTrailBucket ? 'pass' : 'warning',
456
+ message: hasTrailBucket
457
+ ? 'S3 bucket found for CloudTrail log storage'
458
+ : 'No S3 bucket found - CloudTrail logs may not be persisted long-term',
459
+ });
460
+
461
+ // Check for bucket encryption
462
+ if (hasTrailBucket) {
463
+ const hasEncryption = s3Buckets.some((bucket: any) =>
464
+ bucket.Properties?.BucketEncryption
465
+ );
466
+
467
+ this.checks.push({
468
+ name: 'S3: Bucket Encryption',
469
+ status: hasEncryption ? 'pass' : 'warning',
470
+ message: hasEncryption
471
+ ? 'S3 bucket configured with encryption'
472
+ : 'S3 bucket missing encryption configuration - logs may not be encrypted at rest',
473
+ });
474
+ }
475
+ }
310
476
  }