@aws/nx-plugin 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE-THIRD-PARTY +114 -244
  2. package/generators.json +1 -7
  3. package/package.json +1 -1
  4. package/src/cloudscape-website/app/README.md +84 -48
  5. package/src/cloudscape-website/app/__snapshots__/generator.spec.ts.snap +157 -218
  6. package/src/cloudscape-website/app/files/app/README.md.template +44 -0
  7. package/src/cloudscape-website/app/files/app/src/layouts/App/index.tsx.template +40 -43
  8. package/src/cloudscape-website/app/files/app/src/layouts/App/navitems.ts.template +3 -3
  9. package/src/cloudscape-website/app/files/app/src/layouts/Routes/index.tsx.template +4 -6
  10. package/src/cloudscape-website/app/files/app/src/main.tsx.template +7 -10
  11. package/src/cloudscape-website/app/files/app/src/pages/Home/index.tsx.template +0 -2
  12. package/src/cloudscape-website/app/files/common/constructs/src/app/static-websites/__websiteNameKebabCase__.ts.template +13 -0
  13. package/src/cloudscape-website/app/files/common/constructs/src/{__websiteNameKebabCase__ → core}/static-website.ts.template +74 -144
  14. package/src/cloudscape-website/app/generator.js +74 -64
  15. package/src/cloudscape-website/app/generator.js.map +1 -1
  16. package/src/cloudscape-website/app/schema.d.ts +3 -4
  17. package/src/cloudscape-website/app/schema.json +1 -24
  18. package/src/cloudscape-website/cognito-auth/README.md +53 -32
  19. package/src/cloudscape-website/cognito-auth/__snapshots__/generator.spec.ts.snap +161 -125
  20. package/src/cloudscape-website/cognito-auth/files/app/components/CognitoAuth/index.tsx.template +53 -39
  21. package/src/cloudscape-website/cognito-auth/files/common/constructs/src/core/user-identity.ts.template +168 -0
  22. package/src/cloudscape-website/cognito-auth/generator.js +129 -46
  23. package/src/cloudscape-website/cognito-auth/generator.js.map +1 -1
  24. package/src/cloudscape-website/cognito-auth/schema.d.ts +1 -0
  25. package/src/cloudscape-website/cognito-auth/schema.json +7 -1
  26. package/src/cloudscape-website/runtime-config/__snapshots__/generator.spec.ts.snap +15 -17
  27. package/src/cloudscape-website/runtime-config/files/app/components/RuntimeConfig/index.tsx.template +7 -10
  28. package/src/cloudscape-website/runtime-config/files/app/hooks/useRuntimeConfig.tsx.template +13 -0
  29. package/src/cloudscape-website/runtime-config/generator.js +3 -1
  30. package/src/cloudscape-website/runtime-config/generator.js.map +1 -1
  31. package/src/infra/app/README.md +71 -46
  32. package/src/infra/app/__snapshots__/generator.spec.ts.snap +114 -252
  33. package/src/infra/app/files/app/README.md.template +76 -0
  34. package/src/infra/app/files/app/src/main.ts.template +18 -0
  35. package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/aws-prototyping.guard +1282 -0
  36. package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/cfn-nag.guard +6839 -0
  37. package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/hipaa-security.guard +2807 -0
  38. package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/nist-csf.guard +2585 -0
  39. package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/pci-dss-3-2-1.guard +2236 -0
  40. package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/wa-reliability-pillar.guard +885 -0
  41. package/src/infra/app/files/common/constructs/src/core/cfn-guard-rules/wa-security-pillar.guard +2205 -0
  42. package/src/infra/app/files/common/constructs/src/core/cfn-guard.ts.template +63 -0
  43. package/src/infra/app/generator.js +17 -3
  44. package/src/infra/app/generator.js.map +1 -1
  45. package/src/infra/app/schema.d.ts +10 -1
  46. package/src/infra/app/schema.json +16 -8
  47. package/src/trpc/backend/README.md +102 -80
  48. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +37 -17
  49. package/src/trpc/backend/files/backend/README.md.template +33 -0
  50. package/src/trpc/backend/files/common/constructs/src/app/trpc-apis/__apiNameKebabCase__.ts.template +18 -0
  51. package/src/trpc/backend/files/common/constructs/src/{__apiNameKebabCase__/index.ts.template → core/trpc-api.ts.template} +12 -16
  52. package/src/trpc/backend/files/schema/README.md.template +33 -0
  53. package/src/trpc/backend/generator.js +29 -43
  54. package/src/trpc/backend/generator.js.map +1 -1
  55. package/src/trpc/backend/schema.d.ts +3 -1
  56. package/src/trpc/backend/schema.json +8 -13
  57. package/src/trpc/react/README.md +46 -66
  58. package/src/trpc/react/__snapshots__/generator.spec.ts.snap +104 -65
  59. package/src/trpc/react/files/src/components/TrpcClients/IsolatedTrpcProvider.tsx.template +75 -0
  60. package/src/trpc/react/files/src/components/TrpcClients/TrpcApis.tsx.template +1 -0
  61. package/src/trpc/react/files/src/components/TrpcClients/TrpcClientProviders.tsx.template +10 -0
  62. package/src/trpc/react/files/src/components/TrpcClients/index.tsx.template +5 -0
  63. package/src/trpc/react/files/src/hooks/useSigV4.tsx.template +38 -0
  64. package/src/trpc/react/files/src/hooks/use__apiNameClassName__.tsx.template +3 -0
  65. package/src/trpc/react/generator.js +123 -24
  66. package/src/trpc/react/generator.js.map +1 -1
  67. package/src/trpc/react/schema.json +2 -2
  68. package/src/ts/cjs-to-esm/generator.js.map +1 -1
  69. package/src/ts/lib/eslint.d.ts +1 -1
  70. package/src/ts/lib/eslint.js +59 -11
  71. package/src/ts/lib/eslint.js.map +1 -1
  72. package/src/ts/lib/files/README.md.template +33 -0
  73. package/src/ts/lib/generator.js +11 -4
  74. package/src/ts/lib/generator.js.map +1 -1
  75. package/src/ts/lib/schema.d.ts +1 -3
  76. package/src/ts/lib/schema.json +2 -15
  77. package/src/ts/lib/ts-project-utils.js.map +1 -1
  78. package/src/ts/lib/vitest.js +14 -0
  79. package/src/ts/lib/vitest.js.map +1 -1
  80. package/src/utils/ast.d.ts +13 -0
  81. package/src/utils/ast.js +102 -0
  82. package/src/utils/ast.js.map +1 -0
  83. package/src/utils/files/common/constructs/src/app/index.ts.template +0 -0
  84. package/src/utils/files/common/constructs/src/{runtime-config → core}/runtime-config.ts.template +3 -5
  85. package/src/utils/files/common/constructs/src/index.ts.template +2 -1
  86. package/src/utils/files/common/readme/README.md.template +33 -0
  87. package/src/utils/files/common/types/src/runtime-config.ts.template +1 -13
  88. package/src/utils/format.js.map +1 -1
  89. package/src/utils/names.d.ts +2 -0
  90. package/src/utils/names.js +27 -0
  91. package/src/utils/names.js.map +1 -0
  92. package/src/utils/npm-scope.js.map +1 -1
  93. package/src/utils/paths.js.map +1 -1
  94. package/src/utils/shared-constructs.js +37 -4
  95. package/src/utils/shared-constructs.js.map +1 -1
  96. package/src/utils/versions.d.ts +15 -9
  97. package/src/utils/versions.js +14 -8
  98. package/src/utils/versions.js.map +1 -1
  99. package/src/cloudscape-website/app/files/common/constructs/src/__websiteNameKebabCase__/cloudfront-web-acl.ts.template +0 -317
  100. package/src/cloudscape-website/app/files/common/constructs/src/__websiteNameKebabCase__/index.ts.template +0 -4
  101. package/src/cloudscape-website/app/files/common/constructs/src/__websiteNameKebabCase__/webacl_event_handler/index.ts.template +0 -301
  102. package/src/cloudscape-website/cognito-auth/files/common/constructs/src/identity/index.ts.template +0 -4
  103. package/src/cloudscape-website/cognito-auth/files/common/constructs/src/identity/user-identity.ts.template +0 -66
  104. package/src/cloudscape-website/cognito-auth/files/common/constructs/src/identity/userpool-with-mfa.ts.template +0 -70
  105. package/src/gitlab/generator.d.ts +0 -8
  106. package/src/gitlab/generator.js +0 -16
  107. package/src/gitlab/generator.js.map +0 -1
  108. package/src/gitlab/schema.d.ts +0 -9
  109. package/src/gitlab/schema.json +0 -52
  110. package/src/infra/app/files/src/main.ts.template +0 -37
  111. package/src/trpc/react/files/src/components/TRPCClientProvider/index.tsx.template +0 -34
  112. package/src/trpc/react/files/src/hooks/useTrpc.tsx.template +0 -5
  113. /package/src/infra/app/files/{cdk.json → app/cdk.json} +0 -0
  114. /package/src/infra/app/files/{src → app/src}/stacks/application-stack.ts.template +0 -0
  115. /package/src/utils/files/common/constructs/src/{runtime-config → core}/index.ts.template +0 -0
