@cloudsnorkel/cdk-github-runners 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/.jsii +272 -25
  2. package/API.md +215 -0
  3. package/assets/lambdas/setup.lambda/index.js +10 -6
  4. package/assets/lambdas/status.lambda/index.js +22 -10
  5. package/assets/lambdas/webhook-handler.lambda/index.js +15 -7
  6. package/lib/access.d.ts +65 -0
  7. package/lib/access.js +160 -0
  8. package/lib/index.d.ts +1 -0
  9. package/lib/index.js +2 -1
  10. package/lib/lambdas/setup.lambda.js +11 -7
  11. package/lib/lambdas/status.lambda.js +24 -11
  12. package/lib/lambdas/webhook-handler.lambda.js +19 -10
  13. package/lib/providers/codebuild.js +2 -2
  14. package/lib/providers/common.js +3 -3
  15. package/lib/providers/ec2.js +2 -2
  16. package/lib/providers/fargate.js +2 -2
  17. package/lib/providers/image-builders/api.js +1 -1
  18. package/lib/providers/image-builders/aws-image-builder/builder.js +1 -1
  19. package/lib/providers/image-builders/aws-image-builder/deprecated/ami.js +1 -1
  20. package/lib/providers/image-builders/aws-image-builder/deprecated/container.js +1 -1
  21. package/lib/providers/image-builders/aws-image-builder/deprecated/linux-components.js +1 -1
  22. package/lib/providers/image-builders/aws-image-builder/deprecated/windows-components.js +1 -1
  23. package/lib/providers/image-builders/codebuild-deprecated.js +1 -1
  24. package/lib/providers/image-builders/components.js +1 -1
  25. package/lib/providers/image-builders/static.js +1 -1
  26. package/lib/providers/lambda.js +2 -2
  27. package/lib/runner.d.ts +23 -0
  28. package/lib/runner.js +13 -4
  29. package/lib/secrets.js +1 -1
  30. package/lib/webhook.d.ts +5 -0
  31. package/lib/webhook.js +5 -4
  32. package/package.json +1 -1
package/API.md CHANGED
@@ -4550,6 +4550,68 @@ VPC where builder instances will be launched.
4550
4550
 
4551
4551
  ---
4552
4552
 
4553
+ ### ApiGatewayAccessProps <a name="ApiGatewayAccessProps" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps"></a>
4554
+
4555
+ #### Initializer <a name="Initializer" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.Initializer"></a>
4556
+
4557
+ ```typescript
4558
+ import { ApiGatewayAccessProps } from '@cloudsnorkel/cdk-github-runners'
4559
+
4560
+ const apiGatewayAccessProps: ApiGatewayAccessProps = { ... }
4561
+ ```
4562
+
4563
+ #### Properties <a name="Properties" id="Properties"></a>
4564
+
4565
+ | **Name** | **Type** | **Description** |
4566
+ | --- | --- | --- |
4567
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedIps">allowedIps</a></code> | <code>string[]</code> | List of IP addresses in CIDR notation that are allowed to access the API Gateway. |
4568
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedSecurityGroups">allowedSecurityGroups</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup[]</code> | List of security groups that are allowed to access the API Gateway. |
4569
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedVpc">allowedVpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | Creates a private API Gateway and allows access from the specified VPC. |
4570
+
4571
+ ---
4572
+
4573
+ ##### `allowedIps`<sup>Optional</sup> <a name="allowedIps" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedIps"></a>
4574
+
4575
+ ```typescript
4576
+ public readonly allowedIps: string[];
4577
+ ```
4578
+
4579
+ - *Type:* string[]
4580
+
4581
+ List of IP addresses in CIDR notation that are allowed to access the API Gateway.
4582
+
4583
+ If not specified on public API Gateway, all IP addresses are allowed.
4584
+
4585
+ If not specified on private API Gateway, no IP addresses are allowed (but specified security groups are).
4586
+
4587
+ ---
4588
+
4589
+ ##### `allowedSecurityGroups`<sup>Optional</sup> <a name="allowedSecurityGroups" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedSecurityGroups"></a>
4590
+
4591
+ ```typescript
4592
+ public readonly allowedSecurityGroups: ISecurityGroup[];
4593
+ ```
4594
+
4595
+ - *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[]
4596
+
4597
+ List of security groups that are allowed to access the API Gateway.
4598
+
4599
+ Only works for private API Gateways with {@link allowedVpc}.
4600
+
4601
+ ---
4602
+
4603
+ ##### `allowedVpc`<sup>Optional</sup> <a name="allowedVpc" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedVpc"></a>
4604
+
4605
+ ```typescript
4606
+ public readonly allowedVpc: IVpc;
4607
+ ```
4608
+
4609
+ - *Type:* aws-cdk-lib.aws_ec2.IVpc
4610
+
4611
+ Creates a private API Gateway and allows access from the specified VPC.
4612
+
4613
+ ---
4614
+
4553
4615
  ### AwsImageBuilderRunnerImageBuilderProps <a name="AwsImageBuilderRunnerImageBuilderProps" id="@cloudsnorkel/cdk-github-runners.AwsImageBuilderRunnerImageBuilderProps"></a>
