feat(byok): byok for hosted model capabilities
Summary
BYOK to allow users to use their own keys for hosted providers
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)
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Review | Updated (UTC) |
|---|---|---|---|
| docs | Preview, Comment | Dec 25, 2025 2:22am |
@greptile
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_keystable 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
isBYOKflag 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