@quiltdata/benchling-webhook 0.9.0-20251127T201515Z → 0.9.0-20251129T063536Z
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.
- package/README.md +111 -5
- package/dist/bin/benchling-webhook.js +6 -0
- package/dist/bin/benchling-webhook.js.map +1 -1
- package/dist/bin/cli.js +1 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/commands/deploy.d.ts +2 -0
- package/dist/bin/commands/deploy.d.ts.map +1 -1
- package/dist/bin/commands/deploy.js +82 -0
- package/dist/bin/commands/deploy.js.map +1 -1
- package/dist/bin/commands/logs.d.ts.map +1 -1
- package/dist/bin/commands/logs.js +20 -3
- package/dist/bin/commands/logs.js.map +1 -1
- package/dist/bin/commands/status.d.ts +1 -0
- package/dist/bin/commands/status.d.ts.map +1 -1
- package/dist/bin/commands/status.js +55 -5
- package/dist/bin/commands/status.js.map +1 -1
- package/dist/lib/benchling-webhook-stack.d.ts.map +1 -1
- package/dist/lib/benchling-webhook-stack.js +10 -7
- package/dist/lib/benchling-webhook-stack.js.map +1 -1
- package/dist/lib/http-api-gateway.d.ts +3 -0
- package/dist/lib/http-api-gateway.d.ts.map +1 -1
- package/dist/lib/http-api-gateway.js +149 -8
- package/dist/lib/http-api-gateway.js.map +1 -1
- package/dist/lib/index.d.ts +0 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +2 -4
- package/dist/lib/index.js.map +1 -1
- package/dist/package.json +6 -3
- package/package.json +6 -3
- package/dist/lib/rest-api-gateway.d.ts +0 -32
- package/dist/lib/rest-api-gateway.d.ts.map +0 -1
- package/dist/lib/rest-api-gateway.js +0 -268
- package/dist/lib/rest-api-gateway.js.map +0 -1
package/dist/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/lib/index.js
CHANGED
|
@@ -26,14 +26,12 @@
|
|
|
26
26
|
* @module quilt-benchling-webhook
|
|
27
27
|
*/
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.EcrRepository = exports.HttpApiGateway = exports.
|
|
29
|
+
exports.EcrRepository = exports.HttpApiGateway = exports.FargateService = exports.BenchlingWebhookStack = void 0;
|
|
30
30
|
var benchling_webhook_stack_1 = require("./benchling-webhook-stack");
|
|
31
31
|
Object.defineProperty(exports, "BenchlingWebhookStack", { enumerable: true, get: function () { return benchling_webhook_stack_1.BenchlingWebhookStack; } });
|
|
32
32
|
var fargate_service_1 = require("./fargate-service");
|
|
33
33
|
Object.defineProperty(exports, "FargateService", { enumerable: true, get: function () { return fargate_service_1.FargateService; } });
|
|
34
|
-
var
|
|
35
|
-
Object.defineProperty(exports, "RestApiGateway", { enumerable: true, get: function () { return rest_api_gateway_1.RestApiGateway; } });
|
|
36
|
-
var http_api_gateway_1 = require("./http-api-gateway"); // Deprecated: use RestApiGateway
|
|
34
|
+
var http_api_gateway_1 = require("./http-api-gateway");
|
|
37
35
|
Object.defineProperty(exports, "HttpApiGateway", { enumerable: true, get: function () { return http_api_gateway_1.HttpApiGateway; } });
|
|
38
36
|
var ecr_repository_1 = require("./ecr-repository");
|
|
39
37
|
Object.defineProperty(exports, "EcrRepository", { enumerable: true, get: function () { return ecr_repository_1.EcrRepository; } });
|
package/dist/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;AAEH,qEAAmG;AAA1F,gIAAA,qBAAqB,OAAA;AAC9B,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,uDAAoD;AAA3C,kHAAA,cAAc,OAAA;AACvB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;AAEH,qEAAmG;AAA1F,gIAAA,qBAAqB,OAAA;AAC9B,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,uDAAoD;AAA3C,kHAAA,cAAc,OAAA;AACvB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA"}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quiltdata/benchling-webhook",
|
|
3
|
-
"version": "0.9.0-
|
|
3
|
+
"version": "0.9.0-20251129T063536Z",
|
|
4
4
|
"description": "AWS CDK deployment for Benchling webhook processing using Fargate - Deploy directly with npx",
|
|
5
5
|
"main": "dist/lib/index.js",
|
|
6
6
|
"types": "dist/lib/index.d.ts",
|
|
@@ -18,8 +18,11 @@
|
|
|
18
18
|
"build:clean": "rm -rf cdk.out dist */{*.js,*.d.ts}",
|
|
19
19
|
"build:synth": "npx cdk synth",
|
|
20
20
|
"build:typecheck": "tsc --noEmit",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
21
|
+
"build:lambda": "make lambda-bundle",
|
|
22
|
+
"build:lambda:check": "make check-bundle",
|
|
23
|
+
"build:lambda:clean": "make clean",
|
|
24
|
+
"deploy:dev": "make lambda-bundle && ts-node bin/cli.ts deploy --stage dev --profile dev",
|
|
25
|
+
"deploy:prod": "make lambda-bundle && ts-node bin/cli.ts deploy --stage prod",
|
|
23
26
|
"deploy:notes": "bash scripts/release-notes.sh",
|
|
24
27
|
"destroy": "ts-node bin/cli.ts destroy",
|
|
25
28
|
"destroy:dev": "ts-node bin/cli.ts destroy --stage dev --profile dev",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quiltdata/benchling-webhook",
|
|
3
|
-
"version": "0.9.0-
|
|
3
|
+
"version": "0.9.0-20251129T063536Z",
|
|
4
4
|
"description": "AWS CDK deployment for Benchling webhook processing using Fargate - Deploy directly with npx",
|
|
5
5
|
"main": "dist/lib/index.js",
|
|
6
6
|
"types": "dist/lib/index.d.ts",
|
|
@@ -18,8 +18,11 @@
|
|
|
18
18
|
"build:clean": "rm -rf cdk.out dist */{*.js,*.d.ts}",
|
|
19
19
|
"build:synth": "npx cdk synth",
|
|
20
20
|
"build:typecheck": "tsc --noEmit",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
21
|
+
"build:lambda": "make lambda-bundle",
|
|
22
|
+
"build:lambda:check": "make check-bundle",
|
|
23
|
+
"build:lambda:clean": "make clean",
|
|
24
|
+
"deploy:dev": "make lambda-bundle && ts-node bin/cli.ts deploy --stage dev --profile dev",
|
|
25
|
+
"deploy:prod": "make lambda-bundle && ts-node bin/cli.ts deploy --stage prod",
|
|
23
26
|
"deploy:notes": "bash scripts/release-notes.sh",
|
|
24
27
|
"destroy": "ts-node bin/cli.ts destroy",
|
|
25
28
|
"destroy:dev": "ts-node bin/cli.ts destroy --stage dev --profile dev",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import * as apigateway from "aws-cdk-lib/aws-apigateway";
|
|
2
|
-
import * as ec2 from "aws-cdk-lib/aws-ec2";
|
|
3
|
-
import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2";
|
|
4
|
-
import * as servicediscovery from "aws-cdk-lib/aws-servicediscovery";
|
|
5
|
-
import * as logs from "aws-cdk-lib/aws-logs";
|
|
6
|
-
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
7
|
-
import { Construct } from "constructs";
|
|
8
|
-
import { ProfileConfig } from "./types/config";
|
|
9
|
-
export interface RestApiGatewayProps {
|
|
10
|
-
readonly vpc: ec2.IVpc;
|
|
11
|
-
readonly cloudMapService: servicediscovery.IService;
|
|
12
|
-
readonly serviceSecurityGroup: ec2.ISecurityGroup;
|
|
13
|
-
readonly config: ProfileConfig;
|
|
14
|
-
readonly ecsService: elbv2.IApplicationLoadBalancerTarget | elbv2.INetworkLoadBalancerTarget;
|
|
15
|
-
}
|
|
16
|
-
export declare class RestApiGateway {
|
|
17
|
-
readonly api: apigateway.RestApi;
|
|
18
|
-
readonly vpcLink: apigateway.VpcLink;
|
|
19
|
-
readonly nlb: elbv2.NetworkLoadBalancer;
|
|
20
|
-
readonly logGroup: logs.ILogGroup;
|
|
21
|
-
readonly authorizer?: lambda.Function;
|
|
22
|
-
readonly authorizerLogGroup?: logs.ILogGroup;
|
|
23
|
-
constructor(scope: Construct, id: string, props: RestApiGatewayProps);
|
|
24
|
-
/**
|
|
25
|
-
* Build IAM resource policy for IP whitelisting
|
|
26
|
-
*
|
|
27
|
-
* If ipAllowList is empty, allow all IPs.
|
|
28
|
-
* Otherwise, only allow requests from specified IP addresses/CIDR blocks.
|
|
29
|
-
*/
|
|
30
|
-
private buildResourcePolicy;
|
|
31
|
-
}
|
|
32
|
-
//# sourceMappingURL=rest-api-gateway.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rest-api-gateway.d.ts","sourceRoot":"","sources":["../../lib/rest-api-gateway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,wCAAwC,CAAC;AAChE,OAAO,KAAK,gBAAgB,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,IAAI,MAAM,sBAAsB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,gBAAgB,CAAC,QAAQ,CAAC;IACpD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,CAAC,cAAc,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,8BAA8B,GAAG,KAAK,CAAC,0BAA0B,CAAC;CAChG;AAED,qBAAa,cAAc;IACvB,SAAgB,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC;IACxC,SAAgB,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC;IAC5C,SAAgB,GAAG,EAAE,KAAK,CAAC,mBAAmB,CAAC;IAC/C,SAAgB,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC;IACzC,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC7C,SAAgB,kBAAkB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;gBAExC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB;IA+MpE;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;CAmC9B"}
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.RestApiGateway = void 0;
|
|
37
|
-
const cdk = __importStar(require("aws-cdk-lib"));
|
|
38
|
-
const apigateway = __importStar(require("aws-cdk-lib/aws-apigateway"));
|
|
39
|
-
const ec2 = __importStar(require("aws-cdk-lib/aws-ec2"));
|
|
40
|
-
const elbv2 = __importStar(require("aws-cdk-lib/aws-elasticloadbalancingv2"));
|
|
41
|
-
const logs = __importStar(require("aws-cdk-lib/aws-logs"));
|
|
42
|
-
const lambda = __importStar(require("aws-cdk-lib/aws-lambda"));
|
|
43
|
-
const iam = __importStar(require("aws-cdk-lib/aws-iam"));
|
|
44
|
-
class RestApiGateway {
|
|
45
|
-
constructor(scope, id, props) {
|
|
46
|
-
// Access logs for REST API
|
|
47
|
-
this.logGroup = new logs.LogGroup(scope, "ApiGatewayAccessLogs", {
|
|
48
|
-
logGroupName: "/aws/apigateway/benchling-webhook-rest",
|
|
49
|
-
retention: logs.RetentionDays.ONE_WEEK,
|
|
50
|
-
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
51
|
-
});
|
|
52
|
-
// Create Network Load Balancer for VPC Link integration
|
|
53
|
-
// REST API Gateway requires NLB (not ALB) for private integration
|
|
54
|
-
this.nlb = new elbv2.NetworkLoadBalancer(scope, "NetworkLoadBalancer", {
|
|
55
|
-
vpc: props.vpc,
|
|
56
|
-
internetFacing: false,
|
|
57
|
-
vpcSubnets: {
|
|
58
|
-
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
// Create target group for ECS service
|
|
62
|
-
const targetGroup = new elbv2.NetworkTargetGroup(scope, "TargetGroup", {
|
|
63
|
-
vpc: props.vpc,
|
|
64
|
-
port: 8080,
|
|
65
|
-
protocol: elbv2.Protocol.TCP,
|
|
66
|
-
targetType: elbv2.TargetType.IP,
|
|
67
|
-
healthCheck: {
|
|
68
|
-
enabled: true,
|
|
69
|
-
protocol: elbv2.Protocol.HTTP,
|
|
70
|
-
path: "/health",
|
|
71
|
-
interval: cdk.Duration.seconds(30),
|
|
72
|
-
timeout: cdk.Duration.seconds(10),
|
|
73
|
-
healthyThresholdCount: 2,
|
|
74
|
-
unhealthyThresholdCount: 3,
|
|
75
|
-
},
|
|
76
|
-
deregistrationDelay: cdk.Duration.seconds(30),
|
|
77
|
-
});
|
|
78
|
-
// Add listener to NLB
|
|
79
|
-
this.nlb.addListener("Listener", {
|
|
80
|
-
port: 80,
|
|
81
|
-
protocol: elbv2.Protocol.TCP,
|
|
82
|
-
defaultTargetGroups: [targetGroup],
|
|
83
|
-
});
|
|
84
|
-
// Register ECS service with target group
|
|
85
|
-
if ("attachToNetworkTargetGroup" in props.ecsService) {
|
|
86
|
-
props.ecsService.attachToNetworkTargetGroup(targetGroup);
|
|
87
|
-
}
|
|
88
|
-
// Create VPC Link with NLB as target
|
|
89
|
-
this.vpcLink = new apigateway.VpcLink(scope, "VpcLink", {
|
|
90
|
-
targets: [this.nlb],
|
|
91
|
-
vpcLinkName: "benchling-webhook-vpclink",
|
|
92
|
-
description: "VPC Link for Benchling Webhook REST API",
|
|
93
|
-
});
|
|
94
|
-
// Parse IP allowlist from config
|
|
95
|
-
const ipAllowList = props.config.security?.webhookAllowList
|
|
96
|
-
?.split(",")
|
|
97
|
-
.map((ip) => ip.trim())
|
|
98
|
-
.filter((ip) => ip.length > 0) || [];
|
|
99
|
-
const verificationEnabled = props.config.security?.enableVerification !== false;
|
|
100
|
-
const benchlingSecretArn = props.config.benchling.secretArn;
|
|
101
|
-
if (!benchlingSecretArn) {
|
|
102
|
-
throw new Error("Benchling secret ARN is required to configure the Lambda authorizer");
|
|
103
|
-
}
|
|
104
|
-
// Build resource policy for IP whitelisting
|
|
105
|
-
const resourcePolicy = this.buildResourcePolicy(ipAllowList);
|
|
106
|
-
// Lambda authorizer for webhook verification
|
|
107
|
-
this.authorizerLogGroup = new logs.LogGroup(scope, "WebhookAuthorizerLogGroup", {
|
|
108
|
-
retention: logs.RetentionDays.ONE_WEEK,
|
|
109
|
-
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
110
|
-
});
|
|
111
|
-
const bundlingCommands = [
|
|
112
|
-
"set -euo pipefail",
|
|
113
|
-
"export PIP_NO_BUILD_ISOLATION=1 PIP_ONLY_BINARY=:all: PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_CACHE_DIR=/tmp/pipcache",
|
|
114
|
-
"pip install -q --platform manylinux2014_x86_64 --implementation cp --python-version 3.11 --abi cp311 --only-binary=:all: -t /asset-output -r /asset-input/lambda/authorizer/requirements.txt -c /asset-input/lambda/authorizer/constraints.txt",
|
|
115
|
-
"cp /asset-input/docker/src/lambda_authorizer.py /asset-output/index.py",
|
|
116
|
-
].join(" && ");
|
|
117
|
-
const authorizerCode = process.env.NODE_ENV === "test"
|
|
118
|
-
? lambda.Code.fromInline("def handler(event, context):\n return {}")
|
|
119
|
-
: lambda.Code.fromAsset(".", {
|
|
120
|
-
bundling: {
|
|
121
|
-
image: lambda.Runtime.PYTHON_3_11.bundlingImage,
|
|
122
|
-
command: ["bash", "-c", bundlingCommands],
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
this.authorizer = new lambda.Function(scope, "WebhookAuthorizerFunction", {
|
|
126
|
-
runtime: lambda.Runtime.PYTHON_3_11,
|
|
127
|
-
handler: "index.handler",
|
|
128
|
-
memorySize: 128,
|
|
129
|
-
timeout: cdk.Duration.seconds(10),
|
|
130
|
-
architecture: lambda.Architecture.X86_64,
|
|
131
|
-
description: "Benchling webhook signature verification (defense-in-depth)",
|
|
132
|
-
environment: {
|
|
133
|
-
BENCHLING_SECRET_ARN: benchlingSecretArn,
|
|
134
|
-
},
|
|
135
|
-
code: authorizerCode,
|
|
136
|
-
logGroup: this.authorizerLogGroup,
|
|
137
|
-
});
|
|
138
|
-
this.authorizer.addToRolePolicy(new iam.PolicyStatement({
|
|
139
|
-
actions: ["secretsmanager:GetSecretValue"],
|
|
140
|
-
resources: [benchlingSecretArn],
|
|
141
|
-
}));
|
|
142
|
-
// Create REST API first (needed for proper authorizer permissions)
|
|
143
|
-
this.api = new apigateway.RestApi(scope, "BenchlingWebhookRestAPI", {
|
|
144
|
-
restApiName: "BenchlingWebhookRestAPI",
|
|
145
|
-
description: "REST API for Benchling webhook integration with IP whitelisting (v1.0.0+)",
|
|
146
|
-
policy: resourcePolicy,
|
|
147
|
-
deployOptions: {
|
|
148
|
-
stageName: "prod",
|
|
149
|
-
accessLogDestination: new apigateway.LogGroupLogDestination(this.logGroup),
|
|
150
|
-
accessLogFormat: apigateway.AccessLogFormat.jsonWithStandardFields({
|
|
151
|
-
caller: true,
|
|
152
|
-
httpMethod: true,
|
|
153
|
-
ip: true,
|
|
154
|
-
protocol: true,
|
|
155
|
-
requestTime: true,
|
|
156
|
-
resourcePath: true,
|
|
157
|
-
responseLength: true,
|
|
158
|
-
status: true,
|
|
159
|
-
user: true,
|
|
160
|
-
}),
|
|
161
|
-
loggingLevel: apigateway.MethodLoggingLevel.INFO,
|
|
162
|
-
dataTraceEnabled: true,
|
|
163
|
-
},
|
|
164
|
-
endpointConfiguration: {
|
|
165
|
-
types: [apigateway.EndpointType.REGIONAL],
|
|
166
|
-
},
|
|
167
|
-
});
|
|
168
|
-
// Create authorizer AFTER API is created (for proper source ARN permissions)
|
|
169
|
-
const requestAuthorizer = verificationEnabled
|
|
170
|
-
? new apigateway.RequestAuthorizer(scope, "WebhookRequestAuthorizer", {
|
|
171
|
-
handler: this.authorizer,
|
|
172
|
-
identitySources: [
|
|
173
|
-
apigateway.IdentitySource.header("webhook-id"),
|
|
174
|
-
apigateway.IdentitySource.header("webhook-signature"),
|
|
175
|
-
apigateway.IdentitySource.header("webhook-timestamp"),
|
|
176
|
-
],
|
|
177
|
-
resultsCacheTtl: cdk.Duration.seconds(0),
|
|
178
|
-
})
|
|
179
|
-
: undefined;
|
|
180
|
-
// Grant API Gateway permission to invoke Lambda authorizer from any method
|
|
181
|
-
// The CDK RequestAuthorizer grants permission only for /authorizers/{id},
|
|
182
|
-
// but API Gateway invokes from /{stage}/{method}/{path}, so we add explicit permission
|
|
183
|
-
if (verificationEnabled && this.authorizer) {
|
|
184
|
-
this.authorizer.addPermission("ApiGatewayInvokePermission", {
|
|
185
|
-
principal: new iam.ServicePrincipal("apigateway.amazonaws.com"),
|
|
186
|
-
action: "lambda:InvokeFunction",
|
|
187
|
-
sourceArn: this.api.arnForExecuteApi("*", "/*", "*"),
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
const createIntegration = (path) => new apigateway.Integration({
|
|
191
|
-
type: apigateway.IntegrationType.HTTP_PROXY,
|
|
192
|
-
integrationHttpMethod: "ANY",
|
|
193
|
-
uri: `http://${this.nlb.loadBalancerDnsName}:80${path}`,
|
|
194
|
-
options: {
|
|
195
|
-
connectionType: apigateway.ConnectionType.VPC_LINK,
|
|
196
|
-
vpcLink: this.vpcLink,
|
|
197
|
-
},
|
|
198
|
-
});
|
|
199
|
-
const webhookMethodOptions = requestAuthorizer
|
|
200
|
-
? {
|
|
201
|
-
authorizer: requestAuthorizer,
|
|
202
|
-
authorizationType: apigateway.AuthorizationType.CUSTOM,
|
|
203
|
-
}
|
|
204
|
-
: undefined;
|
|
205
|
-
// Webhook endpoints secured by Lambda authorizer
|
|
206
|
-
const eventResource = this.api.root.addResource("event");
|
|
207
|
-
eventResource.addMethod("ANY", createIntegration("/event"), webhookMethodOptions);
|
|
208
|
-
const lifecycleResource = this.api.root.addResource("lifecycle");
|
|
209
|
-
lifecycleResource.addMethod("ANY", createIntegration("/lifecycle"), webhookMethodOptions);
|
|
210
|
-
const canvasResource = this.api.root.addResource("canvas");
|
|
211
|
-
canvasResource.addMethod("ANY", createIntegration("/canvas"), webhookMethodOptions);
|
|
212
|
-
// Health endpoints remain unauthenticated
|
|
213
|
-
const healthResource = this.api.root.addResource("health");
|
|
214
|
-
healthResource.addMethod("GET", createIntegration("/health"));
|
|
215
|
-
healthResource.addResource("ready").addMethod("GET", createIntegration("/health/ready"));
|
|
216
|
-
healthResource.addResource("live").addMethod("GET", createIntegration("/health/live"));
|
|
217
|
-
// Output IP filtering status
|
|
218
|
-
if (ipAllowList.length > 0) {
|
|
219
|
-
console.log(`IP Whitelisting enabled: ${ipAllowList.length} CIDR blocks`);
|
|
220
|
-
ipAllowList.forEach((ip) => console.log(` - ${ip}`));
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
console.log("IP Whitelisting disabled: all IPs allowed");
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Build IAM resource policy for IP whitelisting
|
|
228
|
-
*
|
|
229
|
-
* If ipAllowList is empty, allow all IPs.
|
|
230
|
-
* Otherwise, only allow requests from specified IP addresses/CIDR blocks.
|
|
231
|
-
*/
|
|
232
|
-
buildResourcePolicy(ipAllowList) {
|
|
233
|
-
if (ipAllowList.length === 0) {
|
|
234
|
-
// No IP filtering - allow all
|
|
235
|
-
return undefined;
|
|
236
|
-
}
|
|
237
|
-
return new iam.PolicyDocument({
|
|
238
|
-
statements: [
|
|
239
|
-
// Allow requests from whitelisted IPs
|
|
240
|
-
new iam.PolicyStatement({
|
|
241
|
-
effect: iam.Effect.ALLOW,
|
|
242
|
-
principals: [new iam.AnyPrincipal()],
|
|
243
|
-
actions: ["execute-api:Invoke"],
|
|
244
|
-
resources: ["execute-api:/*"],
|
|
245
|
-
conditions: {
|
|
246
|
-
IpAddress: {
|
|
247
|
-
"aws:SourceIp": ipAllowList,
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
}),
|
|
251
|
-
// Explicitly deny requests from non-whitelisted IPs
|
|
252
|
-
new iam.PolicyStatement({
|
|
253
|
-
effect: iam.Effect.DENY,
|
|
254
|
-
principals: [new iam.AnyPrincipal()],
|
|
255
|
-
actions: ["execute-api:Invoke"],
|
|
256
|
-
resources: ["execute-api:/*"],
|
|
257
|
-
conditions: {
|
|
258
|
-
NotIpAddress: {
|
|
259
|
-
"aws:SourceIp": ipAllowList,
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
}),
|
|
263
|
-
],
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
exports.RestApiGateway = RestApiGateway;
|
|
268
|
-
//# sourceMappingURL=rest-api-gateway.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rest-api-gateway.js","sourceRoot":"","sources":["../../lib/rest-api-gateway.ts"],"names":[],"mappings":"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"}
|