Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .checkov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@ skip-check:
# It is not needed here since our Lambda functions use container
# images over uploading .zip files for layers.
- CKV_AWS_272

# AWS-managed key encryption is sufficient and CMK not required for this service
- CKV_AWS_149

# IAM user required for local development
- CKV_AWS_273

# Key rotation is already provisioned by external module
- CKV2_AWS_57
9 changes: 8 additions & 1 deletion .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ AVD-AWS-0017
AVD-AWS-0104

# Ignore wildcarded resource in IAM policy
AVD-AWS-0057
AVD-AWS-0057

# MFA enforcement on IAM group is not applicable as group is used for
# programmatic access via access keys, not console login
AVD-AWS-0123

# AWS-managed key encryption is sufficient and CMK not required
AVD-AWS-0098
6 changes: 3 additions & 3 deletions docs/technical_documentation/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The `config.json` file contains the following:
"features": {
"show_log_locally": false,
"write_data_locally": false
},
}
}
```

Expand Down Expand Up @@ -40,7 +40,7 @@ When testing locally, you might set the `config.json` file as follows:
"features": {
"show_log_locally": true,
"write_data_locally": true
},
}
}
```

Expand All @@ -53,7 +53,7 @@ When deploying to AWS, the `config.json` file should be set as follows:
"features": {
"show_log_locally": false,
"write_data_locally": false
},
}
}
```

Expand Down
6 changes: 6 additions & 0 deletions kics.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ exclude-queries:

# Sensitive Port Exposed to Private Network (This is fine due to VPC)
- 92fe237e-074c-4262-81a4-2077acb928c1

# AWS-managed key encryption is sufficient and CMK not required for this service
- a2f548f2-188c-4fff-b172-e9a6acb216bd

# Prevent user group no membership false positive
- fc101ca7-c9dd-4198-a1eb-0fbe92e80044
298 changes: 176 additions & 122 deletions poetry.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ github-api-toolkit = {git = "https://github.com/ONS-Innovation/github-api-packag
requests = "^2.32.3"
botocore = "^1.40.2"
certifi = "^2025.8.3"
cffi = "^1.17.1"
cffi = ">=2.0.0"
charset-normalizer = "^3.4.2"
cryptography = "^45.0.5"
cryptography = "^46.0.5"
idna = "^3.10"
jmespath = "^1.0.1"
pycparser = "^2.22"
Expand Down
56 changes: 56 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,60 @@ resource "aws_iam_role_policy_attachment" "eventbridge_policy" {
resource "aws_cloudwatch_log_group" "loggroup" {
name = "/aws/lambda/${aws_lambda_function.lambda_function.function_name}"
retention_in_days = var.log_retention_days
}

# IAM User Group
resource "aws_iam_group" "group" {
name = "${var.env_name}-${var.lambda_name}-user-group"
path = "/"
}

resource "aws_iam_group_policy_attachment" "group_vpc_permissions_attachment" {
group = aws_iam_group.group.name
policy_arn = aws_iam_policy.vpc_permissions.arn
}

resource "aws_iam_group_policy_attachment" "group_lambda_logging_attachment" {
group = aws_iam_group.group.name
policy_arn = aws_iam_policy.lambda_logging.arn
}

resource "aws_iam_group_policy_attachment" "group_lambda_s3_policy_attachment" {
group = aws_iam_group.group.name
policy_arn = aws_iam_policy.lambda_s3_policy.arn
}

resource "aws_iam_group_policy_attachment" "group_lambda_secret_manager_policy_attachment" {
group = aws_iam_group.group.name
policy_arn = aws_iam_policy.lambda_secret_manager_policy.arn
}

resource "aws_iam_group_policy_attachment" "group_lambda_eventbridge_policy_attachment" {
group = aws_iam_group.group.name
policy_arn = aws_iam_policy.lambda_eventbridge_policy.arn
}

# IAM User
resource "aws_iam_user" "user" {
name = "${var.env_name}-${var.lambda_name}"
path = "/"
}

# Assign IAM User to group
resource "aws_iam_user_group_membership" "user_group_attach" {
user = aws_iam_user.user.name

groups = [
aws_iam_group.group.name
]
}

# IAM Key Rotation Module
module "iam_key_rotation" {
source = "git::https://github.com/ONS-Innovation/keh-aws-iam-key-rotation.git?ref=v0.1.0"

iam_username = aws_iam_user.user.name
access_key_secret_arn = aws_secretsmanager_secret.access_key.arn
secret_key_secret_arn = aws_secretsmanager_secret.secret_key.arn
rotation_in_days = 90
}
14 changes: 14 additions & 0 deletions terraform/secrets.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Secrets for rotated IAM user access keys
resource "aws_secretsmanager_secret" "access_key" {
name = "${var.env_name}-${var.lambda_name}-access-key"
description = "Access Key ID for copilot usage lambda IAM user"
recovery_window_in_days = 0 // Secret will be deleted immediately
force_overwrite_replica_secret = true // Allow overwriting the secret in case of changes
}

resource "aws_secretsmanager_secret" "secret_key" {
name = "${var.env_name}-${var.lambda_name}-secret-key"
description = "Secret Access Key for copilot usage lambda IAM user"
recovery_window_in_days = 0 // Secret will be deleted immediately
force_overwrite_replica_secret = true // Allow overwriting the secret in case of changes
}