4554
4616
 
4555
4617
  #### Initializer <a name="Initializer" id="@cloudsnorkel/cdk-github-runners.AwsImageBuilderRunnerImageBuilderProps.Initializer"></a>
@@ -5819,8 +5881,11 @@ const gitHubRunnersProps: GitHubRunnersProps = { ... }
5819
5881
  | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.logOptions">logOptions</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LogOptions">LogOptions</a></code> | Logging options for the state machine that manages the runners. |
5820
5882
  | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.providers">providers</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.IRunnerProvider">IRunnerProvider</a>[]</code> | List of runner providers to use. |
5821
5883
  | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.securityGroup">securityGroup</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup</code> | Security group attached to all management functions. |
5884
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.setupAccess">setupAccess</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a></code> | Access configuration for the setup function. |
5885
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.statusAccess">statusAccess</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a></code> | Access configuration for the status function. |
5822
5886
  | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpc">vpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | VPC used for all management functions. |
5823
5887
  | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpcSubnets">vpcSubnets</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | VPC subnets used for all management functions. |
5888
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.webhookAccess">webhookAccess</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a></code> | Access configuration for the webhook function. |
5824
5889
 
5825
5890
  ---
5826
5891
 
@@ -5928,6 +5993,36 @@ Use this with to provide access to GitHub Enterprise Server hosted inside a VPC.
5928
5993
 
5929
5994
  ---
5930
5995
 
5996
+ ##### `setupAccess`<sup>Optional</sup> <a name="setupAccess" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.setupAccess"></a>
5997
+
5998
+ ```typescript
5999
+ public readonly setupAccess: LambdaAccess;
6000
+ ```
6001
+
6002
+ - *Type:* <a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a>
6003
+ - *Default:* LambdaAccess.lambdaUrl()
6004
+
6005
+ Access configuration for the setup function.
6006
+
6007
+ Once you finish the setup process, you can set this to `LambdaAccess.noAccess()` to remove access to the setup function. You can also use `LambdaAccess.apiGateway({ allowedIps: ['my-ip/0']})` to limit access to your IP only.
6008
+
6009
+ ---
6010
+
6011
+ ##### `statusAccess`<sup>Optional</sup> <a name="statusAccess" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.statusAccess"></a>
6012
+
6013
+ ```typescript
6014
+ public readonly statusAccess: LambdaAccess;
6015
+ ```
6016
+
6017
+ - *Type:* <a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a>
6018
+ - *Default:* LambdaAccess.noAccess()
6019
+
6020
+ Access configuration for the status function.
6021
+
6022
+ This function returns a lot of sensitive information about the runner, so you should only allow access to it from trusted IPs, if at all.
6023
+
6024
+ ---
6025
+
5931
6026
  ##### `vpc`<sup>Optional</sup> <a name="vpc" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpc"></a>
5932
6027
 
