Skip to content

feat: adds support for jwt auth to provider-proxy#1963

Merged
stalniy merged 2 commits intomainfrom
feat/provider-proxy-jwt
Sep 25, 2025
Merged

feat: adds support for jwt auth to provider-proxy#1963
stalniy merged 2 commits intomainfrom
feat/provider-proxy-jwt

Conversation

@stalniy
Copy link
Contributor

@stalniy stalniy commented Sep 24, 2025

Why

#1952

Summary by CodeRabbit

  • New Features

    • Added provider authentication via mTLS client certificates and JWT tokens for both HTTP and WebSocket proxying.
    • Unified request/message schema with auth and network fields; legacy payloads are auto-normalized.
  • Deprecations

    • Deprecated chainNetwork, certPem, and keyPem fields. Use network and auth instead.
  • Tests

    • Added functional tests covering mTLS and JWT flows for HTTP and WebSocket.
  • Chores

    • Updated build configuration for reliability.
    • Added authentication-related dependencies.

@stalniy stalniy requested a review from a team as a code owner September 24, 2025 12:26
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 24, 2025

Walkthrough

Refactors provider authentication across HTTP and WebSocket paths by introducing a unified auth model (mtls/jwt) and network field in schema, replacing legacy certificate fields. Updates ProviderProxy connection options and agent management, adjusts route and WS flows, revises imports/paths, augments tests for mtls/jwt, and tweaks build/dependencies.

Changes

Cohort / File(s) Summary
Build & dependencies
apps/provider-proxy/package.json
Build script switches to direct tsc and adds esbuild --packages=external. Adds dependency @akashnetwork/jwt and devDependency @cosmjs/proto-signing.
Schema and auth utilities
apps/provider-proxy/src/utils/schema.ts
Introduces providerRequestSchema with auth discriminated union (mtls/jwt) and network; adds addProviderAuthValidation; deprecates chainNetwork/certPem/keyPem; integrates JWT validation. Removes addCertificateValidation.
HTTP route: provider proxy
apps/provider-proxy/src/routes/proxyProviderRequest.ts
Replaces certificate validation with addProviderAuthValidation; payload now includes auth and network; uses ctx.req.valid; passes auth to ProviderProxy.connect; updates error paths.
Service: ProviderProxy refactor
apps/provider-proxy/src/services/ProviderProxy.ts
Expands ProxyConnectOptions to include method, auth, body, headers, network, timeout, providerAddress, signal. Adds request options builder and https agent caching keyed by auth; supports mtls and jwt; removes TLSChainAgentOptions and genAgentsCacheKey. Adjusts imports.
Service: WebSocketServer flow
apps/provider-proxy/src/services/WebsocketServer.ts
Switches to auth-based validation and network usage; adds WebSocketDetails with verification states; introduces connectWebSocket helper supporting mtls/jwt; updates linking and verification logic; revises message schema handling.
CertificateValidator path adjustments
apps/provider-proxy/src/container.ts, apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.ts, apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts
Normalizes import paths for CertificateValidator and related utilities/types; no functional changes.
Test setup server
apps/provider-proxy/test/setup/providerServer.ts
Adds requireClientCertificate option; adjusts HTTPS server options for client cert handling; extends onConnection signature to include IncomingMessage.
Functional tests
apps/provider-proxy/test/functional/provider-proxy-http.spec.ts, apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
Adds MTLS and JWT tests for HTTP and WS; updates message/payload shapes (network, auth nesting); imports JwtToken and wallet utilities; adjusts error expectations.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant Route as HTTP Route
  participant Schema as addProviderAuthValidation
  participant Proxy as ProviderProxy
  participant Provider as Provider API

  Client->>Route: POST /proxy { method, url, body, network, providerAddress, auth? }
  Route->>Schema: validate payload (auth mtls/jwt or legacy)
  Schema-->>Route: normalized { ... , auth?, network }
  Route->>Proxy: connect({ method, auth, body, headers, network, timeout, providerAddress })
  Proxy->>Proxy: build requestOptions + agentCacheKey
  alt auth.type == "mtls"
    Proxy->>Proxy: getHttpsAgent(cert,key,servername="")
  else auth.type == "jwt"
    Proxy->>Proxy: set Authorization: Bearer <token>
    Proxy->>Proxy: getHttpsAgent(default)
  end
  Proxy->>Provider: HTTPS request
  Provider-->>Proxy: Response (socket, headers)
  alt socket.authorized or cert validated
    Proxy-->>Route: stream response
  else invalid cert
    Proxy->>Proxy: drop cached agent
    Proxy-->>Route: error
  end
  Route-->>Client: response / error
