Skip to content

Commit 8cc5864

Browse files
authored
Add JWKS generation to both dev and prod Docker setups (#433)
1 parent e68eff4 commit 8cc5864

File tree

7 files changed

+123
-5
lines changed

7 files changed

+123
-5
lines changed

query-connector/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ certificates
88
/playwright/.cache/
99
/coverage
1010
report.json
11-
.tool-versions
11+
.tool-versions
12+
keys/

query-connector/Dockerfile

+11-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ FROM node:22-alpine AS base
33
FROM base AS installer
44

55
RUN apk update
6-
RUN apk add --no-cache libc6-compat
7-
RUN apk add --no-cache bash curl
6+
RUN apk add --no-cache libc6-compat bash curl git go
87

98
WORKDIR /app
109
COPY . .
@@ -24,11 +23,16 @@ ENV NEXT_TELEMETRY_DISABLED=1
2423
RUN npm ci
2524
RUN npm run build
2625

26+
# Download jwksetinfer tool
27+
RUN git clone https://github.com/MicahParks/jwkset.git \
28+
&& cd jwkset/cmd/jwksetinfer \
29+
&& go build
30+
2731
# Final stage for running the app
2832
FROM base AS runner
2933
WORKDIR /app
3034

31-
RUN apk add --no-cache bash openjdk17-jre
35+
RUN apk add --no-cache bash openjdk17-jre openssl uuidgen jq
3236

3337
# Copy Flyway from the installer stage
3438
COPY --from=installer /flyway /flyway
@@ -50,11 +54,13 @@ COPY --from=installer /app/package.json .
5054
COPY --from=installer /app/flyway/conf/flyway.conf ../flyway/conf/flyway.conf
5155
COPY --from=installer /app/flyway/sql ../flyway/sql
5256
COPY --from=installer /app/src/app/assets ./.next/server/app/assets
57+
COPY --from=installer /app/jwkset/cmd/jwksetinfer/jwksetinfer /usr/local/bin/jwksetinfer
5358

5459
# Automatically leverage output traces to reduce image size
5560
COPY --from=installer --chown=nextjs:nodejs /app/.next/standalone ./
5661
COPY --from=installer --chown=nextjs:nodejs /app/.next/static ./.next/static
5762
COPY --from=installer --chown=nextjs:nodejs /app/public ./public
63+
COPY --from=installer --chown=nextjs:nodejs /app/start.sh ./start.sh
5864
RUN ls -R
5965
# Set environment variables for Flyway and Node.js telemetry
6066
ENV NEXT_TELEMETRY_DISABLED=1
@@ -64,4 +70,5 @@ ENV JAVA_HOME=/usr/lib/jvm/default-jvm
6470
# Add the OpenJDK to the PATH so the java command is available for Flways
6571
ENV PATH=$JAVA_HOME/bin:$PATH
6672

67-
CMD ["sh", "-c","flyway -configFiles=../flyway/conf/flyway.conf -schemas=public -connectRetries=60 migrate && echo done with flyway && node server.js"]
73+
ENTRYPOINT ["/bin/bash"]
74+
CMD ["/app/start.sh"]
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
FROM alpine:latest
2+
3+
# Install required packages
4+
RUN apk update && apk add --no-cache \
5+
bash \
6+
openssl \
7+
uuidgen \
8+
jq \
9+
git \
10+
go
11+
12+
# Set up work directory
13+
WORKDIR /app
14+
15+
# Download and build jwksetinfer tool
16+
RUN git clone https://github.com/MicahParks/jwkset.git && \
17+
cd jwkset/cmd/jwksetinfer && \
18+
go build && \
19+
mv jwksetinfer /usr/local/bin/ && \
20+
chmod +x /usr/local/bin/jwksetinfer && \
21+
cd / && \
22+
rm -rf /app/jwkset
23+
24+
# Set entrypoint to bash to keep container running or execute scripts
25+
ENTRYPOINT ["/bin/bash"]
26+
27+
# Default command (can be overridden in docker-compose)
28+
CMD ["/app/generate_jwks.sh"]

query-connector/docker-compose-dev.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,14 @@ services:
101101
flyway:
102102
condition: service_completed_successfully
103103

104+
# JWKS key generator
105+
jwks-generator:
106+
build:
107+
context: .
108+
dockerfile: Dockerfile.jwks-seeder
109+
volumes:
110+
- "./keys:/app/keys"
111+
- "./generate_jwks.sh:/app/generate_jwks.sh"
112+
104113
volumes:
105114
aidbox_pg_data:

query-connector/generate_jwks.sh

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
# Check if keys/jwks.json exists
4+
if [ -f keys/jwks.json ]; then
5+
echo "JWKS already exists. Skipping key generation."
6+
exit 0
7+
fi
8+
9+
mkdir -p keys
10+
11+
# Generate ECDSA key pair and JWKS for SMART on FHIR
12+
set -e
13+
if [ ! -f keys/ec384-private.pem ]; then
14+
echo "Generating new ECDSA key pair..."
15+
16+
# Generate ECDSA P-384 key pair
17+
openssl ecparam -name secp384r1 -genkey -noout -out keys/ec384-private.pem
18+
openssl ec -in keys/ec384-private.pem -pubout -out keys/ec384-public.pem
19+
20+
# Generate JWKS
21+
jwksetinfer keys/ec384-private.pem >keys/jwks.json
22+
23+
# Generate a UUID and replace kid in jwks.json using jq
24+
KID=$(uuidgen)
25+
jq --arg KID "$KID" '.keys[0].kid = $KID' keys/jwks.json >keys/jwks.json.tmp
26+
27+
# Add algorithm to jwks.json
28+
jq '.keys[0].alg = "ES384"' keys/jwks.json.tmp >keys/jwks.json
29+
30+
# Fix permissions
31+
chmod 600 keys/ec384-private.pem
32+
chmod 644 keys/ec384-public.pem keys/jwks.json
33+
34+
echo "Key generation complete."
35+
else
36+
echo "Using existing keys."
37+
fi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { NextResponse } from "next/server";
2+
import fs from "fs";
3+
import path from "path";
4+
5+
export async function GET() {
6+
try {
7+
// Path to the JWKS file
8+
const jwksPath = path.join(process.cwd(), "keys", "jwks.json");
9+
10+
// Read the JWKS file
11+
const jwksContent = fs.readFileSync(jwksPath, "utf-8");
12+
const jwks = JSON.parse(jwksContent);
13+
14+
// Return the JWKS as JSON
15+
return NextResponse.json(jwks, {
16+
headers: {
17+
"Cache-Control": "public, max-age=3600", // Cache for 1 hour
18+
"Content-Type": "application/json",
19+
},
20+
});
21+
} catch (error) {
22+
console.error("Error serving JWKS:", error);
23+
return NextResponse.json({ error: "Failed to load JWKS" }, { status: 500 });
24+
}
25+
}

query-connector/start.sh

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
# Run flyway migrations
4+
flyway -configFiles=/flyway/conf/flyway.conf -schemas=public -connectRetries=60 migrate
5+
echo "Flyway migrations complete."
6+
7+
# Generate JWKS
8+
./generate_jwks.sh
9+
10+
# Start the server
11+
node server.js

0 commit comments

Comments
 (0)