@@ -0,0 +1,1282 @@
1
+ #
2
+ #####################################
3
+ ## Gherkin ##
4
+ #####################################
5
+ #
6
+ # Rule Identifier:
7
+ # AUTOSCALING_LAUNCH_CONFIG_PUBLIC_IP_DISABLED
8
+ #
9
+ # Description:
10
+ # Checks that Amazon EC2 Auto Scaling launch configurations are configured to not associate public IP addresses
11
+ #
12
+ # Reports on:
13
+ # AWS::AutoScaling::LaunchConfiguration
14
+ #
15
+ # Evaluates:
16
+ # AWS CloudFormation
17
+ #
18
+ # Rule Parameters:
19
+ # NA
20
+ #
21
+ # Scenarios:
22
+ # a) SKIP: when there are no AutoScaling::LaunchConfiguration resource present
23
+ # b) SKIP: when metada has rule suppression for AUTOSCALING_LAUNCH_CONFIG_PUBLIC_IP_DISABLED
24
+ # c) FAIL: when all AutoScaling::LaunchConfiguration resources AssociatePublicIpAddress property does not exist
25
+ # d) FAIL: when all AutoScaling::LaunchConfiguration resources have AssociatePublicIpAddress set to true
26
+ # e) PASS: when all AutoScaling::LaunchConfiguration resources AssociatePublicIpAddress property is set to false
27
+
28
+ #
29
+ # Select all AutoScaling Launch Configuration resources from incoming template (payload)
30
+ #
31
+ let autoscaling_launch_config_public_ip_disabled = Resources.*[ Type == "AWS::AutoScaling::LaunchConfiguration"
32
+ Metadata.guard.SuppressedRules not exists or
33
+ Metadata.guard.SuppressedRules.* != "AUTOSCALING_LAUNCH_CONFIG_PUBLIC_IP_DISABLED"
34
+ ]
35
+
36
+ rule AUTOSCALING_LAUNCH_CONFIG_PUBLIC_IP_DISABLED when %autoscaling_launch_config_public_ip_disabled !empty {
37
+ %autoscaling_launch_config_public_ip_disabled.Properties {
38
+ AssociatePublicIpAddress exists
39
+ AssociatePublicIpAddress == false
40
+ <<
41
+ Guard Rule Set: aws-prototyping
42
+ Controls: AutoScalingLaunchConfigPublicIpDisabled
43
+ Violation: Amazon EC2 Auto Scaling launch configurations are configured to not associate public IP addresses
44
+ Fix: Explicitly set the AssociatePublicIpAddress attribute to false.
45
+ >>
46
+ }
47
+ }
48
+
49
+ #
50
+ #####################################
51
+ ## Gherkin ##
52
+ #####################################
53
+ # Rule Identifier:
54
+ # CLOUDFRONT_ORIGIN_ACCESS_CONTROL_ENABLED
55
+ #
56
+ # Description:
57
+ # Checks if Amazon CloudFront distributions backed by S3 are configured with an Origin Access Control (OAC).
58
+ #
59
+ # Reports on:
60
+ # AWS::CloudFront::Distribution
61
+ #
62
+ # Evaluates:
63
+ # AWS CloudFormation
64
+ #
65
+ # Rule Parameters:
66
+ # NA
67
+ #
68
+ # Scenarios:
69
+ # a) SKIP: when there are no CloudFront Distribution Resources
70
+ # b) SKIP: when metadata has rule suppression for CLOUDFRONT_ORIGIN_ACCESS_IDENTITY_ENABLED
71
+ # c) FAIL: when CloudFront Distribution Resources have a Legacy S3 Origin configuration present
72
+ # d) FAIL: when CloudFront Distribution Resources have an S3 Origin configured without an Origin Access Identity (OAI)
73
+ # e) PASS: when CloudFront Distribution Resources do not have an S3 Origin configured
74
+ # f) PASS: when CloudFront Distribution Resources have an S3 Origin configured with an Origin Access Identity (OAI)
75
+
76
+ #
77
+ # Select all CloudFront Distribution Resources from incoming template (payload)
78
+ #
79
+ let cloudfront_origin_access_control_enabled_resources = Resources.*[ Type == 'AWS::CloudFront::Distribution'
80
+ Metadata.guard.SuppressedRules not exists or
81
+ Metadata.guard.SuppressedRules.* != "CLOUDFRONT_ORIGIN_ACCESS_CONTROL_ENABLED"
82
+ ]
83
+
84
+ rule CLOUDFRONT_ORIGIN_ACCESS_CONTROL_ENABLED when %cloudfront_origin_access_control_enabled_resources !empty {
85
+ let doc = this
86
+ %cloudfront_origin_access_control_enabled_resources.Properties.DistributionConfig {
87
+ S3Origin not exists
88
+
89
+ when Origins exists
90
+ Origins is_list
91
+ Origins not empty {
92
+
93
+ Origins [
94
+ DomainName == /(.*)\.s3(-external-\d|[-\.][a-z]*-[a-z]*-[0-9])?\.amazonaws\.com(\.cn)?$/ or
95
+ DomainName {
96
+ 'Fn::GetAtt' {
97
+ this is_list
98
+ this[1] == "DomainName" or
99
+ this[1] == "RegionalDomainName"
100
+
101
+ let resource_logical_name = this[0]
102
+ let referenced_resource = %doc.Resources[ keys == %resource_logical_name ]
103
+
104
+ %referenced_resource not empty
105
+ %referenced_resource {
106
+ Type == "AWS::S3::Bucket"
107
+ }
108
+ }
109
+ }
110
+ ] {
111
+ OriginAccessControlId exists
112
+ OriginAccessControlId is_struct
113
+ <<
114
+ Guard Rule Set: aws-prototyping
115
+ Controls: CloudFrontDistributionS3OriginAccessControl
116
+ Violation: CloudFront Distributions backed by S3 must be configured with an Origin Access Control (OAC).
117
+ Fix: Set the OriginAccessControlId property for CloudFront Distribution Origins backed by S3.
118
+ >>
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ #
125
+ #####################################
126
+ ## Gherkin ##
127
+ #####################################
128
+ #
129
+ # Rule Identifier:
130
+ # CODEBUILD_PROJECT_ENVVAR_AWSCRED_CHECK
131
+ #
132
+ # Description:
133
+ # Checks whether the project contains environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
134
+ #
135
+ # Reports on:
136
+ # AWS::CodeBuild::Project
137
+ #
138
+ # Evaluates:
139
+ # AWS CloudFormation
140
+ #
141
+ # Rule Parameters:
142
+ # NA
143
+ #
144
+ # Scenarios:
145
+ # a) SKIP: when there are no AWS::CodeBuild::Project resources
146
+ # b) SKIP: when metada has rule suppression for CODEBUILD_PROJECT_ENVVAR_AWSCRED_CHECK
147
+ # c) FAIL: environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are present
148
+ # d) PASS: when environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not present
149
+
150
+ #
151
+ # Select all Code Build resources from incoming template (payload)
152
+ #
153
+ let codebuild_project_envvar_awscred_check = Resources.*[ Type == "AWS::CodeBuild::Project"
154
+ Metadata.guard.SuppressedRules not exists or
155
+ Metadata.guard.SuppressedRules.* != "CODEBUILD_PROJECT_ENVVAR_AWSCRED_CHECK"
156
+ ]
157
+ let disallowed_names = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
158
+
159
+ rule CODEBUILD_PROJECT_ENVVAR_AWSCRED_CHECK when %codebuild_project_envvar_awscred_check !empty {
160
+ %codebuild_project_envvar_awscred_check.Properties {
161
+ Environment !exists OR
162
+ Environment {
163
+ EnvironmentVariables !exists OR
164
+ EnvironmentVariables [
165
+ Type == "PLAINTEXT"
166
+ ] {
167
+ Name NOT IN %disallowed_names
168
+ <<
169
+ Guard Rule Set: aws-prototyping
170
+ Controls: CodeBuildProjectEnvVarAwsCred
171
+ Violation: AWS CodeBuild Projects are not configured with environment variables that contain credentials in PLAINTEXT
172
+ Fix: Remove environment variables that contain credentials in PLAINTEXT ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY")
173
+ >>
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ #
180
+ #####################################
181
+ ## AWS Solutions ##
182
+ #####################################
183
+ #
184
+ # Rule Identifier:
185
+ # COGNITO_ALLOW_UNAUTHENTICATED_IDENTITIES_RULE
186
+ #
187
+ # Description:
188
+ # AWS::Cognito::IdentityPool AllowUnauthenticatedIdentities property should be false. But CAN be true if proper restrictive IAM roles and permissions are established for unauthenticated users.
189
+ #
190
+ # Reports on:
191
+ # AWS::Cognito::IdentityPool
192
+ #
193
+ # Evaluates:
194
+ # AWS CloudFormation
195
+ #
196
+ # Rule Parameters:
197
+ # None
198
+ #
199
+ # CFN_NAG Rule Id:
200
+ # W57
201
+ #
202
+ # Scenarios:
203
+ # a) SKIP: when there are no Cognito Identity Pool Resources.
204
+ # b) SKIP: when metadata has rule suppression for COGNITO_ALLOW_UNAUTHENTICATED_IDENTITIES_RULE.
205
+ # c) FAIL: when AllowUnauthenticatedIdentities in Cognito Identity Pool Resources is set to true.
206
+ # d) PASS: when AllowUnauthenticatedIdentities in Cognito Identity Pool Resources is set to false.
207
+
208
+ #
209
+ # Select all Cognito Identity Pool Resources from incoming template (payload)
210
+ #
211
+ let cognito_allow_unauthenticated_identities_rule = Resources.*[ Type == 'AWS::Cognito::IdentityPool'
212
+ Metadata.cfn_nag.rules_to_suppress not exists or
213
+ Metadata.cfn_nag.rules_to_suppress.*.id != "W57"
214
+ Metadata.guard.SuppressedRules not exists or
215
+ Metadata.guard.SuppressedRules.* != "COGNITO_ALLOW_UNAUTHENTICATED_IDENTITIES_RULE"
216
+ ]
217
+
218
+ rule COGNITO_ALLOW_UNAUTHENTICATED_IDENTITIES_RULE when %cognito_allow_unauthenticated_identities_rule !empty {
219
+ let violations = %cognito_allow_unauthenticated_identities_rule[
220
+ Type == 'AWS::Cognito::IdentityPool'
221
+ Properties.AllowUnauthenticatedIdentities == /(?i)true/
222
+ OR
223
+ Properties.AllowUnauthenticatedIdentities == true
224
+ OR
225
+ Properties.AllowUnauthenticatedIdentities == True
226
+ OR
227
+ Properties.AllowUnauthenticatedIdentities == TRUE
228
+ ]
229
+
230
+ %violations empty
231
+ <<
232
+ Guard Rule Set: aws-prototyping
233
+ Controls: CognitoUserPoolNoUnauthenticatedLogins
234
+ Violation: AllowUnauthenticatedIdentities in Cognito Identity Pool Resources is set to true.
235
+ Fix: set AllowUnauthenticatedIdentities to false in Cognito Identity Pool Resources.
236
+ >>
237
+ }
238
+
239
+ #
240
+ #####################################
241
+ ## Gherkin ##
242
+ #####################################
243
+ # Rule Identifier:
244
+ # DMS_REPLICATION_NOT_PUBLIC
245
+ #
246
+ # Description:
247
+ # Checks whether AWS Database Migration Service replication instances are not set to allow public.
248
+ #
249
+ # Reports on:
250
+ # AWS::DMS::ReplicationInstance
251
+ #
252
+ # Evaluates:
253
+ # AWS CloudFormation
254
+ #
255
+ # Rule Parameters:
256
+ # NA
257
+ #
258
+ # Scenarios:
259
+ # a) SKIP: when there is no DMS Replication Instance present
260
+ # b) FAIL: When DMS Replication Instance is present and PubliclyAccessible property is set to true
261
+ # c) PASS: When DMS Replication Instance is present and PubliclyAccessible property is set to false
262
+ # c) FAIL: When DMS Replication Instance is present and PubliclyAccessible property is not set
263
+ # d) SKIP: when metadata has rule suppression for DMS_REPLICATION_NOT_PUBLIC or cfn_nag W91
264
+
265
+ #
266
+ # Select all DMS ReplicationInstance resources from incoming template
267
+ #
268
+
269
+ let dms_replication_instances = Resources.*[ Type == 'AWS::DMS::ReplicationInstance'
270
+ Metadata.cfn_nag.rules_to_suppress not exists or
271
+ Metadata.cfn_nag.rules_to_suppress.*.id != "W91"
272
+ Metadata.guard.SuppressedRules not exists or
273
+ Metadata.guard.SuppressedRules.* != "DMS_REPLICATION_NOT_PUBLIC"
274
+ ]
275
+
276
+ rule DMS_REPLICATION_NOT_PUBLIC when %dms_replication_instances !empty {
277
+ %dms_replication_instances.Properties.PubliclyAccessible exists
278
+ %dms_replication_instances.Properties.PubliclyAccessible == false
279
+ <<
280
+ Guard Rule Set: aws-prototyping
281
+ Controls: DMSReplicationNotPublic
282
+ Violation: AWS Database Migration Service replication instances should not be public.
283
+ Fix: Set the DMS Replication Instance property PubliclyAccessible parameter to false.
284
+ >>
285
+ }
286
+
287
+ #
288
+ #####################################
289
+ ## Gherkin ##
290
+ #####################################
291
+ # Rule Identifier:
292
+ # EC2_INSTANCES_IN_VPC
293
+ #
294
+ # Description:
295
+ # Checks if your EC2 instances belong to a virtual private cloud (VPC).
296
+ #
297
+ # Reports on:
298
+ # AWS::EC2::Instance
299
+ #
300
+ # Evaluates:
301
+ # AWS CloudFormation
302
+ #
303
+ # Rule Parameters:
304
+ # NA
305
+ #
306
+ # Scenarios:
307
+ # a) SKIP: when there are no EC2 resource present
308
+ # b) PASS: when all EC2 resources have the SubnetId property set
309
+ # c) FAIL: when any EC2 resources do not have the SubnetId property set
310
+ # d) SKIP: when metadata includes the suppression for rule EC2_INSTANCES_IN_VPC
311
+
312
+ #
313
+ # Select all ECS Instance resources from incoming template (payload)
314
+ #
315
+ let ec2_instances_in_vpc = Resources.*[ Type == 'AWS::EC2::Instance'
316
+ Metadata.guard.SuppressedRules not exists or
317
+ Metadata.guard.SuppressedRules.* != "EC2_INSTANCES_IN_VPC"
318
+ ]
319
+
320
+ rule EC2_INSTANCES_IN_VPC when %ec2_instances_in_vpc !empty {
321
+ %ec2_instances_in_vpc.Properties.SubnetId !empty
322
+ <<
323
+ Guard Rule Set: aws-prototyping
324
+ Controls: EC2InstancesInVPC
325
+ Violation: EC2 Instances must belong to a VPC
326
+ Fix: set the SubnetId property to a subnet ID
327
+ >>
328
+ }
329
+ #
330
+ #####################################
331
+ ## Gherkin ##
332
+ #####################################
333
+ # Rule Identifier:
334
+ # RESTRICTED_INCOMING_TRAFFIC
335
+ #
336
+ # Description:
337
+ # Checks if the security groups in use do not allow unrestricted incoming TCP traffic to the specified ports.
338
+ #
339
+ # Reports on:
340
+ # AWS::EC2::SecurityGroup
341
+ #
342
+ # Evaluates:
343
+ # AWS CloudFormation
344
+ #
345
+ # Rule Parameters:
346
+ # NA
347
+ #
348
+ # Scenarios:
349
+ # a) SKIP: when there are no Security Groups resource present
350
+ # b) SKIP when there are no TCP or UDP ingress rules
351
+ # c) PASS: when all Security Groups do no allow any of the restricted common ports
352
+ # d) FAIL: when a Security Group allows any of the restricted common ports
353
+ # e) SKIP: when metadata includes the suppression for rule RESTRICTED_INCOMING_TRAFFIC
354
+
355
+ #
356
+ # Select all Security Group resources from incoming template (payload)
357
+ #
358
+ let aws_security_groups_restricted_incoming_traffic = Resources.*[ Type == 'AWS::EC2::SecurityGroup'
359
+ some Properties.SecurityGroupIngress[*] {
360
+ IpProtocol in ['tcp', 'udp']
361
+ }
362
+ Metadata.guard.SuppressedRules not exists or
363
+ Metadata.guard.SuppressedRules.* != "RESTRICTED_INCOMING_TRAFFIC"
364
+ ]
365
+
366
+ rule RESTRICTED_INCOMING_TRAFFIC when %aws_security_groups_restricted_incoming_traffic !empty {
367
+ let violations = %aws_security_groups_restricted_incoming_traffic[
368
+ Type == 'AWS::EC2::SecurityGroup'
369
+ some Properties.SecurityGroupIngress[*] {
370
+ FromPort in [ 20, 21, 3389, 3306, 4333 ]
371
+ ToPort in [ 20, 21, 3389, 3306, 4333 ]
372
+ }
373
+ ]
374
+ %violations empty
375
+ <<
376
+ Guard Rule Set: aws-prototyping
377
+ Controls: EC2RestrictedCommonPorts
378
+ Violation: Security groups must not allow unrestricted incoming TCP/UDP traffic to the specified ports [20, 21, 3389, 3306, 4333].
379
+ Fix: change the FromPort and ToPort properties in the SecurityGroupIngress list
380
+ >>
381
+ }
382
+ #
383
+ #####################################
384
+ ## Gherkin ##
385
+ #####################################
386
+ # Rule Identifier:
387
+ # RESTRICTED_INCOMING_TRAFFIC
388
+ #
389
+ # Description:
390
+ # Checks if the security groups in use do not allow unrestricted incoming TCP traffic to the specified ports.
391
+ #
392
+ # Reports on:
393
+ # AWS::EC2::SecurityGroup
394
+ #
395
+ # Evaluates:
396
+ # AWS CloudFormation
397
+ #
398
+ # Rule Parameters:
399
+ # NA
400
+ #
401
+ # Scenarios:
402
+ # a) SKIP: when there are no Security Groups resource present
403
+ # b) SKIP when there are no TCP or UDP ingress rules
404
+ # c) PASS: when all Security Groups do no allow any of the restricted common ports
405
+ # d) FAIL: when a Security Group allows any of the restricted common ports
406
+ # e) SKIP: when metadata includes the suppression for rule RESTRICTED_INCOMING_TRAFFIC
407
+
408
+ #
409
+ # Select all Security Group resources from incoming template (payload)
410
+ #
411
+ let aws_security_groups_restricted_incoming_traffic = Resources.*[ Type == 'AWS::EC2::SecurityGroup'
412
+ some Properties.SecurityGroupIngress[*] {
413
+ IpProtocol in ['tcp', 'udp']
414
+ }
415
+ Metadata.guard.SuppressedRules not exists or
416
+ Metadata.guard.SuppressedRules.* != "RESTRICTED_INCOMING_TRAFFIC"
417
+ ]
418
+
419
+ rule RESTRICTED_INCOMING_TRAFFIC when %aws_security_groups_restricted_incoming_traffic !empty {
420
+ let violations = %aws_security_groups_restricted_incoming_traffic[
421
+ Type == 'AWS::EC2::SecurityGroup'
422
+ some Properties.SecurityGroupIngress[*] {
423
+ FromPort in [ 20, 21, 3389, 3306, 4333 ]
424
+ ToPort in [ 20, 21, 3389, 3306, 4333 ]
425
+ }
426
+ ]
427
+ %violations empty
428
+ <<
429
+ Guard Rule Set: aws-prototyping
430
+ Controls: EC2RestrictedCommonPorts
431
+ Violation: Security groups must not allow unrestricted incoming TCP/UDP traffic to the specified ports [20, 21, 3389, 3306, 4333].
432
+ Fix: change the FromPort and ToPort properties in the SecurityGroupIngress list
433
+ >>
434
+ }
435
+ #
436
+ #####################################
437
+ ## AWS Solutions ##
438
+ #####################################
439
+ # Rule Identifier:
440
+ # EC2_SECURITY_GROUP_INGRESS_OPEN_TO_WORLD_RULE
441
+ #
442
+ # Description:
443
+ # Check if cidr FOR ipv4 and ipv6 on security group ingress is open or private.
444
+ #
445
+ # Reports on:
446
+ # [AWS::EC2::SecurityGroupIngress, AWS::EC2::SecurityGroup]
447
+ #
448
+ # Evaluates:
449
+ # AWS CloudFormation
450
+ #
451
+ # Rule Parameters:
452
+ # NA
453
+ #
454
+ # CFN_NAG Rule Id:
455
+ # W2
456
+ #
457
+ # Scenarios:
458
+ # a) SKIP: when there are no Security Ingress Groups resource present
459
+ # b) PASS: When all Security Ingress Groups do not use open to world cidr
460
+ # c) FAIL: when any Security Ingress Groups uses open to world cidr
461
+ # d) SKIP: when metadata has rule suppression for EC2_SECURITY_GROUP_INGRESS_OPEN_TO_WORLD_RULE
462
+
463
+ #
464
+ # Select all Security Group Ingress resources from incoming template (payload)
465
+ #
466
+
467
+ let ec2_security_group_ingress_open_to_world_rule_sg_ingress_resources = Resources.*[ Type == 'AWS::EC2::SecurityGroup'
468
+ Metadata.cfn_nag.rules_to_suppress not exists or
469
+ Metadata.cfn_nag.rules_to_suppress.*.id != "W2"
470
+ Metadata.guard.SuppressedRules not exists or
471
+ Metadata.guard.SuppressedRules.* != "EC2_SECURITY_GROUP_INGRESS_OPEN_TO_WORLD_RULE"
472
+ ]
473
+
474
+ let ec2_security_group_ingress_open_to_world_rule_sgi_resources = Resources.*[ Type == 'AWS::EC2::SecurityGroupIngress'
475
+ Metadata.cfn_nag.rules_to_suppress not exists or
476
+ Metadata.cfn_nag.rules_to_suppress.*.id != "W2"
477
+ Metadata.guard.SuppressedRules not exists or
478
+ Metadata.guard.SuppressedRules.* != "EC2_SECURITY_GROUP_INGRESS_OPEN_TO_WORLD_RULE"
479
+ ]
480
+
481
+ rule EC2_SECURITY_GROUP_INGRESS_OPEN_TO_WORLD_RULE when %ec2_security_group_ingress_open_to_world_rule_sgi_resources !empty OR %ec2_security_group_ingress_open_to_world_rule_sg_ingress_resources !empty {
482
+ let violations_sg = %ec2_security_group_ingress_open_to_world_rule_sg_ingress_resources[
483
+ Type == 'AWS::EC2::SecurityGroup'
484
+ Properties.SecurityGroupIngress exists
485
+ some Properties.SecurityGroupIngress[*].CidrIp == '0.0.0.0/0'
486
+ OR
487
+ some Properties.SecurityGroupIngress[*].CidrIpv6 == '::/0'
488
+ ]
489
+
490
+ let violations_sgi = %ec2_security_group_ingress_open_to_world_rule_sgi_resources[
491
+ Type == 'AWS::EC2::SecurityGroupIngress'
492
+ Properties.CidrIp == '0.0.0.0/0'
493
+ OR
494
+ Properties.CidrIpv6 == '::/0'
495
+ ]
496
+
497
+ %violations_sg empty
498
+ %violations_sgi empty
499
+ <<
500
+ Guard Rule Set: aws-prototyping
501
+ Controls: EC2RestrictedInbound
502
+ Violation: Security Group Ingress has a range of ports instead of a single port
503
+ Fix: Use single port instead of range of ports for ingress rules
504
+ >>
505
+ }
506
+
507
+ #
508
+ #####################################
509
+ ## Gherkin ##
510
+ #####################################
511
+ # Rule Identifier:
512
+ # INCOMING_SSH_DISABLED
513
+ #
514
+ # Description:
515
+ # Checks if the incoming SSH traffic for the security groups is accessible.
516
+ #
517
+ # Reports on:
518
+ # AWS::EC2::SecurityGroup
519
+ #
520
+ # Evaluates:
521
+ # AWS CloudFormation
522
+ #
523
+ # Rule Parameters:
524
+ # NA
525
+ #
526
+ # Scenarios:
527
+ # a) SKIP: when no Security Group resources are present
528
+ # b) SKIP: when no SSH ingress is defined (port 22)
529
+ # c) PASS: when all Security Groups resources restrict the IP address of the incoming SSH traffic
530
+ # d) FAIL: when a Security Group allows SSH traffic from any IP address (0.0.0.0/0).
531
+ # e) SKIP: hen metadata includes the suppression for rule INCOMING_SSH_DISABLED
532
+
533
+ #
534
+ # Select all Security Group resources from incoming template (payload)
535
+ #
536
+ let aws_security_groups_restricted_ssh = Resources.*[
537
+ Type == 'AWS::EC2::SecurityGroup'
538
+ some Properties.SecurityGroupIngress[*] {
539
+ ToPort == 22
540
+ FromPort == 22
541
+ IpProtocol == "tcp"
542
+ }
543
+ Metadata.guard.SuppressedRules not exists or
544
+ Metadata.guard.SuppressedRules.* != "INCOMING_SSH_DISABLED"
545
+ ]
546
+
547
+ rule INCOMING_SSH_DISABLED when %aws_security_groups_restricted_ssh !empty {
548
+ %aws_security_groups_restricted_ssh.Properties.SecurityGroupIngress[*] != {CidrIp:"0.0.0.0/0", ToPort:22, FromPort:22, IpProtocol:"tcp"}
549
+ <<
550
+ Guard Rule Set: aws-prototyping
551
+ Controls: EC2RestrictedSSH
552
+ Violation: IP addresses of the incoming SSH traffic in the security groups are restricted (CIDR other than 0.0.0.0/0)
553
+ Fix: set SecurityGroupIngress.CidrIp property to a more restrictive CIDR than 0.0.0.0/0
554
+ >>
555
+ }
556
+ #
557
+ #####################################
558
+ ## Gherkin ##
559
+ #####################################
560
+ # Rule Identifier:
561
+ # EKS_ENDPOINT_NO_PUBLIC_ACCESS
562
+ #
563
+ # Description:
564
+ # Checks whether Amazon Elastic Kubernetes Service (Amazon EKS) endpoint is not publicly accessible.
565
+ #
566
+ # Reports on:
567
+ # AWS::EKS::Cluster
568
+ #
569
+ # Evaluates:
570
+ # AWS CloudFormation
571
+ #
572
+ # Rule Parameters:
573
+ # NA
574
+ #
575
+ # Scenarios:
576
+ # a) SKIP: when there are no EKS clusters present
577
+ # b) PASS: when all EKS cluster endpoints are not publicly accessible
578
+ # c) FAIL: when any EKS cluster endpoints are publicly accessible
579
+ # d) SKIP: when metada has rule suppression for EKS_ENDPOINT_NO_PUBLIC_ACCESS
580
+
581
+ #
582
+ # Select all EKS cluster resources from incoming template (payload)
583
+ #
584
+
585
+ let amazon_eks_clusters_endpoint_no_public_access = Resources.*[ Type == 'AWS::EKS::Cluster'
586
+ Metadata.guard.SuppressedRules not exists or
587
+ Metadata.guard.SuppressedRules.* != "EKS_ENDPOINT_NO_PUBLIC_ACCESS"
588
+ ]
589
+
590
+ rule EKS_ENDPOINT_NO_PUBLIC_ACCESS when %amazon_eks_clusters_endpoint_no_public_access !empty {
591
+ # ensure the optional parameter is specified in the template
592
+ %amazon_eks_clusters_endpoint_no_public_access.Properties.ResourcesVpcConfig.EndpointPublicAccess EXISTS
593
+ # ensure the parameter is set to false
594
+ %amazon_eks_clusters_endpoint_no_public_access.Properties.ResourcesVpcConfig.EndpointPublicAccess == false
595
+ <<
596
+ Guard Rule Set: aws-prototyping
597
+ Controls: EKSClusterNoEndpointPublicAccess
598
+ Violation: EKS endpoint public access is not allowed.
599
+ Fix: Set the boolean parameter ResourcesVpcConfig.EndpointPublicAccess to false
600
+ >>
601
+ }
602
+ ## Config Rule Name : elastic-beanstalk-managed-updates-enabled
603
+ ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elastic-beanstalk-managed-updates-enabled.html"
604
+
605
+ #
606
+ #####################################
607
+ ## Gherkin ##
608
+ #####################################
609
+ # Rule Identifier:
610
+ # IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS
611
+ #
612
+ # Description:
613
+ # Checks the IAM policies that you create for Allow statements that grant permissions to all actions on all resources.
614
+ #
615
+ # Reports on:
616
+ # AWS::IAM::Policy
617
+ #
618
+ # Evaluates:
619
+ # AWS CloudFormation
620
+ #
621
+ # Rule Parameters:
622
+ # NA
623
+ #
624
+ # Scenarios:
625
+ # a) SKIP: when there are no IAM Policies present
626
+ # b) PASS: when all IAM Policies do not grant permissions to all actions on all resources
627
+ # c) FAIL: when any IAM Policies grant permissions to all actions on all resources
628
+ # d) SKIP: when metadata has rule suppression for IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS
629
+
630
+ #
631
+ # Select all IAM Policy resources from incoming template (payload)
632
+ #
633
+ let aws_iam_policies_no_statements_with_admin_access = Resources.*[ Type == 'AWS::IAM::Policy'
634
+ Metadata.guard.SuppressedRules not exists or
635
+ Metadata.guard.SuppressedRules.* != "IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS"
636
+ ]
637
+
638
+ rule IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS when %aws_iam_policies_no_statements_with_admin_access !empty {
639
+ let violations = Resources.*[
640
+ Type == 'AWS::IAM::Policy'
641
+ some Properties.PolicyDocument.Statement[*] {
642
+ some Action[*] == "*"
643
+ Effect == "Allow"
644
+ some Resource in ["*"]
645
+ }
646
+ ]
647
+ %violations empty
648
+ <<
649
+ Guard Rule Set: aws-prototyping
650
+ Controls: IAMPolicyNoStatementsWithAdminAccess
651
+ Violation: One or more IAM policies contain allow statements that grant permissions to all actions on all resources
652
+ Fix: Remove policy statements that match {"Effect": "Allow", "Action": "*", "Resource": "*"}
653
+ >>
654
+ }
655
+
656
+
657
+
658
+ #
659
+ #####################################
660
+ ## Gherkin ##
661
+ #####################################
662
+ # Rule Identifier:
663
+ # LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED
664
+ #
665
+ # Description:
666
+ # Checks if the AWS Lambda function policy attached to the Lambda resource prohibits public access.
667
+ #
668
+ # Reports on:
669
+ # AWS::Lambda::Permission
670
+ # AWS::Lambda::LayerVersionPermission
671
+ #
672
+ # Evaluates:
673
+ # AWS CloudFormation
674
+ #
675
+ # Rule Parameters:
676
+ # NA
677
+ #
678
+ # Scenarios:
679
+ # a) SKIP: when no AWS Lambda permission policies are present
680
+ # b) PASS: when all AWS Lambda permission policies prohibit public access
681
+ # c) FAIL: when any AWS Lambda permission policies allow public access
682
+ # d) SKIP: hen metadata includes the suppression for rule LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED
683
+
684
+ #
685
+ # Select all AWS Lambda Permission resources from incoming template (payload)
686
+ #
687
+ let aws_lambda_permissions_public_access_prohibited = Resources.*[
688
+ Type in [ /AWS::Lambda::Permission/,
689
+ /AWS::Lambda::LayerVersionPermission/ ]
690
+ Metadata.guard.SuppressedRules not exists or
691
+ Metadata.guard.SuppressedRules.* != "LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED"
692
+ ]
693
+
694
+ rule LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED when %aws_lambda_permissions_public_access_prohibited !empty {
695
+
696
+ # Lambda permission policy where principal is an account id
697
+ %aws_lambda_permissions_public_access_prohibited {
698
+ Type == 'AWS::Lambda::Permission'
699
+ Properties {
700
+ Principal in [ /^\d{12}$/, {"Ref":"AWS::AccountId"} ]
701
+ OR Principal > 0
702
+ }
703
+ }
704
+
705
+ # Lambda permission policy where principal is a service (not s3)
706
+ OR %aws_lambda_permissions_public_access_prohibited {
707
+ Type == 'AWS::Lambda::Permission'
708
+ Properties {
709
+ Principal != 's3.amazonaws.com'
710
+ PrincipalOrgID !empty
711
+ OR SourceAccount exists
712
+ OR SourceArn !empty
713
+ <<
714
+ Guard Rule Set: aws-prototyping
715
+ Controls: LambdaFunctionPublicAccessProhibited
716
+ Violation: All Lambda permission policies attached to Lambda resources must prohibit public access.
717
+ Fix: Limit permission policies by setting the Principal property to an account ID,
718
+ or limiting a service principal by setting the SourceArn, SourceAccount, or PrincipalOrgID properties.
719
+ >>
720
+ }
721
+ }
722
+
723
+ # Lambda permission policy where principal is s3 service
724
+ OR %aws_lambda_permissions_public_access_prohibited {
725
+ Type == 'AWS::Lambda::Permission'
726
+ Properties {
727
+ Principal == 's3.amazonaws.com'
728
+ PrincipalOrgID !empty
729
+ OR SourceAccount exists
730
+ <<
731
+ Guard Rule Set: aws-prototyping
732
+ Controls: LambdaFunctionPublicAccessProhibited
733
+ Violation: All Lambda permission policies attached to Lambda resources must prohibit public access.
734
+ Fix: Limit permission policies by setting the Principal property to an account ID,
735
+ or for S3 as the principal specify either a SourceAccount or PrincipalOrgID.
736
+ Note: It is possible for an S3 bucket to be deleted by its owner and recreated by another account.
737
+ >>
738
+ }
739
+ }
740
+
741
+ # Lambda layer version permission policies
742
+ OR %aws_lambda_permissions_public_access_prohibited {
743
+ Type == 'AWS::Lambda::LayerVersionPermission'
744
+ Properties {
745
+ OrganizationId !empty
746
+ OR Principal in [ /^\d{12}$/, {"Ref":"AWS::AccountId"} ]
747
+ OR Principal > 0
748
+ <<
749
+ Guard Rule Set: aws-prototyping
750
+ Controls: LambdaFunctionPublicAccessProhibited
751
+ Violation: All Lambda permission policies attached to Lambda resources must prohibit public access.
752
+ Fix: For Lambda layer version permission policies, either limit permissions by the OrganizationId property
753
+ or set the Principal property to an account ID rather than using a wildcard (*).
754
+ >>
755
+ }
756
+ }
757
+ }
758
+
759
+ #
760
+ #####################################
761
+ ## AWS Solutions ##
762
+ #####################################
763
+ # Rule Identifier:
764
+ # LAMBDA_PERMISSION_INVOKE_FUNCTION_ACTION
765
+ #
766
+ # Description:
767
+ # Checks if the AWS Lambda permission uses any other action apart from 'lambda:InvokeFunction'
768
+ #
769
+ # Reports on:
770
+ # AWS::Lambda::Permission
771
+ #
772
+ # Evaluates:
773
+ # AWS CloudFormation
774
+ #
775
+ # Rule Parameters:
776
+ # NA
777
+ #
778
+ # CFN_NAG Rule Id:
779
+ # W24
780
+ #
781
+ # Scenarios:
782
+ # a) SKIP: when no AWS Lambda permission policies are present
783
+ # b) PASS: when no AWS Lambda permission uses any other action apart from 'lambda:InvokeFunction'
784
+ # c) FAIL: when any AWS Lambda permission allows action apart from 'lambda:InvokeFunction'
785
+ # d) SKIP: When metadata includes the suppression for rule LAMBDA_PERMISSION_INVOKE_FUNCTION_ACTION
786
+
787
+ let applicable_types = [
788
+ "AWS::Lambda::Permission"
789
+ ]
790
+
791
+ let lambda_permission_invoke_function_action = Resources.*[ Type in %applicable_types
792
+ Metadata.cfn_nag.rules_to_suppress not exists or
793
+ Metadata.cfn_nag.rules_to_suppress.*.id != "W24"
794
+ Metadata.guard.SuppressedRules not exists or
795
+ Metadata.guard.SuppressedRules.* != "LAMBDA_PERMISSION_INVOKE_FUNCTION_ACTION"
796
+ ]
797
+
798
+ rule LAMBDA_PERMISSION_INVOKE_FUNCTION_ACTION when %lambda_permission_invoke_function_action !empty {
799
+ let violations = %lambda_permission_invoke_function_action[
800
+ some Properties.Action != 'lambda:InvokeFunction'
801
+ ]
802
+ %violations empty
803
+ <<
804
+ Guard Rule Set: aws-prototyping
805
+ Controls: LambdaFunctionUrlAuth
806
+ Violation: Lambda permission beside InvokeFunction might not be what you want.
807
+ Fix: Remove Actions beside 'lambda:InvokeFunction'.
808
+ >>
809
+ }
810
+
811
+ #
812
+ #####################################
813
+ ## Gherkin ##
814
+ #####################################
815
+ # Rule Identifier:
816
+ # OPENSEARCH_IN_VPC_ONLY
817
+ #
818
+ # Description:
819
+ # OpenSearchService domains must be in a VPC
820
+ #
821
+ # Reports on:
822
+ # AWS::OpenSearchService::Domain
823
+ #
824
+ # Evaluates:
825
+ # AWS CloudFormation
826
+ #
827
+ # Rule Parameters:
828
+ # NA
829
+ #
830
+ # Scenarios:
831
+ # a) SKIP: when there is no OpenSearchService domain present
832
+ # b) SKIP: when metadata has rule suppression for OPENSEARCH_IN_VPC_ONLY
833
+ # c) PASS: when OpenSearchService domain has VPCOptions or Endpoint properties
834
+ # d) FAIL: when OpenSearchService domain does not have VPCOptions or Endpoint properties
835
+
836
+ #
837
+ # Select all elasticsearch domains from incoming template
838
+ #
839
+ let opensearch_in_vpc_only = Resources.*[ Type == "AWS::OpenSearchService::Domain"
840
+ Metadata.guard.SuppressedRules not exists or
841
+ Metadata.guard.SuppressedRules.* != "OPENSEARCH_IN_VPC_ONLY"
842
+ ]
843
+
844
+ rule OPENSEARCH_IN_VPC_ONLY when %opensearch_in_vpc_only !empty {
845
+ %opensearch_in_vpc_only.Properties.VPCOptions exists
846
+ <<
847
+ Guard Rule Set: aws-prototyping
848
+ Controls: OpenSearchInVPCOnly
849
+ Violation: OpenSearchService domains must be in a VPC.
850
+ Fix: Provide VPCOptions object to enable opensearch to function in a VPC.
851
+ >>
852
+ }
853
+ #
854
+ #####################################
855
+ ## Gherkin ##
856
+ #####################################
857
+ # Rule Identifier:
858
+ # OPENSEARCH_ACCESS_CONTROL_ENABLED
859
+ #
860
+ # Description:
861
+ # OpenSearchService domains are are configured with fine-grained access control enabled
862
+ #
863
+ # Reports on:
864
+ # AWS::OpenSearchService::Domain
865
+ #
866
+ # Evaluates:
867
+ # AWS CloudFormation
868
+ #
869
+ # Rule Parameters:
870
+ # NA
871
+ #
872
+ # Scenarios:
873
+ # a) SKIP: when there are no OpenSearchService Domain Resources
874
+ # b) SKIP: when metadata has rule suppression for OPENSEARCH_ACCESS_CONTROL_ENABLED
875
+ # c) FAIL: when OpenSearchService Domain Resources are missing AdvancedSecurityOptions.Enabled
876
+ # d) FAIL: when OpenSearchService Domain Resources have AdvancedSecurityOptions.Enabled set to a value other than true
877
+ # e) PASS: when OpenSearchService Domain Resources have AdvancedSecurityOptions.Enabled set to true
878
+
879
+ #
880
+ # Select all OpenSearchService domains from incoming template
881
+ #
882
+ let opensearch_access_control_enabled = Resources.*[ Type == "AWS::OpenSearchService::Domain"
883
+ Metadata.guard.SuppressedRules not exists or
884
+ Metadata.guard.SuppressedRules.* != "OPENSEARCH_ACCESS_CONTROL_ENABLED"
885
+ ]
886
+
887
+ rule OPENSEARCH_ACCESS_CONTROL_ENABLED when %opensearch_access_control_enabled !empty {
888
+ %opensearch_access_control_enabled.Properties {
889
+ AdvancedSecurityOptions exists
890
+ AdvancedSecurityOptions is_struct
891
+
892
+ AdvancedSecurityOptions {
893
+ Enabled exists
894
+ Enabled == true
895
+ <<
896
+ Guard Rule Set: aws-prototyping
897
+ Controls: OpenSearchNoUnsignedOrAnonymousAccess
898
+ Violation: OpenSearchService domains are are configured with fine-grained access control enabled
899
+ Fix: In AdvancedSecurityOptions, set the Enabled property to true
900
+ >>
901
+ }
902
+ }
903
+ }
904
+
905
+ #
906
+ #####################################
907
+ ## Gherkin ##
908
+ #####################################
909
+ # Rule Identifier:
910
+ # RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED
911
+ #
912
+ # Description:
913
+ # Checks whether storage encryption is enabled for your RDS DB instances
914
+ #
915
+ # Reports on:
916
+ # AWS::RDS::DBInstance
917
+ #
918
+ # Evaluates:
919
+ # AWS CloudFormation
920
+ #
921
+ # Rule Parameters:
922
+ # NA
923
+ #
924
+ # Scenarios:
925
+ # a) SKIP: when there are no RDS instances present
926
+ # b) PASS: when all RDS instances have AutoMinorVersionUpgrade set to true
927
+ # c) FAIL: when all RDS instances have AutoMinorVersionUpgrade set to false
928
+ # d) FAIL: when there are RDS instances with AutoMinorVersionUpgrade property is not present
929
+ # e) SKIP: when metadata includes the suppression for rule RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED
930
+
931
+ #
932
+ # Select all RDS instance resources from incoming template (payload)
933
+ #
934
+
935
+ let aws_rds_instances_minor_version_upgrade_enabled = Resources.*[ Type == 'AWS::RDS::DBInstance'
936
+ Metadata.guard.SuppressedRules not exists or
937
+ Metadata.guard.SuppressedRules.* != "RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED"
938
+ ]
939
+
940
+
941
+ rule RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED when %aws_rds_instances_minor_version_upgrade_enabled !empty {
942
+ %aws_rds_instances_minor_version_upgrade_enabled.Properties.AutoMinorVersionUpgrade EXISTS
943
+ %aws_rds_instances_minor_version_upgrade_enabled.Properties.AutoMinorVersionUpgrade == true
944
+ <<
945
+ Guard Rule Set: aws-prototyping
946
+ Controls: RDSAutomaticMinorVersionUpgradeEnabled
947
+ Violation: All RDS instances must have automatic minor version upgrade enabled.
948
+ Fix: Set the AutoMinorVersionUpgrade parameter to true.
949
+ >>
950
+ }
951
+
952
+ #
953
+ #####################################
954
+ ## Gherkin ##
955
+ #####################################
956
+ # Rule Identifier:
957
+ # RDS_INSTANCE_PUBLIC_ACCESS_CHECK
958
+ #
959
+ # Description:
960
+ # Checks if an RDS instances has Publicly Accessible not set.
961
+ #
962
+ # Reports on:
963
+ # AWS::RDS::DBInstance
964
+ #
965
+ # Evaluates:
966
+ # AWS CloudFormation
967
+ #
968
+ # Rule Parameters:
969
+ # NA
970
+ #
971
+ # Scenarios:
972
+ # a) SKIP: when there are no RDS instances present
973
+ # b) PASS: when all RDS instances have PubliclyAccessible set to true
974
+ # c) FAIL: when all RDS instances have PubliclyAccessible set to false
975
+ # d) FAIL: when there are RDS instances with PubliclyAccessible property is not present
976
+ # e) SKIP: when metadata includes the suppression for rule RDS_INSTANCE_PUBLIC_ACCESS_CHECK
977
+
978
+ #
979
+ # Select all RDS instance resources from incoming template (payload)
980
+ #
981
+ let aws_rds_instances_not_public = Resources.*[ Type == 'AWS::RDS::DBInstance'
982
+ Metadata.cfn_nag.rules_to_suppress not exists or
983
+ Metadata.cfn_nag.rules_to_suppress.*.id != "F22"
984
+ Metadata.guard.SuppressedRules not exists or
985
+ Metadata.guard.SuppressedRules.* != "RDS_INSTANCE_PUBLIC_ACCESS_CHECK"
986
+ ]
987
+
988
+ rule RDS_INSTANCE_PUBLIC_ACCESS_CHECK when %aws_rds_instances_not_public !empty {
989
+ # ALL RDS instances must have PubliclyAccessible set to false
990
+ %aws_rds_instances_not_public.Properties.PubliclyAccessible == false
991
+ <<
992
+ Guard Rule Set: aws-prototyping
993
+ Controls: RDSInstancePublicAccess
994
+ Violation: All RDS instances must not be publicly accessible.
995
+ Fix: The default depends on the VPC configuration, so it is recommended to eplicitly set PubliclyAccessible to false.
996
+ >>
997
+ }
998
+
999
+ #
1000
+ #####################################
1001
+ ## Gherkin ##
1002
+ #####################################
1003
+ # Rule Identifier:
1004
+ # REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK
1005
+ #
1006
+ # Description:
1007
+ # Redshift cluster should not be publicly accessible on the internet.
1008
+ #
1009
+ # Reports on:
1010
+ # AWS::EKS::Cluster
1011
+ #
1012
+ # Evaluates:
1013
+ # AWS CloudFormation
1014
+ #
1015
+ # Rule Parameters:
1016
+ # NA
1017
+ #
1018
+ # Scenarios:
1019
+ # a) SKIP: when there is no Redshift cluster present
1020
+ # b) PASS: when Redshift Cluster resources do not have the publiclyAccessible property set (default false)
1021
+ # c) PASS: when Redshift Cluster resources have the PubliclyAccessible property set to false
1022
+ # d) FAIL: when any Redshift Cluster resources have the PubliclyAccessible property set to true
1023
+ # e) SKIP: when metada includes the suppression for rule REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK
1024
+
1025
+ #
1026
+ # Select all Redshift cluster resources from incoming template
1027
+ #
1028
+
1029
+ let aws_redshift_clusters_resources_public_access_check = Resources.*[ Type == 'AWS::Redshift::Cluster'
1030
+ Metadata.guard.SuppressedRules not exists or
1031
+ Metadata.guard.SuppressedRules.* != "REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK"
1032
+ ]
1033
+
1034
+
1035
+ rule REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK when %aws_redshift_clusters_resources_public_access_check !empty {
1036
+ %aws_redshift_clusters_resources_public_access_check.Properties.PubliclyAccessible not exists or
1037
+ %aws_redshift_clusters_resources_public_access_check.Properties.PubliclyAccessible == false
1038
+
1039
+ <<
1040
+ Guard Rule Set: aws-prototyping
1041
+ Controls: RedshiftClusterPublicAccess
1042
+ Violation: Redshift cluster should not be available to public.
1043
+ Fix: Set the Redshift property PubliclyAccessible parameter to false.
1044
+ >>
1045
+ }
1046
+
1047
+ ####################################
1048
+ ## Gherkin ##
1049
+ #####################################
1050
+ # Rule Identifier:
1051
+ # REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK
1052
+ #
1053
+ # Description:
1054
+ # Checks whether Amazon Redshift clusters have the specified maintenance settings (AllowVersionUpgrade, PreferredMaintenanceWindow, AutomatedSnapshotRetentionPeriod)
1055
+ #
1056
+ # Reports on:
1057
+ # AWS::Redshift::Cluster
1058
+ #
1059
+ # Evaluates:
1060
+ # AWS CloudFormation
1061
+ #
1062
+ # Rule Parameters:
1063
+ # NA
1064
+ #
1065
+ # Scenarios:
1066
+ # a) SKIP: when there are no Redshift Cluster resource present
1067
+ # b) PASS: when Redshift Cluster resources have properties PreferredMaintenanceWindow set, AllowVersionUpgrade either not set (default true) or set to true, and AutomatedSnapshotRetentionPeriod either not set (default 1 day) or set to greated than 0.
1068
+ # c) FAIL: when any Redshift Cluster resources do not have PreferredMaintenanceWindow property set
1069
+ # d) FAIL: when any Redshift Cluster resources have AllowVersionUpgrade property set to false
1070
+ # e) FAIL: when any Redshift Cluster resources have AutomatedSnapshotRetentionPeriod property set to 0
1071
+ # f) SKIP: when metadata includes the suppression for rule REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK
1072
+
1073
+ #
1074
+ # Select all Redshift Cluster resources from incoming template (payload)
1075
+ #
1076
+ let redhshift_clusters_maintenancesettings_check = Resources.*[ Type == 'AWS::Redshift::Cluster'
1077
+ Metadata.guard.SuppressedRules not exists or
1078
+ Metadata.guard.SuppressedRules.* != "REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK"
1079
+ ]
1080
+
1081
+ rule REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK when %redhshift_clusters_maintenancesettings_check !empty {
1082
+ %redhshift_clusters_maintenancesettings_check.Properties.PreferredMaintenanceWindow exists
1083
+
1084
+ %redhshift_clusters_maintenancesettings_check.Properties.AllowVersionUpgrade not exists or
1085
+ %redhshift_clusters_maintenancesettings_check.Properties.AllowVersionUpgrade == true
1086
+
1087
+
1088
+ %redhshift_clusters_maintenancesettings_check.Properties.AutomatedSnapshotRetentionPeriod not exists or
1089
+ %redhshift_clusters_maintenancesettings_check.Properties.AutomatedSnapshotRetentionPeriod > 0
1090
+
1091
+ <<
1092
+ Guard Rule Set: aws-prototyping
1093
+ Controls: RedshiftClusterVersionUpgrade
1094
+ Violation: Amazon Redshift maintenance settings must be configured
1095
+ Fix: set the PreferredMaintenanceWindow property, remove the AllowVersionUpgrade property (default true) or set it to true, and remove the AutomatedSnapshotRetentionPeriod property (default 1 day) or set it to greated than 0.
1096
+ >>
1097
+ }
1098
+ #
1099
+ #####################################
1100
+ ## Gherkin ##
1101
+ #####################################
1102
+ # Rule Identifier:
1103
+ # S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED
1104
+ #
1105
+ # Description:
1106
+ # Checks if Amazon Simple Storage Service (Amazon S3) buckets are publicly accessible.
1107
+ #
1108
+ # Reports on:
1109
+ # AWS::S3::Bucket
1110
+ #
1111
+ # Evaluates:
1112
+ # AWS CloudFormation
1113
+ #
1114
+ # Rule Parameters:
1115
+ # NA
1116
+ #
1117
+ # Scenarios:
1118
+ # a) SKIP: when there are no S3 resource present
1119
+ # b) PASS: when all S3 resources Public Access Block Configuration element is present and properties are set to true
1120
+ # c) FAIL: when all S3 resources do not have the Public Access Block Configuration element present or all properties set to true
1121
+ # d) SKIP: when metada has rule suppression for S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED
1122
+
1123
+ #
1124
+ # Select all S3 resources from incoming template (payload)
1125
+ #
1126
+ let s3_buckets_level_public_access_prohibited = Resources.*[ Type == 'AWS::S3::Bucket'
1127
+ Metadata.guard.SuppressedRules not exists or
1128
+ Metadata.guard.SuppressedRules.* != "S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED"
1129
+ ]
1130
+
1131
+ rule S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED when %s3_buckets_level_public_access_prohibited !empty {
1132
+ %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration exists
1133
+ %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicAcls == true
1134
+ %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicPolicy == true
1135
+ %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.IgnorePublicAcls == true
1136
+ %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == true
1137
+ <<
1138
+ Guard Rule Set: aws-prototyping
1139
+ Controls: S3BucketLevelPublicAccessProhibited
1140
+ Violation: S3 Bucket Public Access controls need to be restricted.
1141
+ Fix: Set S3 Bucket PublicAccessBlockConfiguration properties for BlockPublicAcls, BlockPublicPolicy, IgnorePublicAcls, RestrictPublicBuckets parameters to true.
1142
+ >>
1143
+ }
1144
+ #
1145
+ #####################################
1146
+ ## Gherkin ##
1147
+ #####################################
1148
+ # Rule Identifier:
1149
+ # S3_BUCKET_PUBLIC_READ_PROHIBITED
1150
+ #
1151
+ # Description:
1152
+ # Checks if your Amazon S3 buckets do not allow public read access. The rule checks the Block Public
1153
+ # Access settings, the bucket policy, and the bucket access control list (ACL).
1154
+ #
1155
+ # Reports on:
1156
+ # AWS::S3::Bucket
1157
+ #
1158
+ # Evaluates:
1159
+ # AWS CloudFormation
1160
+ #
1161
+ # Rule Parameters:
1162
+ # NA
1163
+ #
1164
+ # Scenarios:
1165
+ # a) SKIP: when there are no S3 resource present
1166
+ # b) PASS: when all S3 resources Public Access Block Configuration element is present and properties are set to true
1167
+ # c) FAIL: when all S3 resources do not have the Public Access Block Configuration element present or all properties set to true
1168
+ # d) SKIP: when metadata includes the suppression for rule S3_BUCKET_PUBLIC_READ_PROHIBITED
1169
+
1170
+ #
1171
+ # Select all S3 resources from incoming template (payload)
1172
+ #
1173
+ let s3_bucket_public_read_prohibited = Resources.*[ Type == 'AWS::S3::Bucket'
1174
+ Metadata.guard.SuppressedRules not exists or
1175
+ Metadata.guard.SuppressedRules.* != "S3_BUCKET_PUBLIC_READ_PROHIBITED"
1176
+ ]
1177
+
1178
+ rule S3_BUCKET_PUBLIC_READ_PROHIBITED when %s3_bucket_public_read_prohibited !empty {
1179
+ %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration exists
1180
+ %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicAcls == true
1181
+ %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicPolicy == true
1182
+ %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.IgnorePublicAcls == true
1183
+ %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == true
1184
+ <<
1185
+ Guard Rule Set: aws-prototyping
1186
+ Controls: S3BucketPublicReadProhibited
1187
+ Violation: S3 Bucket Public Write Access controls need to be restricted.
1188
+ Fix: Set S3 Bucket PublicAccessBlockConfiguration properties for BlockPublicAcls, BlockPublicPolicy, IgnorePublicAcls, RestrictPublicBuckets parameters to true.
1189
+ >>
1190
+ }
1191
+ #
1192
+ #####################################
1193
+ ## Gherkin ##
1194
+ #####################################
1195
+ # Rule Identifier:
1196
+ # S3_BUCKET_PUBLIC_WRITE_PROHIBITED
1197
+ #
1198
+ # Description:
1199
+ # Checks if your Amazon S3 buckets do not allow public write access. The rule checks the Block Public
1200
+ # Access settings, the bucket policy, and the bucket access control list (ACL).
1201
+ #
1202
+ # Reports on:
1203
+ # AWS::S3::Bucket
1204
+ #
1205
+ # Evaluates:
1206
+ # AWS CloudFormation
1207
+ #
1208
+ # Rule Parameters:
1209
+ # NA
1210
+ #
1211
+ # Scenarios:
1212
+ # a) SKIP: when there are no S3 resource present
1213
+ # b) PASS: when all S3 resources Public Access Block Configuration element is present and properties are set to true
1214
+ # c) FAIL: when all S3 resources do not have the Public Access Block Configuration element present or all properties set to true
1215
+ # d) SKIP: when metadata includes the suppression for rule S3_BUCKET_PUBLIC_WRITE_PROHIBITED
1216
+
1217
+ #
1218
+ # Select all S3 resources from incoming template (payload)
1219
+ #
1220
+ let s3_buckets_public_write_prohibited = Resources.*[ Type == 'AWS::S3::Bucket'
1221
+ Metadata.guard.SuppressedRules not exists or
1222
+ Metadata.guard.SuppressedRules.* != "S3_BUCKET_PUBLIC_WRITE_PROHIBITED"
1223
+ ]
1224
+
1225
+ rule S3_BUCKET_PUBLIC_WRITE_PROHIBITED when %s3_buckets_public_write_prohibited !empty {
1226
+ %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration exists
1227
+ %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicAcls == true
1228
+ %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicPolicy == true
1229
+ %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.IgnorePublicAcls == true
1230
+ %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == true
1231
+ <<
1232
+ Guard Rule Set: aws-prototyping
1233
+ Controls: S3BucketPublicWriteProhibited
1234
+ Violation: S3 Bucket Public Write Access controls need to be restricted.
1235
+ Fix: Set S3 Bucket PublicAccessBlockConfiguration properties for BlockPublicAcls, BlockPublicPolicy, IgnorePublicAcls, RestrictPublicBuckets parameters to true.
1236
+ >>
1237
+ }
1238
+ #
1239
+ #####################################
1240
+ ## Gherkin ##
1241
+ #####################################
1242
+ # Rule Identifier:
1243
+ # SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED
1244
+ #
1245
+ # Description:
1246
+ # Checks if Amazon Virtual Private Cloud (Amazon VPC) subnets are assigned a public IP address.
1247
+ #
1248
+ # Reports on:
1249
+ # AWS::EC2::Subnet
1250
+ #
1251
+ # Evaluates:
1252
+ # AWS CloudFormation
1253
+ #
1254
+ # Rule Parameters:
1255
+ # NA
1256
+ #
1257
+ # Scenarios:
1258
+ # a) SKIP: when there are no EC2 Subnet resource present
1259
+ # b) PASS: when all EC2 Subnet resources have the MapPublicIpOnLaunch property set to false or it is missing (default false)
1260
+ # c) FAIL: when any EC2 Subnet resources have the MapPublicIpOnLaunch property set to true
1261
+ # d) SKIP: hen metadata includes the suppression for rule SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED
1262
+
1263
+ #
1264
+ # Select all EC2 Subnet resources from incoming template (payload)
1265
+ #
1266
+ let ec2_subnets_auto_assign_public_ip_disabled = Resources.*[ Type == 'AWS::EC2::Subnet'
1267
+ Metadata.cfn_nag.rules_to_suppress not exists or
1268
+ Metadata.cfn_nag.rules_to_suppress.*.id != "W33"
1269
+ Metadata.guard.SuppressedRules not exists or
1270
+ Metadata.guard.SuppressedRules.* != "SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED"
1271
+ ]
1272
+
1273
+ rule SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED when %ec2_subnets_auto_assign_public_ip_disabled !empty {
1274
+ %ec2_subnets_auto_assign_public_ip_disabled.Properties.MapPublicIpOnLaunch !exists
1275
+ OR %ec2_subnets_auto_assign_public_ip_disabled.Properties.MapPublicIpOnLaunch == false
1276
+ <<
1277
+ Guard Rule Set: aws-prototyping
1278
+ Controls: VPCSubnetAutoAssignPublicIpDisabled
1279
+ Violation: VPCs should not have subnets that are assigned a public IP address.
1280
+ Fix: remove the MapPublicIpOnLaucnh property or set it to false
1281
+ >>
1282
+ }