How the Edge Middleware in proxy.ts Validates Supabase Auth and Injects X‑Request‑Id

The proxy.ts edge middleware verifies Supabase JWTs via auth.getUser(), rejects unauthenticated requests with a 401 response, and injects a crypto.randomUUID() as the X‑Request‑Id header for distributed tracing.

The DeskcommCRM repository implements a secure entrance point for all API traffic using Next.js edge middleware. Located in the root proxy.ts file, this middleware intercepts every incoming request to validate Supabase authentication tokens and ensure every request carries a unique trace identifier before reaching application routes.

Supabase Authentication Validation at the Edge

The primary security function of the middleware is to verify that every request presents a valid Supabase session. This prevents unauthorized access to protected API endpoints and server actions.

Token Extraction from Cookies

The middleware extracts the authentication token from the sb:token cookie, falling back to the legacy supabase-auth-token cookie name for backward compatibility. These cookies contain the JWT issued by Supabase Auth upon user login.

JWT Verification with auth.getUser()

Rather than trusting the cookie value directly, the middleware initializes a server-side Supabase client using createSupabaseClient() from lib/supabase/server.ts. It then calls auth.getUser() to validate the JWT signature, expiration, and audience with Supabase's servers. This approach ensures that revoked tokens or malformed payloads are rejected immediately at the edge.

Returning 401 for Invalid Sessions

If the token is missing, malformed, or auth.getUser() returns an error, the middleware responds with a 401 Unauthorized status. According to the DeskcommCRM source, the middleware utilizes response helpers from lib/api/wrappers.ts to standardize error formatting before terminating the request.

Distributed Tracing with X‑Request‑Id Injection

Beyond authentication, the middleware ensures observability by guaranteeing every request carries a unique identifier suitable for distributed tracing across services.

Generating UUIDs with crypto.randomUUID()

When a request arrives without an X‑Request‑Id header, the middleware generates a new UUID v4 using the Web Crypto API's crypto.randomUUID() method. This identifier is attached to the request headers as X‑Request‑Id, ensuring that logs, database queries, and external API calls can be correlated to the original request.

Header Propagation to Downstream Services

The injected X‑Request‑Id value propagates through the Next.js routing pipeline. Downstream components, including the structured logger in lib/logger.ts, capture this identifier to create coherent trace chains across the application stack.

Implementation Structure in proxy.ts

The middleware follows a sequential pattern: extract cookies, validate with Supabase, check/generate request ID, then forward. The implementation returns NextResponse.next() to continue processing when both checks pass.

// proxy.ts - Implementation pattern in DeskcommCRM
import { NextResponse } from 'next/server'
import { createSupabaseClient } from './lib/supabase/server'

export async function middleware(request: NextRequest) {
  // Extract token from cookies
  const token = request.cookies.get('sb:token')?.value || 
                request.cookies.get('supabase-auth-token')?.value
  
  // Validate with Supabase
  const supabase = createSupabaseClient()
  const { data: { user }, error } = await supabase.auth.getUser(token)
  
  if (error || !user) {
    return new NextResponse('Unauthorized', { status: 401 })
  }
  
  // Inject X-Request-Id
  const requestId = request.headers.get('X-Request-Id') || crypto.randomUUID()
  const requestHeaders = new Headers(request.headers)
  requestHeaders.set('X-Request-Id', requestId)
  
  // Forward with modified headers
  return NextResponse.next({
    request: {
      headers: requestHeaders,
    },
  })
}

Consuming the Validated Context

Once the middleware completes, application code can safely assume a valid authentication context and access the trace identifier.

Accessing the Supabase User in API Routes

API routes can access the validated user object attached to the request context. The middleware enriches the request with the Supabase user data retrieved during the auth.getUser() call:

// app/api/v1/orders/route.ts
export async function GET(req: Request) {
  // User object set by proxy.ts middleware
  const user = (req as any).context?.supabaseUser
  
  if (!user) {
    return new Response('Unauthorized', { status: 401 })
  }
  
  return Response.json({ email: user.email })
}

Retrieving X‑Request‑Id in Server Actions

Server actions can access the injected header using Next.js headers() helper to maintain trace context through asynchronous operations:

import { headers } from 'next/headers'

export const processOrder = async (orderId: string) => {
  const requestId = headers().get('X-Request-Id')
  
  if (!requestId) {
    throw new Error('Request ID not found')
  }
  
  // Pass ID to downstream services or logging
  await logOrderAccess(orderId, requestId)
  return { success: true, requestId }
}

Summary

  • The proxy.ts edge middleware validates every request against Supabase Auth using auth.getUser() before allowing access to protected routes.
  • Authentication tokens are extracted from the sb:token or supabase-auth-token cookies and verified server-side to prevent tampering.
  • Invalid or missing tokens trigger an immediate 401 Unauthorized response, preventing unauthorized access to backend resources.
  • The middleware injects a X‑Request‑Id header using crypto.randomUUID() if one is not present, enabling distributed tracing across the application.
  • Validated user context and request IDs are propagated downstream to API routes and server actions for secure, traceable request processing.

Frequently Asked Questions

How does proxy.ts handle expired Supabase tokens?

The middleware validates tokens by calling auth.getUser() from the server-side Supabase client. If the JWT has expired or been revoked, Supabase returns an error, and the middleware responds with a 401 status code, forcing the client to re-authenticate.

Can I customize the X‑Request‑Id generation logic?

Yes, the middleware checks for existing X‑Request‑Id headers before generating a new UUID. If your infrastructure already injects this header (via a load balancer or CDN), the middleware preserves that value. To customize generation, modify the crypto.randomUUID() call in proxy.ts to use your preferred ID format.

Which files depend on the X‑Request‑Id set by the middleware?

According to the DeskcommCRM source, the structured logger in lib/logger.ts and API response wrappers in lib/api/wrappers.ts both utilize the X‑Request‑Id header to correlate logs and standardize error responses with trace identifiers.

What happens if the Supabase client fails to initialize in the middleware?

If createSupabaseClient() from lib/supabase/server.ts throws an exception or returns an invalid client, the auth.getUser() call will fail, resulting in a 401 response. This fail-safe ensures that authentication state is never assumed without explicit verification.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →