Problem
The desktop macOS app retrieves DEEPGRAM_API_KEY and GEMINI_API_KEY from the Rust backend via /v1/config/api-keys, then uses them directly to connect to third-party services. This exposes production API keys to the client process — extractable via memory inspection, network interception, or binary analysis.
Current Gemini spend is ~$900/day on low user count — likely key abuse.
Proposal
Add proxy endpoints to the existing Rust backend (desktop/Backend-Rust/) so the desktop app never touches API keys directly:
Tier 1 — Gemini proxy (highest priority, $900/day bleeding)
POST /v1/proxy/gemini/models/:model:generateContent
POST /v1/proxy/gemini/models/:model:embedContent
POST /v1/proxy/gemini/models/:model:batchEmbedContents
Tier 2 — Deepgram proxy
WS /v1/proxy/deepgram/listen (bidirectional WebSocket bridge)
Desktop changes
GeminiClient.swift → route through Rust backend proxy
EmbeddingService.swift → route through Rust backend proxy
TranscriptionService.swift → route through Rust backend WS proxy
Cleanup
- Remove
deepgram_api_key and gemini_api_key from /v1/config/api-keys response
- Rotate both compromised keys after deploy
Acceptance Criteria
Notes
- Rust backend already has Firebase auth (
AuthUser extractor), reqwest, and tokio
- Need
tokio-tungstenite for WS proxy and axum ws feature
- 10 Gemini consumers in desktop all go through
GeminiClient.swift and EmbeddingService.swift — only 3 Swift files need URL changes
by AI for @beastoin
Problem
The desktop macOS app retrieves
DEEPGRAM_API_KEYandGEMINI_API_KEYfrom the Rust backend via/v1/config/api-keys, then uses them directly to connect to third-party services. This exposes production API keys to the client process — extractable via memory inspection, network interception, or binary analysis.Current Gemini spend is ~$900/day on low user count — likely key abuse.
Proposal
Add proxy endpoints to the existing Rust backend (
desktop/Backend-Rust/) so the desktop app never touches API keys directly:Tier 1 — Gemini proxy (highest priority, $900/day bleeding)
POST /v1/proxy/gemini/models/:model:generateContentPOST /v1/proxy/gemini/models/:model:embedContentPOST /v1/proxy/gemini/models/:model:batchEmbedContentsTier 2 — Deepgram proxy
WS /v1/proxy/deepgram/listen(bidirectional WebSocket bridge)Desktop changes
GeminiClient.swift→ route through Rust backend proxyEmbeddingService.swift→ route through Rust backend proxyTranscriptionService.swift→ route through Rust backend WS proxyCleanup
deepgram_api_keyandgemini_api_keyfrom/v1/config/api-keysresponseAcceptance Criteria
/v1/config/api-keysresponseNotes
AuthUserextractor),reqwest, andtokiotokio-tungstenitefor WS proxy andaxumws featureGeminiClient.swiftandEmbeddingService.swift— only 3 Swift files need URL changesby AI for @beastoin