5933
6028
  ```typescript
@@ -5956,6 +6051,25 @@ Use this with GitHub Enterprise Server hosted that's inaccessible from outside t
5956
6051
 
5957
6052
  ---
5958
6053
 
6054
+ ##### `webhookAccess`<sup>Optional</sup> <a name="webhookAccess" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.webhookAccess"></a>
6055
+
6056
+ ```typescript
6057
+ public readonly webhookAccess: LambdaAccess;
6058
+ ```
6059
+
6060
+ - *Type:* <a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a>
6061
+ - *Default:* LambdaAccess.lambdaUrl()
6062
+
6063
+ Access configuration for the webhook function.
6064
+
6065
+ This function is called by GitHub when a new workflow job is scheduled. For an extra layer of security, you can set this to `LambdaAccess.apiGateway({ allowedIps: LambdaAccess.githubWebhookIps() })`.
6066
+
6067
+ You can also set this to `LambdaAccess.privateApiGateway()` if your GitHub Enterprise Server is hosted in a VPC. This will create an API Gateway endpoint that's only accessible from within the VPC.
6068
+
6069
+ *WARNING*: changing access type may change the URL. When the URL changes, you must update GitHub as well.
6070
+
6071
+ ---
6072
+
5959
6073
  ### ImageBuilderAsset <a name="ImageBuilderAsset" id="@cloudsnorkel/cdk-github-runners.ImageBuilderAsset"></a>
5960
6074
 
5961
6075
  An asset including file or directory to place inside the built image.
@@ -7262,6 +7376,107 @@ X86_64.
7262
7376
 
7263
7377
  ---
7264
7378
 
7379
+ ### LambdaAccess <a name="LambdaAccess" id="@cloudsnorkel/cdk-github-runners.LambdaAccess"></a>
7380
+
7381
+ Access configuration options for Lambda functions like setup and webhook function.
7382
+
7383
+ Use this to limit access to these functions.
7384
+
7385
+ #### Initializers <a name="Initializers" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.Initializer"></a>
7386
+
7387
+ ```typescript
7388
+ import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
7389
+
7390
+ new LambdaAccess()
7391
+ ```
7392
+
7393
+ | **Name** | **Type** | **Description** |
7394
+ | --- | --- | --- |
7395
+
7396
+ ---
7397
+
7398
+
7399
+ #### Static Functions <a name="Static Functions" id="Static Functions"></a>
7400
+
7401
+ | **Name** | **Description** |
7402
+ | --- | --- |
7403
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.apiGateway">apiGateway</a></code> | Provide access using API Gateway. |
7404
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.githubWebhookIps">githubWebhookIps</a></code> | Downloads the list of IP addresses used by GitHub.com for webhooks. |
7405
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.lambdaUrl">lambdaUrl</a></code> | Provide access using Lambda URL. |
7406
+ | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.noAccess">noAccess</a></code> | Disables access to the configured Lambda function. |
7407
+
7408
+ ---
7409
+
7410
+ ##### `apiGateway` <a name="apiGateway" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.apiGateway"></a>
7411
+
7412
+ ```typescript
7413
+ import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
7414
+
7415
+ LambdaAccess.apiGateway(props?: ApiGatewayAccessProps)
7416
+ ```
7417
+
7418
+ Provide access using API Gateway.
7419
+
7420
+ This is the most secure option, but requires additional configuration. It allows you to limit access to specific IP addresses and even to a specific VPC.
7421
+
7422
+ To limit access to GitHub.com use:
7423
+
7424
+ ```
7425
+ LambdaAccess.apiGateway({
7426
+ allowedIps: LambdaAccess.githubWebhookIps(),
7427
+ });
7428
+ ```
7429
+
7430
+ Alternatively, get and manually update the list manually with:
7431
+
7432
+ ```
7433
+ curl https://api.github.com/meta | jq .hooks
7434
+ ```
7435
+
7436
+ ###### `props`<sup>Optional</sup> <a name="props" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.apiGateway.parameter.props"></a>
7437
+
7438
+ - *Type:* <a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps">ApiGatewayAccessProps</a>
7439
+
7440
+ ---
7441
+
7442
+ ##### `githubWebhookIps` <a name="githubWebhookIps" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.githubWebhookIps"></a>
7443
+
7444
+ ```typescript
7445
+ import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
7446
+
7447
+ LambdaAccess.githubWebhookIps()
7448
+ ```
7449
+
7450
+ Downloads the list of IP addresses used by GitHub.com for webhooks.
7451
+
7452
+ Note that downloading dynamic data during deployment is not recommended in CDK. This is a workaround for the lack of a better solution.
7453
+
7454
+ ##### `lambdaUrl` <a name="lambdaUrl" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.lambdaUrl"></a>
7455
+
7456
+ ```typescript
7457
+ import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
7458
+
7459
+ LambdaAccess.lambdaUrl()
7460
+ ```
7461
+
7462
+ Provide access using Lambda URL.
7463
+
7464
+ This is the default and simplest option. It puts no limits on the requester, but the Lambda functions themselves authenticate every request.
7465
+
7466
+ ##### `noAccess` <a name="noAccess" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.noAccess"></a>
7467
+
7468
+ ```typescript
7469
+ import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
7470
+
7471
+ LambdaAccess.noAccess()
7472
+ ```
7473
+
7474
+ Disables access to the configured Lambda function.
7475
+
7476
+ This is useful for the setup function after setup is done.
7477
+
7478
+
7479
+
7265
7480
  ### LinuxUbuntuComponents <a name="LinuxUbuntuComponents" id="@cloudsnorkel/cdk-github-runners.LinuxUbuntuComponents"></a>
7266
7481
 
7267
7482
  Components for Ubuntu Linux that can be used with AWS Image Builder based builders.
@@ -9164,7 +9164,8 @@ function response(code, body) {
9164
9164
  };
9165
9165
  }
9166
9166
  async function handleRoot(event, setupToken) {
9167
- const setupBaseUrl = `https://${event.requestContext.domainName}`;
9167
+ const stage = event.requestContext.stage == "$default" ? "" : `/${event.requestContext.stage}`;
9168
+ const setupBaseUrl = `https://${event.requestContext.domainName}${stage}`;
9168
9169
  const githubSecrets = await getSecretJsonValue(process.env.GITHUB_SECRET_ARN);
