BYOK (“bring your own key”) lets you paste an Anthropic or OpenAI API key into your workspace. The platform validates it, encrypts it, and uses it on your behalf for two specific flows:Documentation Index
Fetch the complete documentation index at: https://docs.chatblocks.ai/llms.txt
Use this file to discover all available pages before exploring further.
- Scheduled runs — the cron-driven agent loop that calls
generateTextagainst the configured provider. blocks.create— the AI block generator that streams a new block from a prompt.
Why BYOK
Two reasons:- Your provider, your billing. Every LLM call is metered against your Anthropic or OpenAI account. The platform doesn’t mark up tokens.
- Your model choice. You pick the model per scheduled run from the supported list, and you can swap to a cheaper model without us pushing a release.
Add a key
Paste the API key
Anthropic (
sk-ant-*) or OpenAI (sk-* or sk-proj-*). Optionally pick a label so you can tell multiple keys apart.The platform validates against the provider’s /v1/models endpoint with a 5-second timeout. Validation failures bubble up with a clear message — “Provider rejected the key” on 401/403, “Could not reach <provider>” on network errors.Supported providers and models
Two providers in v1. Each carries a whitelist of model IDs the platform will accept at scheduled-run-set time.- Anthropic
- OpenAI
- Google
| Model ID |
|---|
claude-opus-4-7 |
claude-sonnet-4-6 |
claude-haiku-4-5 |
packages/shared/src/byokProviders.ts. To add a model, open a PR there.How keys get used
The runner decrypts your key just-in-time and passes it directly to the provider — the plaintext never travels back out of the action.Scheduled runs
Scheduled runs
convex/scheduledRuns/runner.ts looks up the BYOK row by id, calls _decryptForRunner({ actor: "system:scheduledRunner" }), and instantiates @ai-sdk/anthropic or @ai-sdk/openai with the plaintext as the API key.AI Gateway is intentionally skipped — gateway BYOK is project-scoped, so per-workspace BYOK has to use the provider SDKs directly.schedule.preview
schedule.preview
The streaming preview tool decrypts with
actor: "system:schedulePreview" so preview events are distinguishable from production runs in the audit log.blocks.create
blocks.create
The AI block generator uses a separate inference path (
@vercel/ai streamObject) but the BYOK selection is the same — pick the key, pick the model, run.auditLog row with the calling actor (system:scheduledRunner, system:schedulePreview, etc.), the BYOK key id, and the timestamp. Customers can see exactly when their key was used and by which flow.
MCP tools
Three tools surface the BYOK panel to agents. Admin-only.| Tool | Purpose |
|---|---|
byokKeys.add | Add a key. Same validation as the UI. Audit-logged. |
byokKeys.list | List keys (metadata only — never returns plaintext). Not audited. |
byokKeys.delete | Remove a key by id. Audit-logged. |
Encryption details
- AES-256-GCM with a per-workspace data encryption key (DEK).
- DEK is wrapped with a master key encryption key (KEK) held in Convex env (
KEK_V1). - Ciphertext is stored inline on the
customerApiKeysrow (vs. data sources, which store ciphertext in a separate table). keyVersionfield tracks the KEK version for rotation.
kekVersion). Until then, KEK is set once at platform install and stays put.
What’s next
Scheduled runs
Cron-driven agent loops powered by your BYOK key.
Audit log
Every BYOK decrypt is logged with actor + key id + timestamp.