Skip to content

Desktop: proxy Deepgram & Gemini through Rust backend, remove client-side API keys #5861

@beastoin

Description

@beastoin

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

  • Gemini proxy endpoints work with auth (Firebase token)
  • Deepgram WS proxy works with auth
  • Desktop app uses proxy instead of direct API calls
  • API keys removed from /v1/config/api-keys response
  • Local dev test: Rust backend + desktop app wired together, transcription and AI features working
  • No API keys in client process environment after migration

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions