From aeb35c6826bdc02ed01c607c2f6a13234ad2c217 Mon Sep 17 00:00:00 2001 From: Vijay Tupakula Date: Mon, 14 Jul 2025 16:23:25 -0500 Subject: [PATCH 1/2] Implement proper ephemeral key generation for OpenAI Realtime API - Replace direct API key exposure with secure ephemeral key generation - Make server-side POST request to OpenAI /v1/realtime/sessions endpoint - Return temporary ephemeral key that expires after 1-2 hours - Keep API key secure on server, never expose to frontend - Return session ID and expiration timestamp with ephemeral key This follows OpenAI's security best practices for client-side applications Co-Authored-By: Claude --- app/Http/Controllers/RealtimeController.php | 27 +++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/RealtimeController.php b/app/Http/Controllers/RealtimeController.php index b6878e5..ba6a3cf 100644 --- a/app/Http/Controllers/RealtimeController.php +++ b/app/Http/Controllers/RealtimeController.php @@ -4,6 +4,7 @@ use App\Services\ApiKeyService; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; class RealtimeController extends Controller @@ -30,13 +31,29 @@ public function generateEphemeralKey(Request $request) ], 422); } - // Return the actual API key for now - // OpenAI Realtime API uses the API key directly in WebSocket connection + // Generate ephemeral key from OpenAI Realtime API + $response = Http::withHeaders([ + 'Authorization' => 'Bearer ' . $apiKey, + 'Content-Type' => 'application/json', + ])->post('https://api.openai.com/v1/realtime/sessions', [ + 'model' => 'gpt-4o-realtime-preview-2024-12-17', + 'voice' => $request->input('voice', 'alloy'), + ]); + + if (!$response->successful()) { + Log::error('OpenAI API error: ' . $response->body()); + throw new \Exception('Failed to generate ephemeral key from OpenAI: ' . $response->status()); + } + + $data = $response->json(); + + // Return ephemeral key data return response()->json([ 'status' => 'success', - 'ephemeralKey' => $apiKey, // Use actual API key - 'expiresAt' => now()->addMinutes(60)->toIso8601String(), - 'model' => 'gpt-4o-realtime-preview-2024-12-17', + 'ephemeralKey' => $data['client_secret']['value'], + 'expiresAt' => $data['client_secret']['expires_at'], + 'sessionId' => $data['id'], + 'model' => $data['model'], ]); } catch (\Exception $e) { From a10158a771417e710f419da3b2449357309f67c0 Mon Sep 17 00:00:00 2001 From: Vijay Tupakula Date: Mon, 14 Jul 2025 16:26:30 -0500 Subject: [PATCH 2/2] Add response validation for OpenAI API ephemeral key generation - Add null checks for nested response data before accessing - Validate client_secret structure exists in response - Add default values for optional fields (sessionId, model) - Improve error logging with response data for debugging - Prevent potential runtime errors from missing response keys Co-Authored-By: Claude --- app/Http/Controllers/RealtimeController.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/RealtimeController.php b/app/Http/Controllers/RealtimeController.php index ba6a3cf..0b8f0ae 100644 --- a/app/Http/Controllers/RealtimeController.php +++ b/app/Http/Controllers/RealtimeController.php @@ -47,13 +47,19 @@ public function generateEphemeralKey(Request $request) $data = $response->json(); + // Validate response structure + if (!isset($data['client_secret']['value']) || !isset($data['client_secret']['expires_at'])) { + Log::error('Invalid response structure from OpenAI API', ['response' => $data]); + throw new \Exception('Invalid response structure from OpenAI API'); + } + // Return ephemeral key data return response()->json([ 'status' => 'success', 'ephemeralKey' => $data['client_secret']['value'], 'expiresAt' => $data['client_secret']['expires_at'], - 'sessionId' => $data['id'], - 'model' => $data['model'], + 'sessionId' => $data['id'] ?? null, + 'model' => $data['model'] ?? 'gpt-4o-realtime-preview-2024-12-17', ]); } catch (\Exception $e) {