Skip to content

Commit c1dc64c

Browse files
committed
Use Bun runtime and relax gRPC TLS verification
1 parent 2d44a7d commit c1dc64c

2 files changed

Lines changed: 13 additions & 11 deletions

File tree

apps/api/Dockerfile

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,11 @@ COPY . .
2323
RUN bun run --filter @sandchest/contract build && \
2424
bun run --filter @sandchest/api build
2525

26-
# Grab the Node.js binary for the runtime stage
27-
FROM node:22-slim AS node-bin
28-
2926
FROM oven/bun:1.3.6-slim
3027
WORKDIR /app
3128

3229
ENV NODE_ENV=production
3330

34-
# Use Node.js runtime instead of Bun for @grpc/grpc-js TLS compatibility.
35-
# Bun's tls.connect polyfill doesn't properly handle secureContext with custom
36-
# CA certificates when upgrading existing sockets, causing gRPC mTLS to fail
37-
# with "unable to verify the first certificate".
38-
COPY --from=node-bin /usr/local/bin/node /usr/local/bin/node
39-
4031
COPY package.json bun.lock ./
4132
COPY apps/api/package.json apps/api/
4233
COPY apps/admin/package.json apps/admin/
@@ -59,4 +50,4 @@ COPY --from=build /app/packages/contract/dist packages/contract/dist
5950
COPY --from=build /app/packages/db/src packages/db/src
6051

6152
EXPOSE 3001
62-
CMD ["node", "apps/api/dist/index.js"]
53+
CMD ["bun", "run", "apps/api/dist/index.js"]

apps/api/src/services/node-client.live.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,18 @@ export function createNodeClientLayer(config: NodeGrpcConfig): Layer.Layer<NodeC
250250
const key = config.keyPem ? Buffer.from(config.keyPem) : readFileSync(config.keyPath!)
251251
const cert = config.certPem ? Buffer.from(config.certPem) : readFileSync(config.certPath!)
252252

253-
const credentials = ChannelCredentials.createSsl(ca, key, cert)
253+
yield* Effect.log(`gRPC mTLS: ca=${ca.length}B key=${key.length}B cert=${cert.length}B target=${config.address}`)
254+
255+
// Bun's tls.connect polyfill does not properly apply custom CA
256+
// certificates from secureContext when upgrading an existing TCP
257+
// socket to TLS (the pattern @grpc/grpc-js uses). This causes
258+
// "unable to verify the first certificate" even with valid certs.
259+
// Workaround: skip client-side server cert verification. The server
260+
// still verifies our client cert (mTLS), and we connect to a known
261+
// IP we control, so MITM risk is minimal.
262+
const credentials = ChannelCredentials.createSsl(ca, key, cert, {
263+
rejectUnauthorized: false,
264+
})
254265
const channel = createChannel(config.address, credentials)
255266
const nodeIdBytes = hexToBytes(config.nodeId)
256267

0 commit comments

Comments
 (0)