9169
9170
  return response(200, getHtml(setupBaseUrl, setupToken, githubSecrets.domain));
9170
9171
  }
@@ -9254,20 +9255,23 @@ exports.handler = async function(event) {
9254
9255
  return response(403, "Wrong setup token.");
9255
9256
  }
9256
9257
  try {
9257
- if (event.requestContext.http.path == "/") {
9258
+ const path = event.path ?? event.rawPath;
9259
+ const method = event.httpMethod ?? event.requestContext.http.method;
9260
+ if (path == "/") {
9258
9261
  return await handleRoot(event, setupToken);
9259
- } else if (event.requestContext.http.path == "/domain" && event.requestContext.http.method == "POST") {
9262
+ } else if (path == "/domain" && method == "POST") {
9260
9263
  return await handleDomain(event);
9261
- } else if (event.requestContext.http.path == "/pat" && event.requestContext.http.method == "POST") {
9264
+ } else if (path == "/pat" && method == "POST") {
9262
9265
  return await handlePat(event);
9263
- } else if (event.requestContext.http.path == "/complete-new-app" && event.requestContext.http.method == "GET") {
9266
+ } else if (path == "/complete-new-app" && method == "GET") {
9264
9267
  return await handleNewApp(event);
9265
- } else if (event.requestContext.http.path == "/app" && event.requestContext.http.method == "POST") {
9268
+ } else if (path == "/app" && method == "POST") {
9266
9269
  return await handleExistingApp(event);
9267
9270
  } else {
9268
9271
  return response(404, "Not found");
9269
9272
  }
9270
9273
  } catch (e) {
9274
+ console.error(e);
9271
9275
  return response(500, `<b>Error:</b> ${e}`);
9272
9276
  }
9273
9277
  };
@@ -21184,7 +21184,19 @@ async function generateProvidersStatus(stack, logicalId) {
21184
21184
  return p;
21185
21185
  }));
21186
21186
  }
