diff --git a/README.md b/README.md index 4d4491053c..48ce800935 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ This [Terraform](https://www.terraform.io/) module creates the required infrastr - [Debugging](#debugging) - [Requirements](#requirements) - [Providers](#providers) +- [Modules](#modules) +- [Resources](#resources) - [Inputs](#inputs) - [Outputs](#outputs) - [Contribution](#contribution) @@ -366,6 +368,7 @@ No requirements. | manage\_kms\_key | Let the module manage the KMS key. | `bool` | `true` | no | | market\_options | Market options for the action runner instances. Setting the value to `null` let the scaler create on-demand instances instead of spot instances. | `string` | `"spot"` | no | | minimum\_running\_time\_in\_minutes | The time an ec2 action runner should be running at minimum before terminated if non busy. | `number` | `5` | no | +| repository\_white\_list | (optional) List of github repository full names (owner/repo_name) that will be allowed to call the runners. Leave empty for no filtering | `list(string)` | `[]` | no | | role\_path | The path that will be added to role path for created roles, if not set the environment name will be used. | `string` | `null` | no | | role\_permissions\_boundary | Permissions boundary that will be added to the created roles. | `string` | `null` | no | | runner\_additional\_security\_group\_ids | (optional) List of additional security groups IDs to apply to the runner | `list(string)` | `[]` | no | diff --git a/main.tf b/main.tf index 4d14d75c8a..096e0cccd0 100644 --- a/main.tf +++ b/main.tf @@ -49,6 +49,7 @@ module "webhook" { role_path = var.role_path role_permissions_boundary = var.role_permissions_boundary + repository_white_list = var.repository_white_list } module "runners" { diff --git a/modules/webhook/README.md b/modules/webhook/README.md index ef6506a5a1..f564397530 100644 --- a/modules/webhook/README.md +++ b/modules/webhook/README.md @@ -56,6 +56,7 @@ No requirements. | lambda\_timeout | Time out of the lambda in seconds. | `number` | `10` | no | | lambda\_zip | File location of the lambda zip file. | `string` | `null` | no | | logging\_retention\_in\_days | Specifies the number of days you want to retain log events for the lambda log group. Possible values are: 0, 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653. | `number` | `7` | no | +| repository\_white\_list | List of github repository full names (owner/repo_name) that will be allowed to call the runners. Leave empty for no filtering | `list(string)` | `[]` | no | | role\_path | The path that will be added to the role, if not set the environment name will be used. | `string` | `null` | no | | role\_permissions\_boundary | Permissions boundary that will be added to the created role for the lambda. | `string` | `null` | no | | sqs\_build\_queue | SQS queue to publish accepted build events. |
object({
id = string
arn = string
})
| n/a | yes | diff --git a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts index 9940351f73..3ec25ab5c0 100644 --- a/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts +++ b/modules/webhook/lambdas/webhook/src/webhook/handler.test.ts @@ -14,6 +14,7 @@ describe('handler', () => { let originalError: Console['error']; beforeEach(() => { + process.env.REPOSITORY_WHITE_LIST = '[]'; process.env.GITHUB_APP_WEBHOOK_SECRET = 'TEST_SECRET'; originalError = console.error; console.error = jest.fn(); @@ -71,4 +72,25 @@ describe('handler', () => { expect(resp).toBe(200); expect(sendActionRequest).not.toBeCalled(); }); + + it('does not handle check_run events from unlisted repositories', async () => { + process.env.REPOSITORY_WHITE_LIST = '["NotCodertocat/Hello-World"]'; + const resp = await handle( + { 'X-Hub-Signature': 'sha1=4a82d2f60346e16dab3546eb3b56d8dde4d5b659', 'X-GitHub-Event': 'check_run' }, + JSON.stringify(check_run_event), + ); + expect(resp).toBe(500); + expect(sendActionRequest).not.toBeCalled(); + }); + + it('handles check_run events from whitelisted repositories', async () => { + process.env.REPOSITORY_WHITE_LIST = '["Codertocat/Hello-World"]'; + const resp = await handle( + { 'X-Hub-Signature': 'sha1=4a82d2f60346e16dab3546eb3b56d8dde4d5b659', 'X-GitHub-Event': 'check_run' }, + JSON.stringify(check_run_event), + ); + expect(resp).toBe(200); + expect(sendActionRequest).toBeCalled(); + }); + }); diff --git a/modules/webhook/lambdas/webhook/src/webhook/handler.ts b/modules/webhook/lambdas/webhook/src/webhook/handler.ts index 5ec86bbdd1..06886677e0 100644 --- a/modules/webhook/lambdas/webhook/src/webhook/handler.ts +++ b/modules/webhook/lambdas/webhook/src/webhook/handler.ts @@ -40,6 +40,18 @@ export const handle = async (headers: IncomingHttpHeaders, payload: any): Promis if (githubEvent === 'check_run') { const body = JSON.parse(payload) as CheckRunEvent; + + const repositoryWhiteListEnv = process.env.REPOSITORY_WHITE_LIST as string || "[]"; + const repositoryWhiteList = JSON.parse(repositoryWhiteListEnv) as Array; + + if (repositoryWhiteList.length > 0) { + const repositoryFullName = body.repository.full_name; + if (!repositoryWhiteList.includes(repositoryFullName)) { + console.error(`Received event from unauthorized repository ${repositoryFullName}`); + return 500; + } + } + let installationId = body.installation?.id; if (installationId == null) { installationId = 0; diff --git a/modules/webhook/variables.tf b/modules/webhook/variables.tf index 665ddaaf34..8b71e1e99b 100644 --- a/modules/webhook/variables.tf +++ b/modules/webhook/variables.tf @@ -79,3 +79,8 @@ variable "webhook_lambda_s3_object_version" { default = null } +variable "repository_white_list" { + description = "List of repositories allowed to use the github app" + type = list(string) + default = [] +} diff --git a/modules/webhook/webhook.tf b/modules/webhook/webhook.tf index fc69049976..e3c1b284aa 100644 --- a/modules/webhook/webhook.tf +++ b/modules/webhook/webhook.tf @@ -44,6 +44,7 @@ resource "aws_lambda_function" "webhook" { KMS_KEY_ID = var.encryption.kms_key_id GITHUB_APP_WEBHOOK_SECRET = local.github_app_webhook_secret SQS_URL_WEBHOOK = var.sqs_build_queue.id + REPOSITORY_WHITE_LIST = jsonencode(var.repository_white_list) } } diff --git a/variables.tf b/variables.tf index 2b914d5ffa..55969b6cec 100644 --- a/variables.tf +++ b/variables.tf @@ -360,3 +360,9 @@ variable "instance_types" { type = set(string) default = null } + +variable "repository_white_list" { + description = "List of repositories allowed to use the github app" + type = list(string) + default = [] +}