diff --git a/infrastructure/modules/lambda/outputs.tf b/infrastructure/modules/lambda/outputs.tf index 076115ed..5b3e686a 100644 --- a/infrastructure/modules/lambda/outputs.tf +++ b/infrastructure/modules/lambda/outputs.tf @@ -16,3 +16,7 @@ output "aws_lambda_invoke_arn" { output "lambda_cmk_arn" { value = aws_kms_key.lambda_cmk.arn } + +output "lambda_signing_profile_name" { + value = aws_signer_signing_profile.lambda_signing.name +} diff --git a/infrastructure/modules/lambda/signing.tf b/infrastructure/modules/lambda/signing.tf new file mode 100644 index 00000000..0392a431 --- /dev/null +++ b/infrastructure/modules/lambda/signing.tf @@ -0,0 +1,25 @@ +resource "aws_signer_signing_profile" "lambda_signing" { + name = "${terraform.workspace == "default" ? "" : "${terraform.workspace}"}EligibilityApiLambdaSigningProfile" + #aws signer is strict with names, does not like hyphens or underscores + + platform_id = "AWSLambda-SHA384-ECDSA" + + signature_validity_period { + value = 365 + type = "DAYS" + } +} + +resource "aws_lambda_code_signing_config" "signing_config" { + allowed_publishers { + signing_profile_version_arns = [ + aws_signer_signing_profile.lambda_signing.version_arn + ] + } + + policies { + untrusted_artifact_on_deployment = "Enforce" + } + + description = "Only allow Lambda bundles signed by our trusted signer profile" +} diff --git a/infrastructure/stacks/api-layer/lambda.tf b/infrastructure/stacks/api-layer/lambda.tf index dfb061ba..b3eba156 100644 --- a/infrastructure/stacks/api-layer/lambda.tf +++ b/infrastructure/stacks/api-layer/lambda.tf @@ -35,6 +35,12 @@ module "eligibility_signposting_lambda_function" { api_domain_name = local.api_domain_name } + +# Needed by github workflows to sign the lambda artifacts +output "signing_profile_name" { + value = module.eligibility_signposting_lambda_function.lambda_signing_profile_name +} + # ----------------------------------------------------------------------------- # Secret rotation lambdas # ----------------------------------------------------------------------------- diff --git a/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf b/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf index 72c46e35..4740ac9e 100644 --- a/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf +++ b/infrastructure/stacks/iams-developer-roles/github_actions_policies.tf @@ -809,6 +809,76 @@ resource "aws_iam_policy" "cloudwatch_management" { tags = merge(local.tags, { Name = "cloudwatch-management" }) } +resource "aws_iam_policy" "code_signing_management" { + #checkov:skip=CKV_AWS_290: Actions require wildcard resource for Lambda code signing configs and Signer jobs + #checkov:skip=CKV_AWS_235: Actions require wildcard resource for Lambda code signing configs and Signer jobs + #checkov:skip=CKV_AWS_355: Actions require wildcard resource for Lambda code signing configs and Signer jobs + name = "code-signing-management" + description = "Allow GitHub Actions to manage Lambda code signing and start Signer jobs" + path = "/service-policies/" + + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Sid = "LambdaCodeSigningConfigManagement", + Effect = "Allow", + Action = [ + "lambda:CreateCodeSigningConfig", + "lambda:UpdateCodeSigningConfig", + "lambda:DeleteCodeSigningConfig", + "lambda:GetCodeSigningConfig", + "lambda:ListCodeSigningConfigs", + "lambda:GetFunctionCodeSigningConfig", + "lambda:ListTags" + ], + Resource = "*" + }, + { + Sid = "LambdaFunctionSigningManagement", + Effect = "Allow", + Action = [ + "lambda:DeleteFunctionCodeSigningConfig", + "lambda:PutFunctionCodeSigningConfig" + ], + Resource = "arn:aws:lambda:*:${data.aws_caller_identity.current.account_id}:function:eligibility_signposting_api" + }, + { + Sid = "SignerProfileManagement" + Effect = "Allow" + Action = [ + "signer:GetSigningProfile", + "signer:TagResource", + "signer:UntagResource", + "signer:ListTagsForResource" + ] + Resource = local.lambda_signing_profile_arn + }, + { + Sid = "SignerProfileCreateAndList" + Effect = "Allow" + Action = [ + "signer:PutSigningProfile", + "signer:ListSigningProfiles" + ] + Resource = "*" + }, + { + Sid = "SignerJobUsage", + Effect = "Allow", + Action = [ + "signer:StartSigningJob", + "signer:DescribeSigningJob", + "signer:ListSigningJobs" + ], + Resource = "*" + }, + ] + }) + + tags = merge(local.tags, { Name = "code-signing-management" }) +} + # Attach the policies to the role resource "aws_iam_role_policy_attachment" "terraform_state" { role = aws_iam_role.github_actions.name @@ -859,3 +929,8 @@ resource "aws_iam_role_policy_attachment" "kinesis_management_attach" { role = aws_iam_role.github_actions.name policy_arn = aws_iam_policy.kinesis_management.arn } + +resource "aws_iam_role_policy_attachment" "code_signing_management" { + role = aws_iam_role.github_actions.name + policy_arn = aws_iam_policy.code_signing_management.arn +} diff --git a/infrastructure/stacks/iams-developer-roles/locals.tf b/infrastructure/stacks/iams-developer-roles/locals.tf index 1696637c..5a43a030 100644 --- a/infrastructure/stacks/iams-developer-roles/locals.tf +++ b/infrastructure/stacks/iams-developer-roles/locals.tf @@ -1,3 +1,5 @@ locals { stack_name = "iams-developer-roles" + lambda_signing_profile_name = "${terraform.workspace == "default" ? "" : "${terraform.workspace}"}EligibilityApiLambdaSigningProfile" + lambda_signing_profile_arn = "arn:aws:signer:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:/signing-profiles/${local.lambda_signing_profile_name}" }