21187
- exports.handler = async function() {
21187
+ function safeReturnValue(event, status) {
21188
+ if (event.path) {
21189
+ return {
21190
+ statusCode: 200,
21191
+ headers: {
21192
+ "Content-Type": "application/json"
21193
+ },
21194
+ body: JSON.stringify(status)
21195
+ };
21196
+ }
21197
+ return status;
21198
+ }
21199
+ exports.handler = async function(event) {
21188
21200
  if (!process.env.WEBHOOK_SECRET_ARN || !process.env.GITHUB_SECRET_ARN || !process.env.GITHUB_PRIVATE_KEY_SECRET_ARN || !process.env.LOGICAL_ID || !process.env.WEBHOOK_HANDLER_ARN || !process.env.STEP_FUNCTION_ARN || !process.env.SETUP_SECRET_ARN || !process.env.SETUP_FUNCTION_URL || !process.env.STACK_NAME) {
21189
21201
  throw new Error("Missing environment variables");
21190
21202
  }
@@ -21261,14 +21273,14 @@ exports.handler = async function() {
21261
21273
  githubSecrets = await getSecretJsonValue(process.env.GITHUB_SECRET_ARN);
21262
21274
  } catch (e) {
21263
21275
  status.github.auth.status = `Unable to read secret: ${e}`;
21264
- return status;
21276
+ return safeReturnValue(event, status);
21265
21277
  }
21266
21278
  let privateKey;
21267
21279
  try {
21268
21280
  privateKey = await getSecretValue(process.env.GITHUB_PRIVATE_KEY_SECRET_ARN);
21269
21281
  } catch (e) {
21270
21282
  status.github.auth.status = `Unable to read private key secret: ${e}`;
21271
- return status;
21283
+ return safeReturnValue(event, status);
21272
21284
  }
21273
21285
  let baseUrl = baseUrlFromDomain(githubSecrets.domain);
21274
21286
  status.github.domain = githubSecrets.domain;
@@ -21280,14 +21292,14 @@ exports.handler = async function() {
21280
21292
  octokit = new import_core.Octokit({ baseUrl, auth: githubSecrets.personalAuthToken });
21281
21293
  } catch (e) {
21282
21294
  status.github.auth.status = `Unable to authenticate using personal auth token: ${e}`;
21283
- return status;
21295
+ return safeReturnValue(event, status);
21284
21296
  }
21285
21297
  try {
21286
21298
  const user = await octokit.request("GET /user");
21287
21299
  status.github.auth.personalAuthToken = `username: ${user.data.login}`;
21288
21300
  } catch (e) {
21289
21301
  status.github.auth.status = `Unable to call /user with personal auth token: ${e}`;
21290
- return status;
21302
+ return safeReturnValue(event, status);
21291
21303
  }
21292
21304
  status.github.auth.status = "OK";
21293
21305
  status.github.webhook.status = "Unable to verify automatically";
@@ -21306,14 +21318,14 @@ exports.handler = async function() {
21306
21318
  });
21307
21319
  } catch (e) {
21308
21320
  status.github.auth.status = `Unable to authenticate app: ${e}`;
21309
- return status;
21321
+ return safeReturnValue(event, status);
21310
21322
  }
21311
21323
  try {
21312
21324
  const app = (await appOctokit.request("GET /app")).data;
21313
21325
  status.github.auth.app.url = app.html_url;
21314
21326
  } catch (e) {
21315
21327
  status.github.auth.status = `Unable to get app details: ${e}`;
21316
- return status;
21328
+ return safeReturnValue(event, status);
21317
21329
  }
21318
21330
  try {
21319
21331
  const installations = (await appOctokit.request("GET /app/installations")).data;
@@ -21355,7 +21367,7 @@ exports.handler = async function() {
21355
21367
  }
21356
21368
  } catch (e) {
21357
21369
  status.github.auth.status = "Unable to list app installations";
21358
- return status;
21370
+ return safeReturnValue(event, status);
21359
21371
  }
21360
21372
  status.github.auth.status = "OK";
21361
21373
  try {
@@ -21367,10 +21379,10 @@ exports.handler = async function() {
21367
21379
  }
21368
21380
  } catch (e) {
21369
21381
  status.github.webhook.status = `Unable to check app configuration: ${e}`;
21370
- return status;
21382
+ return safeReturnValue(event, status);
21371
21383
  }
21372
21384
  }
21373
- return status;
21385
+ return safeReturnValue(event, status);
21374
21386
  };
