-
Notifications
You must be signed in to change notification settings - Fork 1
Add AWS Lambda code signing capability with secure S3 configuration #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
15588b9
139a209
2fc759b
e346d2a
9a74aa7
1a1ce07
74d26f8
ebe54a8
328d289
fb4275e
40f15b8
4333916
8462365
be17cd0
f3ae2ba
a570657
15fe914
427650d
b7c05af
33008ec
bec6699
f233095
bab1928
a61fed9
83b68a3
4a695e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,65 @@ | ||||||||||||||||||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key | ||||||||||||||||||
| resource "aws_kms_key" "encrypt_storage" { | ||||||||||||||||||
| enable_key_rotation = true | ||||||||||||||||||
| description = "Key to encrypt S3 bucket in ${var.name}." | ||||||||||||||||||
| deletion_window_in_days = 7 | ||||||||||||||||||
| } | ||||||||||||||||||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias | ||||||||||||||||||
| resource "aws_kms_alias" "encrypt_storage" { | ||||||||||||||||||
| name = "alias/${var.name}-encrypt-storage" | ||||||||||||||||||
| target_key_id = aws_kms_key.encrypt_storage.key_id | ||||||||||||||||||
| } | ||||||||||||||||||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document | ||||||||||||||||||
| data "aws_iam_policy_document" "encrypt_storage_policy" { | ||||||||||||||||||
| statement { | ||||||||||||||||||
| sid = "Enable IAM User Permissions" | ||||||||||||||||||
| effect = "Allow" | ||||||||||||||||||
| principals { | ||||||||||||||||||
| type = "AWS" | ||||||||||||||||||
| identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] | ||||||||||||||||||
| } | ||||||||||||||||||
| actions = [ | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Description: The KMS key policy includes a long list of actions, which could be simplified for better readability and maintainability. Consider grouping similar actions or using wildcards where appropriate to reduce the length of the action list. Severity: Low There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fix simplifies the long list of KMS actions in the first statement by using a wildcard "kms:*" instead of listing all individual actions. This improves readability and maintainability of the policy document while still granting full KMS permissions to the root user. The second statement for S3 permissions remains unchanged as it requires specific actions.
Suggested change
|
||||||||||||||||||
| "kms:Encrypt", | ||||||||||||||||||
| "kms:Decrypt", | ||||||||||||||||||
| "kms:ReEncrypt*", | ||||||||||||||||||
| "kms:GenerateDataKey*", | ||||||||||||||||||
| "kms:DescribeKey", | ||||||||||||||||||
| "kms:Create*", | ||||||||||||||||||
| "kms:Enable*", | ||||||||||||||||||
| "kms:List*", | ||||||||||||||||||
| "kms:Put*", | ||||||||||||||||||
| "kms:Update*", | ||||||||||||||||||
| "kms:Revoke*", | ||||||||||||||||||
| "kms:Disable*", | ||||||||||||||||||
| "kms:Get*", | ||||||||||||||||||
| "kms:Delete*", | ||||||||||||||||||
| "kms:ScheduleKeyDeletion", | ||||||||||||||||||
| "kms:CancelKeyDeletion", | ||||||||||||||||||
| "kms:TagResource", | ||||||||||||||||||
| "kms:UntagResource" | ||||||||||||||||||
| ] | ||||||||||||||||||
| resources = [aws_kms_key.encrypt_storage.arn] | ||||||||||||||||||
| } | ||||||||||||||||||
| statement { | ||||||||||||||||||
| sid = "Allow S3 to use the key" | ||||||||||||||||||
| effect = "Allow" | ||||||||||||||||||
| principals { | ||||||||||||||||||
| type = "Service" | ||||||||||||||||||
| identifiers = ["s3.amazonaws.com"] | ||||||||||||||||||
| } | ||||||||||||||||||
| actions = [ | ||||||||||||||||||
| "kms:Encrypt", | ||||||||||||||||||
| "kms:Decrypt", | ||||||||||||||||||
| "kms:ReEncrypt*", | ||||||||||||||||||
| "kms:GenerateDataKey*", | ||||||||||||||||||
| "kms:DescribeKey", | ||||||||||||||||||
| "kms:CreateGrant" | ||||||||||||||||||
| ] | ||||||||||||||||||
| resources = [aws_kms_key.encrypt_storage.arn] | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy | ||||||||||||||||||
| resource "aws_kms_key_policy" "encrypt_storage" { | ||||||||||||||||||
| key_id = aws_kms_key.encrypt_storage.id | ||||||||||||||||||
| policy = data.aws_iam_policy_document.encrypt_storage_policy.json | ||||||||||||||||||
| } | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,46 @@ | ||
| # Generate a random string to use as a suffix | ||
| #https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string | ||
| resource "random_string" "suffix" { | ||
| length = 8 | ||
| special = false | ||
| upper = false | ||
| } | ||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/signer_signing_profile | ||
| resource "aws_signer_signing_profile" "lambda_signing_profile" { | ||
| platform_id = "AWSLambda-SHA384-ECDSA" | ||
| name = "${replace(var.name, "-", "_")}_lambda_signing_profile" | ||
| name = "${replace(var.name, "-", "_")}_lambda_signing_profile_${random_string.suffix.result}" | ||
| signature_validity_period { | ||
| value = 135 | ||
| type = "MONTHS" | ||
| } | ||
| } | ||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_code_signing_config | ||
| resource "aws_lambda_code_signing_config" "configuration" { | ||
| allowed_publishers { | ||
| signing_profile_version_arns = [aws_signer_signing_profile.lambda_signing_profile.arn] | ||
| signing_profile_version_arns = [aws_signer_signing_profile.lambda_signing_profile.version_arn] | ||
| } | ||
|
|
||
| policies { | ||
| untrusted_artifact_on_deployment = "Enforce" | ||
| } | ||
| description = "Code signing configuration for ${var.name} Lambda function." | ||
| } | ||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/signer_signing_job | ||
| resource "aws_signer_signing_job" "build_signing_job" { | ||
| profile_name = aws_signer_signing_profile.lambda_signing_profile.name | ||
|
|
||
| source { | ||
| s3 { | ||
| bucket = aws_s3_bucket.lambda_source.bucket | ||
| key = aws_s3_object.lambda_zip.key | ||
| version = aws_s3_object.lambda_zip.version_id | ||
| } | ||
| } | ||
|
|
||
| destination { | ||
| s3 { | ||
| bucket = aws_s3_bucket.lambda_source.bucket | ||
| prefix = "signed/" | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket | ||
| # Create S3 bucket for Lambda source code | ||
| resource "aws_s3_bucket" "lambda_source" { | ||
| bucket = "${var.name}-lambda-source-${data.aws_caller_identity.current.account_id}" | ||
| force_destroy = true | ||
| #checkov:skip=CKV_AWS_18: AWS Access logging not enabled on S3 buckets | ||
| #checkov:skip=CKV_AWS_144: Region replication not enabled on S3 bucket | ||
| #checkov:skip=CKV2_AWS_62: Ensure S3 buckets should have event notifications enabled | ||
| # These security controls are suppressed as this bucket is only used temporarily for Lambda code signing | ||
| # and is not intended for long-term storage or public access. The bucket has other security measures | ||
| # like encryption and public access blocking enabled. | ||
| } | ||
|
Comment on lines
+3
to
+12
Check warningCode scanning / checkov Ensure S3 buckets should have event notifications enabled Warning
Ensure S3 buckets should have event notifications enabled
Comment on lines
+3
to
+12
Check warningCode scanning / checkov Ensure the S3 bucket has access logging enabled Warning
Ensure the S3 bucket has access logging enabled
Comment on lines
+3
to
+12
Check warningCode scanning / checkov Ensure that S3 bucket has cross-region replication enabled Warning
Ensure that S3 bucket has cross-region replication enabled
|
||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning | ||
| # Enable versioning on the source S3 bucket (required for signing) | ||
| resource "aws_s3_bucket_versioning" "lambda_source" { | ||
| bucket = aws_s3_bucket.lambda_source.id | ||
| versioning_configuration { | ||
| status = "Enabled" | ||
| } | ||
| } | ||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block | ||
| resource "aws_s3_bucket_public_access_block" "lambda_source" { | ||
| bucket = aws_s3_bucket.lambda_source.id | ||
| block_public_acls = true | ||
| block_public_policy = true | ||
| restrict_public_buckets = true | ||
| ignore_public_acls = true | ||
| } | ||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration | ||
| resource "aws_s3_bucket_server_side_encryption_configuration" "lambda_source" { | ||
| bucket = aws_s3_bucket.lambda_source.id | ||
|
|
||
| rule { | ||
| apply_server_side_encryption_by_default { | ||
| kms_master_key_id = aws_kms_key.encrypt_storage.arn | ||
| sse_algorithm = "aws:kms" | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration | ||
| resource "aws_s3_bucket_lifecycle_configuration" "lambda_source" { | ||
| bucket = aws_s3_bucket.lambda_source.id | ||
|
|
||
| rule { | ||
| id = "abort-multipart-uploads" | ||
| status = "Enabled" | ||
|
|
||
| abort_incomplete_multipart_upload { | ||
| days_after_initiation = 3 | ||
| } | ||
| } | ||
| rule { | ||
| id = "cleanup-old-versions" | ||
| status = "Enabled" | ||
|
|
||
| noncurrent_version_expiration { | ||
| noncurrent_days = 90 | ||
| } | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warning
Description: The KMS key policy grants broad permissions to the root user, which may pose security risks. Consider limiting the permissions granted to the root user in the KMS key policy. Use the principle of least privilege.
Severity: High
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix addresses the security concern by limiting the permissions granted to the root user in the KMS key policy. Instead of granting broad permissions to the root user, the fix assumes an AdminRole and grants it a more restricted set of permissions. The actions list has been reduced to include only the essential KMS operations. This change implements the principle of least privilege, reducing potential security risks.