Loading
sequenceDiagram
  autonumber
  actor Client
  participant WSS as WebsocketServer
  participant Conn as connectWebSocket
  participant Provider as Provider WS

  Client->>WSS: message { url, network, providerAddress, auth?, ... }
  WSS->>WSS: validate via MESSAGE_SCHEMA (addProviderAuthValidation)
  WSS->>Conn: connect(url, { network, auth })
  alt auth.type == "mtls"
    Conn->>Provider: WS with TLS cert/key
  else auth.type == "jwt"
    Conn->>Provider: WS with Authorization: Bearer <token>
  else no auth
    Conn->>Provider: WS default
  end
  Conn-->>WSS: providerSocket (verification=in-progress)
  WSS->>WSS: verify (mtls cert or token flow)
  alt verified
    WSS->>WSS: mark verification=finished
    WSS-->>Client: "verified"
    WSS-->>Client: proxy stream
  else failed
    WSS->>WSS: mark verification=failed
    WSS-->>Client: error
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • ygrishajev
  • baktun14

Poem

I hop between sockets, nimble and bright,
Trading certs for tokens in the hush of night.
MTLS or JWT—two paths, one dance,
Packets twirl onward, given half a chance.
With whiskered logs and ears alert—
Proxy perfected. No dropped dessert. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately summarizes the primary change: adding JWT authentication support to the provider-proxy; it is a single concise sentence and directly reflects the PR objectives and the file-level changes that introduce JWT handling. It avoids noise and is clear for teammates scanning the history.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/provider-proxy-jwt

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 904153d and 4fe95b0.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • apps/provider-proxy/package.json (3 hunks)
  • apps/provider-proxy/src/container.ts (1 hunks)
  • apps/provider-proxy/src/routes/proxyProviderRequest.ts (4 hunks)
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts (1 hunks)
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.ts (1 hunks)
  • apps/provider-proxy/src/services/ProviderProxy.ts (6 hunks)
  • apps/provider-proxy/src/services/WebsocketServer.ts (13 hunks)
  • apps/provider-proxy/src/utils/schema.ts (2 hunks)
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (4 hunks)
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts (3 hunks)
  • apps/provider-proxy/test/setup/providerServer.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.ts
  • apps/provider-proxy/test/setup/providerServer.ts
  • apps/provider-proxy/src/container.ts
  • apps/provider-proxy/package.json
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/provider-proxy/src/utils/schema.ts
  • apps/provider-proxy/src/routes/proxyProviderRequest.ts
  • apps/provider-proxy/src/services/WebsocketServer.ts
  • apps/provider-proxy/src/services/ProviderProxy.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/provider-proxy/src/utils/schema.ts
  • apps/provider-proxy/src/routes/proxyProviderRequest.ts
  • apps/provider-proxy/src/services/WebsocketServer.ts
  • apps/provider-proxy/src/services/ProviderProxy.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
🧠 Learnings (1)
📚 Learning: 2025-07-21T08:24:27.953Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/query-by-in-tests.mdc:0-0
Timestamp: 2025-07-21T08:24:27.953Z
Learning: Applies to apps/{deploy-web,provider-console}/**/*.spec.tsx : Use `queryBy` methods instead of `getBy` methods in test expectations in `.spec.tsx` files