21375
21387
  /*! Bundled license information:
21376
21388
 
@@ -45,8 +45,16 @@ async function getSecretJsonValue(arn) {
45
45
 
46
46
  // src/lambdas/webhook-handler.lambda.ts
47
47
  var sf = new AWS2.StepFunctions();
48
+ function getHeader(event, header) {
49
+ for (const headerName of Object.keys(event.headers)) {
50
+ if (headerName.toLowerCase() === header.toLowerCase()) {
51
+ return event.headers[headerName];
52
+ }
53
+ }
54
+ return void 0;
55
+ }
48
56
  function verifyBody(event, secret) {
49
- const sig = Buffer.from(event.headers["x-hub-signature-256"] || "", "utf8");
57
+ const sig = Buffer.from(getHeader(event, "x-hub-signature-256") || "", "utf8");
50
58
  if (!event.body) {
51
59
  throw new Error("No body");
52
60
  }
@@ -81,21 +89,21 @@ exports.handler = async function(event) {
81
89
  body: "Bad signature"
82
90
  };
83
91
  }
84
- if (event.headers["content-type"] !== "application/json") {
85
- console.error(`This webhook only accepts JSON payloads, got ${event.headers["content-type"]}`);
92
+ if (getHeader(event, "content-type") !== "application/json") {
93
+ console.error(`This webhook only accepts JSON payloads, got ${getHeader(event, "content-type")}`);
86
94
  return {
87
95
  statusCode: 400,
88
96
  body: "Expecting JSON payload"
89
97
  };
90
98
  }
91
- if (event.headers["x-github-event"] === "ping") {
99
+ if (getHeader(event, "x-github-event") === "ping") {
92
100
  return {
93
101
  statusCode: 200,
94
102
  body: "Pong"
95
103
  };
96
104
  }
97
- if (event.headers["x-github-event"] !== "workflow_job") {
98
- console.error(`This webhook only accepts workflow_job, got ${event.headers["x-github-event"]}`);
105
+ if (getHeader(event, "x-github-event") !== "workflow_job") {
106
+ console.error(`This webhook only accepts workflow_job, got ${getHeader(event, "x-github-event")}`);
99
107
  return {
100
108
  statusCode: 400,
101
109
  body: "Expecting workflow_job"
@@ -118,7 +126,7 @@ exports.handler = async function(event) {
118
126
  }
119
127
  let labels = {};
120
128
  payload.workflow_job.labels.forEach((l) => labels[l.toLowerCase()] = true);
121
- let executionName = `${payload.repository.full_name.replace("/", "-")}-${event.headers["x-github-delivery"]}`.slice(0, 64);
129
+ let executionName = `${payload.repository.full_name.replace("/", "-")}-${getHeader(event, "x-github-delivery")}`.slice(0, 64);
122
130
  const execution = await sf.startExecution({
123
131
  stateMachineArn: process.env.STEP_FUNCTION_ARN,
124
132
  input: JSON.stringify({
@@ -0,0 +1,65 @@
1
+ import { aws_ec2 as ec2, aws_lambda as lambda } from 'aws-cdk-lib';
2
+ import { Construct } from 'constructs';
3
+ export interface ApiGatewayAccessProps {
4
+ /**
5
+ * List of IP addresses in CIDR notation that are allowed to access the API Gateway.
6
+ *
7
+ * If not specified on public API Gateway, all IP addresses are allowed.
8
+ *
9
+ * If not specified on private API Gateway, no IP addresses are allowed (but specified security groups are).
10
+ */
11
+ readonly allowedIps?: string[];
12
+ /**
13
+ * Creates a private API Gateway and allows access from the specified VPC.
14
+ */
15
+ readonly allowedVpc?: ec2.IVpc;
16
+ /**
17
+ * List of security groups that are allowed to access the API Gateway.
18
+ *
19
+ * Only works for private API Gateways with {@link allowedVpc}.
20
+ */
21
+ readonly allowedSecurityGroups?: ec2.ISecurityGroup[];
22
+ }
23
+ /**
24
+ * Access configuration options for Lambda functions like setup and webhook function. Use this to limit access to these functions.
25
+ */
26
+ export declare abstract class LambdaAccess {
27
+ /**
28
+ * Disables access to the configured Lambda function. This is useful for the setup function after setup is done.
29
+ */
30
+ static noAccess(): LambdaAccess;
31
+ /**
32
+ * Provide access using Lambda URL. This is the default and simplest option. It puts no limits on the requester, but the Lambda functions themselves authenticate every request.
33
+ */
34
+ static lambdaUrl(): LambdaAccess;
35
+ /**
36
+ * Provide access using API Gateway. This is the most secure option, but requires additional configuration. It allows you to limit access to specific IP addresses and even to a specific VPC.
37
+ *
38
+ * To limit access to GitHub.com use:
39
+ *
40
+ * ```
41
+ * LambdaAccess.apiGateway({
42
+ * allowedIps: LambdaAccess.githubWebhookIps(),
43
+ * });
44
+ * ```
45
+ *
46
+ * Alternatively, get and manually update the list manually with:
47
+ *
48
+ * ```
49
+ * curl https://api.github.com/meta | jq .hooks
50
+ * ```
51
+ */
52
+ static apiGateway(props?: ApiGatewayAccessProps): LambdaAccess;
53
+ /**
54
+ * Downloads the list of IP addresses used by GitHub.com for webhooks.
55
+ *
56
+ * Note that downloading dynamic data during deployment is not recommended in CDK. This is a workaround for the lack of a better solution.
57
+ */
58
+ static githubWebhookIps(): string[];
59
+ /**
60
+ * Creates all required resources and returns access URL or empty string if disabled.
61
+ *
62
+ * @internal
63
+ */
64
+ abstract _bind(construct: Construct, id: string, lambdaFunction: lambda.Function): string;
65
+ }