Skip to content

Commit f36ebaa

Browse files
authored
feat: add stac-auth-proxy construct (#171)
1 parent 6e14c16 commit f36ebaa

File tree

6 files changed

+170
-0
lines changed

6 files changed

+170
-0
lines changed

lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from "./ingestor-api";
44
export * from "./lambda-api-gateway-private";
55
export * from "./lambda-api-gateway";
66
export * from "./stac-api";
7+
export * from "./stac-auth-proxy";
78
export * from "./stac-browser";
89
export * from "./stac-loader";
910
export * from "./stactools-item-generator";

lib/stac-auth-proxy/index.ts

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import * as cdk from "aws-cdk-lib";
2+
import * as ec2 from "aws-cdk-lib/aws-ec2";
3+
import * as lambda from "aws-cdk-lib/aws-lambda";
4+
import * as apigatewayv2 from "aws-cdk-lib/aws-apigatewayv2";
5+
import { Construct } from "constructs";
6+
import { LambdaApiGateway } from "../lambda-api-gateway";
7+
import { CustomLambdaFunctionProps } from "../utils";
8+
import * as path from "path";
9+
10+
export class StacAuthProxyLambdaRuntime extends Construct {
11+
public readonly lambdaFunction: lambda.Function;
12+
13+
constructor(
14+
scope: Construct,
15+
id: string,
16+
props: StacAuthProxyLambdaRuntimeProps
17+
) {
18+
super(scope, id);
19+
20+
this.lambdaFunction = new lambda.Function(this, "lambda", {
21+
runtime: lambda.Runtime.PYTHON_3_13,
22+
handler: "handler.handler",
23+
memorySize: 8192,
24+
logRetention: cdk.aws_logs.RetentionDays.ONE_WEEK,
25+
timeout: cdk.Duration.seconds(30),
26+
code: lambda.Code.fromDockerBuild(path.join(__dirname, ".."), {
27+
file: "stac-auth-proxy/runtime/Dockerfile",
28+
buildArgs: { PYTHON_VERSION: "3.13" },
29+
}),
30+
vpc: props.vpc,
31+
vpcSubnets: props.subnetSelection,
32+
allowPublicSubnet: true,
33+
environment: {
34+
// stac-auth-proxy config
35+
UPSTREAM_URL: props.upstreamUrl,
36+
OIDC_DISCOVERY_URL: props.oidcDiscoveryUrl,
37+
38+
// swagger-ui config
39+
OPENAPI_SPEC_ENDPOINT: "/api",
40+
SWAGGER_UI_ENDPOINT: "/api.html",
41+
SWAGGER_UI_INIT_OAUTH: cdk.Stack.of(this).toJsonString({
42+
clientId: props.stacApiClientId,
43+
usePkceWithAuthorizationCodeGrant: true,
44+
}),
45+
46+
// customized settings
47+
...props.apiEnv,
48+
},
49+
// overwrites defaults with user-provided configurable properties
50+
...props.lambdaFunctionOptions,
51+
});
52+
}
53+
}
54+
55+
export interface StacAuthProxyLambdaRuntimeProps {
56+
/**
57+
* URL to upstream STAC API.
58+
*/
59+
readonly upstreamUrl: string;
60+
61+
/**
62+
* URL to OIDC Discovery Endpoint.
63+
*/
64+
readonly oidcDiscoveryUrl: string;
65+
66+
/**
67+
* OAuth Client ID for Swagger UI.
68+
*/
69+
readonly stacApiClientId?: string;
70+
71+
/**
72+
* VPC into which the lambda should be deployed.
73+
*/
74+
readonly vpc?: ec2.IVpc;
75+
76+
/**
77+
* Subnet into which the lambda should be deployed.
78+
*/
79+
readonly subnetSelection?: ec2.SubnetSelection;
80+
81+
/**
82+
* Customized environment variables to send to stac-auth-proxy runtime.
83+
* https://github.com/developmentseed/stac-auth-proxy/?tab=readme-ov-file#configuration
84+
*/
85+
readonly apiEnv?: Record<string, string>;
86+
87+
/**
88+
* Can be used to override the default lambda function properties.
89+
*
90+
* @default - defined in the construct.
91+
*/
92+
readonly lambdaFunctionOptions?: CustomLambdaFunctionProps;
93+
}
94+
95+
export class StacAuthProxyLambda extends Construct {
96+
/**
97+
* URL for the STAC API.
98+
*/
99+
readonly url: string;
100+
101+
/**
102+
* Lambda function for the STAC API.
103+
*/
104+
readonly lambdaFunction: lambda.Function;
105+
106+
constructor(scope: Construct, id: string, props: StacAuthProxyLambdaProps) {
107+
super(scope, id);
108+
109+
const { domainName, ...runtimeProps } = props;
110+
111+
const runtime = new StacAuthProxyLambdaRuntime(
112+
this,
113+
"runtime",
114+
runtimeProps
115+
);
116+
this.lambdaFunction = runtime.lambdaFunction;
117+
118+
const { api } = new LambdaApiGateway(this, "stac-auth-proxy", {
119+
lambdaFunction: runtime.lambdaFunction,
120+
domainName,
121+
});
122+
123+
this.url = api.url!;
124+
125+
new cdk.CfnOutput(this, "stac-auth-proxy-output", {
126+
exportName: `${cdk.Stack.of(this).stackName}-stac-auth-proxy-url`,
127+
value: this.url,
128+
});
129+
}
130+
}
131+
132+
export interface StacAuthProxyLambdaProps
133+
extends StacAuthProxyLambdaRuntimeProps {
134+
/**
135+
* Domain Name for the STAC API. If defined, will create the domain name and integrate it with the STAC API.
136+
*
137+
* @default - undefined
138+
*/
139+
readonly domainName?: apigatewayv2.IDomainName;
140+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
ARG PYTHON_VERSION
2+
FROM --platform=linux/amd64 public.ecr.aws/lambda/python:${PYTHON_VERSION}
3+
4+
WORKDIR /tmp
5+
RUN python -m pip install pip -U
6+
7+
COPY stac-auth-proxy/runtime/requirements.txt requirements.txt
8+
RUN python -m pip install -r requirements.txt "mangum>=0.14,<0.15" -t /asset
9+
10+
RUN mkdir -p /asset/src
11+
COPY stac-auth-proxy/runtime/src/*.py /asset/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
stac-auth-proxy>=0.6,<1

lib/stac-auth-proxy/runtime/src/__init__.py

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""
2+
Handler for AWS Lambda.
3+
"""
4+
5+
import asyncio
6+
import os
7+
8+
from mangum import Mangum
9+
from stac_auth_proxy import create_app
10+
11+
app = create_app()
12+
handler = Mangum(app, lifespan="off")
13+
14+
15+
if "AWS_EXECUTION_ENV" in os.environ:
16+
loop = asyncio.get_event_loop()
17+
loop.run_until_complete(app.router.startup())

0 commit comments

Comments
 (0)