sim icon indicating copy to clipboard operation
sim copied to clipboard

feat(byok): byok for hosted model capabilities

Open icecrasher321 opened this issue 1 month ago • 4 comments

Summary

BYOK to allow users to use their own keys for hosted providers

Screenshot 2025-12-24 at 1 25 34 PM

Type of Change

  • [x] New feature

Testing

Tested manually

Checklist

  • [x] Code follows project style guidelines
  • [x] Self-reviewed my changes
  • [x] Tests added/updated and passing
  • [x] No new warnings introduced
  • [x] I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

icecrasher321 avatar Dec 24 '25 21:12 icecrasher321

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs Ready Ready Preview, Comment Dec 25, 2025 2:22am

vercel[bot] avatar Dec 24 '25 21:12 vercel[bot]

@greptile

icecrasher321 avatar Dec 24 '25 21:12 icecrasher321

Greptile Summary

This PR implements Bring Your Own Key (BYOK) functionality allowing workspaces to use their own API keys for hosted model providers (OpenAI, Anthropic, Google, Mistral, Exa). When BYOK keys are configured, the platform skips billing charges since users are paying providers directly.

Key Changes

  • Added workspace_byok_keys table with encrypted key storage and workspace-provider uniqueness constraint
  • Created API endpoints for BYOK key management with admin-only access controls
  • Integrated BYOK lookup across LLM calls, embeddings generation, and web search
  • Added isBYOK flag to provider requests to skip billing when BYOK keys are used
  • Implemented frontend UI for managing keys with masked display and secure input

Architecture

The implementation follows a clean separation of concerns: encryption happens at the API boundary, decryption occurs at usage time via getApiKeyWithBYOK(), and the isBYOK flag propagates through the execution pipeline to control billing. Keys are scoped per workspace-provider pair with proper cascade deletion.

Confidence Score: 5/5

  • This PR is safe to merge with robust security implementation and proper billing controls
  • The implementation follows security best practices with encrypted key storage, admin-only access controls, proper foreign key constraints, and consistent billing logic. The code is well-structured with clear separation between key management, retrieval, and usage. Integration points are comprehensive covering LLM calls, embeddings, and search tools.
  • No files require special attention

Important Files Changed

Filename Overview
packages/db/schema.ts Added workspaceBYOKKeys table with proper encryption, foreign keys, and unique constraints for workspace-provider pairs
apps/sim/app/api/workspaces/[id]/byok-keys/route.ts API endpoints for BYOK key management with proper authentication, encryption/decryption, and admin-only write access
apps/sim/lib/api-key/byok.ts Core BYOK logic retrieves workspace keys and integrates with hosted model routing, falls back to server keys when BYOK unavailable
apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/byok/byok.tsx Frontend UI for managing BYOK keys across 5 providers (OpenAI, Anthropic, Google, Mistral, Exa) with masked display and secure input
apps/sim/providers/index.ts Provider request execution checks isBYOK flag to skip billing for BYOK usage
apps/sim/lib/knowledge/embeddings.ts Embedding generation checks for workspace BYOK OpenAI key before falling back to server keys
apps/sim/app/api/tools/search/route.ts Search tool checks for workspace BYOK Exa key and skips billing when BYOK is used
apps/sim/executor/handlers/agent/agent-handler.ts Agent handler retrieves BYOK keys via getApiKeyWithBYOK and propagates isBYOK flag through provider requests

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as BYOK Settings UI
    participant API as BYOK API Route
    participant DB as Database
    participant Enc as Encryption Service
    participant Workflow as Workflow Executor
    participant Handler as Agent Handler
    participant BYOK as BYOK Service
    participant Provider as Provider Service
    participant LLM as LLM Provider

    User->>UI: Add/Update API Key
    UI->>API: POST /api/workspaces/{id}/byok-keys
    API->>API: Verify admin permissions
    API->>Enc: encryptSecret(apiKey)
    Enc-->>API: encrypted key
    API->>DB: Insert/Update workspace_byok_keys
    DB-->>API: Success
    API-->>UI: Masked key response
    UI-->>User: Show success

    Note over Workflow,LLM: Workflow Execution Flow

    Workflow->>Handler: Execute agent block
    Handler->>BYOK: getApiKeyWithBYOK(provider, model, workspaceId)
    BYOK->>DB: Query workspace_byok_keys
    DB-->>BYOK: Encrypted key (if exists)
    BYOK->>Enc: decryptSecret(encryptedKey)
    Enc-->>BYOK: Decrypted API key
    BYOK-->>Handler: {apiKey, isBYOK: true}
    Handler->>Provider: executeRequest({...request, isBYOK: true})
    Provider->>LLM: API call with BYOK key
    LLM-->>Provider: Response
    Provider->>Provider: Skip billing (isBYOK=true)
    Provider-->>Handler: Response with cost=0
    Handler-->>Workflow: Block output

greptile-apps[bot] avatar Dec 24 '25 21:12 greptile-apps[bot]

@greptile

icecrasher321 avatar Dec 24 '25 21:12 icecrasher321