Applied to files:

  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
🧬 Code graph analysis (6)
apps/provider-proxy/src/utils/schema.ts (3)
packages/net/src/index.ts (1)
  • netConfig (3-3)
apps/provider-proxy/src/utils/isValidBech32.ts (1)
  • isValidBech32Address (3-10)
apps/provider-proxy/src/utils/validateClientCertificateAttrs.ts (1)
  • validateClientCertificateAttrs (6-11)
apps/provider-proxy/src/routes/proxyProviderRequest.ts (1)
apps/provider-proxy/src/utils/schema.ts (2)
  • addProviderAuthValidation (41-82)
  • providerRequestSchema (9-32)
apps/provider-proxy/src/services/WebsocketServer.ts (4)
apps/provider-proxy/src/utils/schema.ts (2)
  • addProviderAuthValidation (41-82)
  • providerRequestSchema (9-32)
apps/provider-proxy/src/utils/telemetry.ts (1)
  • propagateTracingContext (9-12)
apps/provider-proxy/src/services/WebsocketStats.ts (1)
  • ClientWebSocketStats (22-78)
packages/net/src/NetConfig/NetConfig.ts (1)
  • SupportedChainNetworks (3-3)
apps/provider-proxy/src/services/ProviderProxy.ts (1)
apps/provider-proxy/src/utils/schema.ts (1)
  • providerRequestSchema (9-32)
apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (4)
apps/provider-proxy/test/setup/chainApiServer.ts (2)
  • generateBech32 (61-63)
  • startChainApiServer (13-50)
apps/provider-proxy/test/seeders/createX509CertPair.ts (1)
  • createX509CertPair (4-26)
apps/provider-proxy/test/setup/providerServer.ts (1)
  • startProviderServer (14-71)
apps/provider-proxy/test/setup/proxyServer.ts (1)
  • request (15-27)
apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts (4)
apps/provider-proxy/test/setup/proxyServer.ts (1)
  • startServer (6-9)
apps/provider-proxy/test/setup/chainApiServer.ts (2)
  • generateBech32 (61-63)
  • startChainApiServer (13-50)
apps/provider-proxy/test/seeders/createX509CertPair.ts (1)
  • createX509CertPair (4-26)
apps/provider-proxy/test/setup/providerServer.ts (1)
  • startProviderServer (14-71)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: validate (apps/log-collector) / validate-unsafe
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
🔇 Additional comments (30)
apps/provider-proxy/src/utils/schema.ts (4)

34-36: Fix JwtToken constructor and use proper type imports.

The use of any violates coding guidelines, and the eslint disable should be removed.

Apply the fix suggested in the past review comment, or use a more specific approach:

-// we need just validation and decoding that's why signer is not provided
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const jwtTokenManager = new JwtToken({} as any);
+// we need just validation and decoding that's why signer is not provided
+const jwtTokenManager = new JwtToken({} as ConstructorParameters<typeof JwtToken>[0]);

41-41: Use ZodTypeAny instead of any for generic constraint.

Apply this diff to use the proper Zod type:

-export function addProviderAuthValidation<T extends z.ZodType<any>>(schema: T): z.ZodEffects<T> {
+export function addProviderAuthValidation<T extends z.ZodTypeAny>(schema: T): z.ZodEffects<T> {

54-66: MTLS validation should require both certPem and keyPem.

The current validation only checks certPem but doesn't validate that keyPem is present for MTLS authentication. This could allow incomplete MTLS configurations to pass validation.

Apply the fix suggested in the past review comment to validate both fields:

-      if (data.auth?.type === "mtls" && data.auth.certPem) {
-        const validationResult = validateClientCertificateAttrs(data.auth.certPem);
-        if (!validationResult.ok) {
-          ctx.addIssue({
-            code: z.ZodIssueCode.custom,
-            message: "is not a valid certificate",
-            path: ["auth", "certPem"],
-            params: {
-              reason: validationResult.code
-            }
-          });
-        }
-      }
+      if (data.auth?.type === "mtls") {
+        if (!data.auth.certPem) {
+          ctx.addIssue({
+            code: z.ZodIssueCode.custom,
+            message: "certPem is required",
+            path: ["auth", "certPem"]
+          });
+        } else {
+          const validationResult = validateClientCertificateAttrs(data.auth.certPem);
+          if (!validationResult.ok) {
+            ctx.addIssue({
+              code: z.ZodIssueCode.custom,
+              message: "is not a valid certificate",
+              path: ["auth", "certPem"],
+              params: { reason: validationResult.code }
+            });
+          }
+        }
+        if (!data.auth.keyPem) {
+          ctx.addIssue({
+            code: z.ZodIssueCode.custom,
+            message: "keyPem is required",
+            path: ["auth", "keyPem"]
+          });
+        }
+      }

13-20: Require non-empty JWT/MTLS credential strings at schema level.

Empty strings currently pass validation but would fail at runtime. Add minimum length validation to catch this earlier.

Apply this diff to require non-empty strings:

       z.object({
         type: z.literal("mtls"),
-        certPem: z.string(),
-        keyPem: z.string()
+        certPem: z.string().min(1, "certPem is required"),
+        keyPem: z.string().min(1, "keyPem is required")
       }),
       z.object({
         type: z.literal("jwt"),
-        token: z.string()
+        token: z.string().min(1, "token is required")
       })

Also apply to the deprecated fields:

-  certPem: z.string().describe('Deprecated certificate. Use mtls auth type  with "auth.certPem" instead.').optional(),
-  keyPem: z.string().describe('Deprecated key. Use mtls auth type  with "auth.keyPem" instead.').optional()
+  certPem: z.string().min(1).describe('Deprecated certificate. Use mtls auth type  with "auth.certPem" instead.').optional(),
+  keyPem: z.string().min(1).describe('Deprecated key. Use mtls auth type  with "auth.keyPem" instead.').optional()

Also applies to: 30-31

apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (3)

1-5: LGTM - Proper imports for JWT and TLS testing.

The new imports support the expanded authentication test scenarios (JWT and MTLS) that align with the updated provider authentication schema.


596-664: LGTM - Comprehensive MTLS authentication test.

The test properly validates both successful MTLS authentication and error handling for invalid certificates. The error path correctly references the new auth structure (["auth", "certPem"]).


666-741: LGTM - Comprehensive JWT authentication test.

Good test coverage for JWT authentication including token creation, validation, and error handling. The test properly uses a test mnemonic and validates the Bearer token format in headers.

apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts (5)

279-291: Avoid 'any' type in test response casting.

Per coding guidelines, replace any with a proper type:

-    const response = (await waitForMessage(ws)) as { errors: any[] };
+    const response = (await waitForMessage(ws)) as {
+      errors: Array<{
+        code: string;
+        message: string;
+        path: (string | number)[];
+        params?: unknown;
+      }>;
+    };

350-362: Avoid 'any' type in JWT test response casting.

Replace any with proper typing:

-    const response = (await waitForMessage(ws)) as { errors: any[] };
+    const response = (await waitForMessage(ws)) as {
+      errors: Array<{
+        code: string;
+        message: string;
+        path: (string | number)[];
+        params?: unknown;
+      }>;
+    };

230-292: LGTM - Well-structured MTLS WebSocket test.

Comprehensive test covering successful MTLS authentication and proper error handling for invalid certificates.


294-363: LGTM - Comprehensive JWT WebSocket test.

Good coverage of JWT authentication flow including token creation with a proper wallet and error handling for invalid tokens.


383-383: Update field name to match new schema.

The message helper correctly updates chainNetwork to network to align with the new provider request schema.

apps/provider-proxy/src/routes/proxyProviderRequest.ts (5)

8-8: LGTM - Updated imports for provider auth validation.

The import change correctly switches from certificate-based validation to the new provider auth validation system.


10-16: LGTM - Updated payload schema with provider auth validation.

The RequestPayload now uses addProviderAuthValidation instead of certificate validation, properly supporting both MTLS and JWT authentication.


56-56: LGTM - Proper request data extraction.

The destructuring correctly extracts auth and other fields from the validated request payload.


72-72: LGTM - Updated provider proxy connection.

The connection now passes a single auth parameter instead of separate certPem/keyPem fields, aligning with the unified authentication model.


123-123: LGTM - Updated error path for auth structure.

The error path correctly references ["auth", "certPem"] instead of just ["certPem"] to match the new nested authentication structure.

apps/provider-proxy/src/services/WebsocketServer.ts (8)

11-11: LGTM - Updated imports for provider auth validation.

The import correctly switches to the new provider auth validation system.


16-31: LGTM - Updated message schema with provider auth validation.

The MESSAGE_SCHEMA properly uses addProviderAuthValidation and the new providerRequestSchema structure.


40-40: LGTM - Enhanced WebSocket details tracking.

The WebSocketDetails interface properly tracks verification state ("in-progress" | "finished" | "failed") for the new auth flow.


135-139: LGTM - Updated attribute tracking for new auth model.

The attributes correctly track the network field and determine authentication status based on the new auth structure (MTLS or JWT).


225-228: LGTM - Updated provider socket creation options.

The socket creation properly passes auth and network parameters instead of the legacy certificate fields.


250-374: LGTM - Comprehensive WebSocket connection logic.

The connectWebSocket method properly handles both MTLS (with cert/key and disabled SNI) and JWT (with Bearer token) authentication methods. The HTTPS agent configuration is appropriate for each auth type.


450-455: LGTM - Updated interface for new auth model.

The CreateProviderSocketOptions interface correctly defines the new auth and network parameters using proper Zod inferred types.


468-471: LGTM - Clear WebSocket verification states.

The WebSocketDetails interface clearly defines the three possible verification states for the authentication flow.

apps/provider-proxy/src/services/ProviderProxy.ts (5)

8-8: Fix invalid Zod type import.

Based on the web search results, Zod uses namespace imports. Fix the import:

-import type z from "zod";
+import type * as z from "zod";

Alternatively, use named imports for specific types if you only need certain Zod types.


119-161: LGTM - Well-structured request options and agent management.

The getRequestOptions method properly handles both MTLS and JWT authentication types. The agent caching with unique keys (including auth hash for MTLS) is a good optimization. The MTLS configuration correctly disables SNI and sets cert/key, while JWT adds the Bearer token header.


45-49: LGTM - Proper CA validation handling.

The early return for CA-validated certificates is correct and maintains the existing optimization for non-self-signed certificates.


163-173: LGTM - Updated interface with comprehensive options.

The ProxyConnectOptions interface properly defines all required parameters for the new authentication model, including method, auth, and other essential fields.


126-126: Request timeout properly applied.

Good that the timeout is now included in the request options to ensure the request-level timeout handler fires correctly.


Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Sep 24, 2025

Codecov Report

❌ Patch coverage is 91.95402% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 45.13%. Comparing base (2b1f0fd) to head (4fe95b0).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...pps/provider-proxy/src/services/WebsocketServer.ts 86.84% 5 Missing ⚠️
apps/provider-proxy/src/services/ProviderProxy.ts 90.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1963      +/-   ##
==========================================
+ Coverage   45.06%   45.13%   +0.06%     
==========================================
  Files         998      998              
  Lines       28170    28210      +40     
  Branches     7372     7382      +10     
==========================================
+ Hits        12695    12732      +37     
- Misses      14350    14372      +22     
+ Partials     1125     1106      -19     
Flag Coverage Δ
api 81.52% <ø> (ø)
deploy-web 23.12% <ø> (ø)
log-collector 75.35% <ø> (ø)
notifications 87.94% <ø> (ø)
provider-console 81.48% <ø> (ø)
provider-proxy 84.98% <91.95%> (+0.51%) ⬆️
Files with missing lines Coverage Δ
apps/provider-proxy/src/container.ts 100.00% <100.00%> (ø)
.../provider-proxy/src/routes/proxyProviderRequest.ts 92.00% <100.00%> (ø)
...vices/CertificateValidator/CertificateValidator.ts 80.95% <100.00%> (ø)
apps/provider-proxy/src/utils/schema.ts 100.00% <100.00%> (+7.14%) ⬆️
apps/provider-proxy/src/services/ProviderProxy.ts 94.28% <90.00%> (-2.39%) ⬇️
...pps/provider-proxy/src/services/WebsocketServer.ts 85.71% <86.84%> (+0.08%) ⬆️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

ygrishajev
ygrishajev previously approved these changes Sep 24, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/provider-proxy/src/routes/proxyProviderRequest.ts (1)

31-38: OpenAPI 400 response schema mismatch (JSON vs text).

The route returns JSON for certain 400 cases (SSL/client cert invalid), but the OpenAPI spec declares only text/plain for 400. This breaks clients relying on the spec.

Apply this diff to add "application/json" to 400 responses:

   responses: {
-      content: {
-        "text/plain": {
-          schema: z.string()
-        }
-      },
+      content: {
+        "text/plain": { schema: z.string() },
+        "application/json": {
+          schema: z.object({
+            error: z.object({
+              code: z.string(),
+              issues: z.array(
+                z.object({
+                  path: z.array(z.union([z.string(), z.number()])),
+                  params: z.record(z.unknown()).optional()
+                })
+              )
+            })
+          })
+        }
+      },
       description: "Returned if it's not possible to establish secure connection with proxied host"
     },

Alternatively, return text consistently for 400 or wrap all 400s as JSON and reflect that in the spec.

Also applies to: 117-132

apps/provider-proxy/src/services/WebsocketServer.ts (1)

237-237: Remove any and correctly build Buffer

Avoid any; parse numbers explicitly to ensure correct byte values.

-    const data = Buffer.from(message.data.split(",") as any);
+    const data = Buffer.from(message.data.split(",").map(n => Number.parseInt(n, 10)));
🧹 Nitpick comments (7)
apps/provider-proxy/package.json (1)

9-9: Pin @akashnetwork/jwt, and verify TypeScript version.

  • Avoid using "*" for dependencies. Pin "@akashnetwork/jwt" to a known compatible version/range to ensure reproducible builds.
  • Confirm that the specified TypeScript version "~5.8.2" exists in your registry. If not, adjust to an available version.

Also, confirm the intent of "--packages=external": the runtime must have deps available in node_modules for prod execution (which seems fine with "start" invoking node on dist).

If helpful, I can scan the repo and PR history to propose an exact version for @akashnetwork/jwt that matches current usage/tests.

Also applies to: 25-25, 44-44

apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.ts (3)

19-20: Typo in instrumentation type name (constructor parameter).

Rename "CertificateValidatorIntrumentation" to "CertificateValidatorInstrumentation" for correctness and consistency.

Apply this diff:

   constructor(
     private readonly now: () => number,
     private readonly providerService: ProviderService,
-    private readonly instrumentation?: CertificateValidatorIntrumentation
+    private readonly instrumentation?: CertificateValidatorInstrumentation
   ) {}

71-82: Fix misspelled interface name; keep a back-compat alias.

The interface is misspelled ("Intrumentation"). Introduce the correctly spelled name and alias the old one.

Apply this diff:

-export interface CertificateValidatorIntrumentation {
+export interface CertificateValidatorInstrumentation {
   onValidationSuccess?(certificate: X509Certificate, network: SupportedChainNetworks, providerAddress: string, now: number): void;
   onInvalidAttrs?(
     certificate: X509Certificate,
     network: SupportedChainNetworks,
     providerAddress: string,
     now: number,
     validationResult: CertValidationResultError
   ): void;
   onUnknownCert?(certificate: X509Certificate, network: SupportedChainNetworks, providerAddress: string): void;
   onInvalidFingerprint?(certificate: X509Certificate, network: SupportedChainNetworks, providerAddress: string, providerCertificate: X509Certificate): void;
 }
+
+// Backward compatibility alias (to avoid breaking imports)
+export type CertificateValidatorIntrumentation = CertificateValidatorInstrumentation;

84-99: Align factory’s return type with corrected interface.

Update the return type of the instrumentation factory to the corrected interface name.

Apply this diff:

-export const createCertificateValidatorInstrumentation = (logger: LoggerService): CertificateValidatorIntrumentation => ({
+export const createCertificateValidatorInstrumentation = (logger: LoggerService): CertificateValidatorInstrumentation => ({
   onValidationSuccess(certificate, network, providerAddress, now) {
     logger.info(`Successfully validated ${certificate.serialNumber} in ${network} for "${providerAddress}" at ${now}`);
   },
   onInvalidAttrs(certificate, network, providerAddress, now, result) {
     logger.warn(`Certificate ${certificate.serialNumber} is invalid in ${network} for "${providerAddress}" because ${result.code} at ${now}`);
   },
apps/provider-proxy/src/services/ProviderProxy.ts (2)

18-20: Agents cache can grow very large

max: 1_000_000 without TTL risks memory pressure. Consider a tighter max and/or TTL based on expected concurrency and session reuse.


61-61: Redundant checks

network and providerAddress are required; the didHandshake check alone is sufficient.

apps/provider-proxy/src/services/WebsocketServer.ts (1)

251-256: Minor: log message mentions certificate but JWT path also exists

Consider generic wording like “identity verification” to cover both CA and custom cert validation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b618851 and 904153d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • apps/provider-proxy/package.json (3 hunks)
  • apps/provider-proxy/src/container.ts (1 hunks)
  • apps/provider-proxy/src/routes/proxyProviderRequest.ts (4 hunks)
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts (1 hunks)
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.ts (1 hunks)
  • apps/provider-proxy/src/services/ProviderProxy.ts (6 hunks)
  • apps/provider-proxy/src/services/WebsocketServer.ts (13 hunks)
  • apps/provider-proxy/src/utils/schema.ts (2 hunks)
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (4 hunks)
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts (3 hunks)
  • apps/provider-proxy/test/setup/providerServer.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/provider-proxy/test/setup/providerServer.ts
  • apps/provider-proxy/src/container.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
  • apps/provider-proxy/src/utils/schema.ts
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts
  • apps/provider-proxy/src/services/ProviderProxy.ts
  • apps/provider-proxy/src/services/WebsocketServer.ts
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.ts
  • apps/provider-proxy/src/routes/proxyProviderRequest.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/provider-proxy/test/setup/providerServer.ts
  • apps/provider-proxy/src/container.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
  • apps/provider-proxy/src/utils/schema.ts
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts
  • apps/provider-proxy/src/services/ProviderProxy.ts
  • apps/provider-proxy/src/services/WebsocketServer.ts
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.ts
  • apps/provider-proxy/src/routes/proxyProviderRequest.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
  • apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
🧬 Code graph analysis (7)
apps/provider-proxy/test/setup/providerServer.ts (1)
apps/provider-proxy/test/seeders/createX509CertPair.ts (1)
  • CertPair (28-31)
apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (4)
apps/provider-proxy/test/setup/chainApiServer.ts (2)
  • generateBech32 (61-63)
  • startChainApiServer (13-50)
apps/provider-proxy/test/seeders/createX509CertPair.ts (1)
  • createX509CertPair (4-26)
apps/provider-proxy/test/setup/providerServer.ts (1)
  • startProviderServer (14-71)
apps/provider-proxy/test/setup/proxyServer.ts (1)
  • request (15-27)
apps/provider-proxy/src/utils/schema.ts (3)
packages/net/src/index.ts (1)
  • netConfig (3-3)
apps/provider-proxy/src/utils/isValidBech32.ts (1)
  • isValidBech32Address (3-10)
apps/provider-proxy/src/utils/validateClientCertificateAttrs.ts (1)
  • validateClientCertificateAttrs (6-11)
apps/provider-proxy/src/services/ProviderProxy.ts (1)
apps/provider-proxy/src/utils/schema.ts (1)
  • providerRequestSchema (9-32)
apps/provider-proxy/src/services/WebsocketServer.ts (4)
apps/provider-proxy/src/utils/schema.ts (2)
  • addProviderAuthValidation (41-82)
  • providerRequestSchema (9-32)
apps/provider-proxy/src/utils/telemetry.ts (1)
  • propagateTracingContext (9-12)
apps/provider-proxy/src/services/WebsocketStats.ts (1)
  • ClientWebSocketStats (22-78)
packages/net/src/NetConfig/NetConfig.ts (1)
  • SupportedChainNetworks (3-3)
apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts (4)
apps/provider-proxy/test/setup/proxyServer.ts (1)
  • startServer (6-9)
apps/provider-proxy/test/setup/chainApiServer.ts (2)
  • generateBech32 (61-63)
  • startChainApiServer (13-50)
apps/provider-proxy/test/seeders/createX509CertPair.ts (1)
  • createX509CertPair (4-26)
apps/provider-proxy/test/setup/providerServer.ts (1)
  • startProviderServer (14-71)
apps/provider-proxy/src/routes/proxyProviderRequest.ts (1)
apps/provider-proxy/src/utils/schema.ts (2)
  • addProviderAuthValidation (41-82)
  • providerRequestSchema (9-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: validate (apps/api) / validate-unsafe
  • GitHub Check: validate (apps/deploy-web) / validate-unsafe
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
🔇 Additional comments (10)
apps/provider-proxy/src/container.ts (1)

6-6: LGTM: import path realignment.

Importing CertificateValidator from its dedicated directory improves cohesion without behavior change.

apps/provider-proxy/src/services/CertificateValidator/CertificateValidator.spec.ts (1)

4-8: LGTM: import adjustments.

Path changes to local module and test seeders look correct; tests remain valid and isolated.

apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (3)

213-214: LGTM: error path updated to auth.certPem.

Matches the new provider auth schema and validation.

Also applies to: 493-494


596-664: LGTM: MTLS flow test.

Solid positive and negative-path coverage for MTLS auth.


666-741: LGTM: JWT flow test.

JWT creation and validation checks are clear; invalid token path asserts expected error shape.

apps/provider-proxy/test/setup/providerServer.ts (2)

22-25: LGTM: optional client cert support for tests.

Enabling requestCert without rejecting unauthorized clients is appropriate for these functional tests.


79-85: LGTM: WS onConnection signature extended.

Passing the IncomingMessage to handlers makes MTLS/JWT verification straightforward in tests.

apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts (2)

230-292: LGTM: MTLS flow over WebSocket.

Covers both success and validation error. Good use of TLSSocket to assert client cert presence.


383-384: LGTM: 'network' field normalization in ourMessage.

Maintains compatibility with older call sites while emitting the new 'network' field.

apps/provider-proxy/src/utils/schema.ts (1)

84-90: JWT validation here does not verify signature — confirm intended scope

This only decodes and validates payload shape/claims. If signature verification is expected here, a signer/verification key must be configured; otherwise, leave as-is and consider renaming the error to “invalid JWT payload”.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments