Skip to content

Commit db8a9cc

Browse files
authored
Merge pull request #470 from NHSDigital/feature/eja-eli-384-adding-WAF-for-API-gateway
eli-384 misc. permissions and changes for deployment
2 parents 1c0113a + ae21090 commit db8a9cc

File tree

3 files changed

+86
-20
lines changed

3 files changed

+86
-20
lines changed

infrastructure/stacks/api-layer/waf.tf

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ resource "aws_wafv2_web_acl_association" "api_gateway" {
170170
# CloudWatch Log Group for WAF logs
171171
resource "aws_cloudwatch_log_group" "waf" {
172172
count = local.waf_enabled ? 1 : 0
173-
name = "/aws/wafv2/${local.workspace}-eligibility-signposting-api"
173+
name = "aws-waf-logs-${local.workspace}-eligibility-signposting-api"
174174
retention_in_days = 365
175175
kms_key_id = aws_kms_key.waf_logs[0].arn
176176

@@ -188,6 +188,46 @@ resource "aws_cloudwatch_log_group" "waf" {
188188
]
189189
}
190190

191+
# CloudWatch Logs resource policy to allow WAF to write logs
192+
resource "aws_cloudwatch_log_resource_policy" "waf" {
193+
count = local.waf_enabled ? 1 : 0
194+
policy_name = "${local.workspace}-waf-logging-policy"
195+
policy_document = jsonencode({
196+
Version = "2012-10-17"
197+
Statement = [
198+
{
199+
Sid = "AWSLogDeliveryWrite"
200+
Effect = "Allow"
201+
Principal = {
202+
Service = "delivery.logs.amazonaws.com"
203+
}
204+
Action = [
205+
"logs:CreateLogStream",
206+
"logs:PutLogEvents"
207+
]
208+
Resource = "${aws_cloudwatch_log_group.waf[0].arn}:*"
209+
Condition = {
210+
StringEquals = {
211+
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
212+
}
213+
ArnLike = {
214+
"aws:SourceArn" = "arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:*"
215+
}
216+
}
217+
},
218+
{
219+
Sid = "AWSLogDeliveryAclCheck"
220+
Effect = "Allow"
221+
Principal = {
222+
Service = "delivery.logs.amazonaws.com"
223+
}
224+
Action = "logs:GetLogDelivery"
225+
Resource = "*"
226+
}
227+
]
228+
})
229+
}
230+
191231
# KMS Key for WAF logs encryption
192232
resource "aws_kms_key" "waf_logs" {
193233
count = local.waf_enabled ? 1 : 0
@@ -272,7 +312,11 @@ data "aws_iam_policy_document" "waf_logs_kms" {
272312
condition {
273313
test = "ArnLike"
274314
variable = "kms:EncryptionContext:aws:logs:arn"
275-
values = ["arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/wafv2/*"]
315+
values = [
316+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/wafv2/*",
317+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:aws-wafv2-logs-*",
318+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:aws-waf-logs-*"
319+
]
276320
}
277321
}
278322
}

infrastructure/stacks/iams-developer-roles/github_actions_policies.tf

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,16 @@ resource "aws_iam_policy" "api_infrastructure" {
240240
"acm:ListCertificates",
241241
# WAF v2 list operations
242242
"wafv2:ListWebACLs",
243-
"wafv2:ListTagsForResource"
243+
"wafv2:ListTagsForResource",
244+
# CloudWatch Logs resource policies (require wildcard)
245+
"logs:PutResourcePolicy",
246+
"logs:DeleteResourcePolicy",
247+
"logs:DescribeResourcePolicies",
248+
# CloudWatch Logs delivery for WAF
249+
"logs:CreateLogDelivery",
250+
"logs:DeleteLogDelivery",
251+
# IAM service-linked role for WAF logging
252+
"iam:CreateServiceLinkedRole"
244253

245254
],
246255
Resource = "*"
@@ -251,6 +260,7 @@ resource "aws_iam_policy" "api_infrastructure" {
251260
Action = [
252261
# CloudWatch Logs creation and management
253262
"logs:CreateLogGroup",
263+
"logs:DeleteLogGroup",
254264
"logs:CreateLogStream",
255265
"logs:PutLogEvents",
256266
# CloudWatch Logs subscription filters for CSOC forwarding
@@ -266,7 +276,11 @@ resource "aws_iam_policy" "api_infrastructure" {
266276
# API Gateway logs
267277
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/apigateway/*",
268278
# Kinesis Firehose logs
269-
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/kinesisfirehose/*"
279+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/kinesisfirehose/*",
280+
# WAF v2 logs (both naming conventions)
281+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/wafv2/*",
282+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:aws-wafv2-logs-*",
283+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:aws-waf-logs-*"
270284
]
271285
},
272286
{
@@ -376,6 +390,7 @@ resource "aws_iam_policy" "api_infrastructure" {
376390
"wafv2:CreateWebACL",
377391
"wafv2:DeleteWebACL",
378392
"wafv2:GetWebACL",
393+
"wafv2:GetWebACLForResource",
379394
"wafv2:UpdateWebACL",
380395
"wafv2:TagResource",
381396
"wafv2:UntagResource",
@@ -405,6 +420,7 @@ resource "aws_iam_policy" "api_infrastructure" {
405420
"arn:aws:acm:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:certificate/*",
406421
"arn:aws:events:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:rule/cloudwatch-alarm-state-change-to-splunk*",
407422
"arn:aws:wafv2:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:regional/webacl/*",
423+
"arn:aws:wafv2:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:regional/managedruleset/*",
408424
]
409425
},
410426
]
@@ -615,6 +631,7 @@ resource "aws_iam_policy" "cloudwatch_management" {
615631
Action = [
616632
"logs:ListTagsForResource",
617633
"logs:DescribeLogGroups",
634+
"logs:DeleteLogGroup",
618635
"logs:PutRetentionPolicy",
619636
"logs:TagResource",
620637
"logs:UntagResource",
@@ -643,6 +660,8 @@ resource "aws_iam_policy" "cloudwatch_management" {
643660
Resource = [
644661
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/kinesisfirehose/*",
645662
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/wafv2/*",
663+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:aws-wafv2-logs-*",
664+
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:aws-waf-logs-*",
646665
"arn:aws:cloudwatch:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:alarm:*",
647666
"arn:aws:sns:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:cloudwatch-security-alarms*",
648667
"arn:aws:logs:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:log-group:/aws/apigateway/default-eligibility-signposting-api*",

infrastructure/stacks/iams-developer-roles/iams_permissions_boundary.tf

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ data "aws_iam_policy_document" "permissions_boundary" {
116116
"iam:UntagPolicy",
117117
"iam:PassRole",
118118
"iam:TagPolicy",
119+
"iam:CreateServiceLinkedRole",
119120

120121
# KMS - encryption key management
121122
"kms:CreateKey",
@@ -170,21 +171,7 @@ data "aws_iam_policy_document" "permissions_boundary" {
170171
"lambda:ListProvisionedConcurrencyConfigs",
171172

172173
# CloudWatch Logs - log management
173-
"logs:CreateLogGroup",
174-
"logs:CreateLogStream",
175-
"logs:PutLogEvents",
176-
"logs:DescribeLogGroups",
177-
"logs:DescribeLogStreams",
178-
"logs:Describe*",
179-
"logs:ListTagsForResource",
180-
"logs:TagResource",
181-
"logs:UntagResource",
182-
"logs:PutRetentionPolicy",
183-
"logs:AssociateKmsKey",
184-
"logs:PutMetricFilter",
185-
"logs:PutSubscriptionFilter",
186-
"logs:DeleteSubscriptionFilter",
187-
"logs:DescribeSubscriptionFilters",
174+
"logs:*",
188175

189176
# S3 - bucket and object management
190177
"s3:GetLifecycleConfiguration",
@@ -241,7 +228,23 @@ data "aws_iam_policy_document" "permissions_boundary" {
241228
"ssm:GetParameters",
242229
"ssm:ListTagsForResource",
243230
"ssm:PutParameter",
244-
"ssm:AddTagsToResource"
231+
"ssm:AddTagsToResource",
232+
233+
# WAFv2 - web application firewall management
234+
"wafv2:CreateWebACL",
235+
"wafv2:DeleteWebACL",
236+
"wafv2:GetWebACL",
237+
"wafv2:GetWebACLForResource",
238+
"wafv2:UpdateWebACL",
239+
"wafv2:ListWebACLs",
240+
"wafv2:TagResource",
241+
"wafv2:UntagResource",
242+
"wafv2:ListTagsForResource",
243+
"wafv2:AssociateWebACL",
244+
"wafv2:DisassociateWebACL",
245+
"wafv2:PutLoggingConfiguration",
246+
"wafv2:GetLoggingConfiguration",
247+
"wafv2:DeleteLoggingConfiguration"
245248
]
246249

247250
resources = ["*"]

0 commit comments

Comments
 (0)