BYOK (Bring Your Own Key)
BYOK (Bring Your Own Key) allows API consumers to override the model for a single request by passing their own provider credentials in HTTP headers. SyntheticBrew uses the consumer’s key for that request only and does not save it as a model credential.
What is BYOK?
Section titled “What is BYOK?”Normally, each agent uses the saved model selected in its configuration. With BYOK enabled, an API consumer can override it by specifying a different provider, model, and API key in request headers. The override applies to that single request only; later requests without BYOK headers use the configured model again.
This is useful for:
- Multi-tenant platforms — each customer uses their own LLM API key and billing.
- Testing — try different models without changing the saved agent configuration.
- Premium tiers — offer customers the option to use a more powerful model by providing their own key.
Headers
Section titled “Headers”| Header | Required | Description |
|---|---|---|
X-BYOK-Provider | Yes | Provider type. One of openai, anthropic, openrouter, openai_compatible, ollama. |
X-BYOK-API-Key | Yes | The consumer’s API key for the specified provider. |
X-BYOK-Model | Usually | Model identifier expected by the provider. OpenAI and Anthropic have the defaults shown below; supply this header for OpenRouter, OpenAI-compatible endpoints, and Ollama. |
X-BYOK-Base-URL | No | Override the provider base URL. Honored only for openai_compatible (required) and ollama. For the pinned hosted providers (openai, anthropic, openrouter) the base URL is fixed — supplying this header is rejected with HTTP 400. |
X-BYOK-Provider and X-BYOK-API-Key are mandatory — if either is missing the request is rejected with HTTP 400. The remaining headers are optional.
The base URL restriction shrinks the request-forgery surface: an end-user cannot repoint a hosted provider at an arbitrary host. See Security for the destination restrictions that apply to openai_compatible / ollama.
Supported providers
Section titled “Supported providers”| Provider | Base URL | Notes |
|---|---|---|
openai | https://api.openai.com/v1 (fixed) | Defaults to gpt-4o-mini when X-BYOK-Model is omitted. Base URL cannot be overridden. |
anthropic | https://api.anthropic.com/v1 (fixed) | Defaults to claude-3-5-sonnet-20241022 when X-BYOK-Model is omitted. Adds the required Anthropic version header automatically. Base URL cannot be overridden. |
openrouter | https://openrouter.ai/api/v1 (fixed) | X-BYOK-Model required (no default). Base URL cannot be overridden. |
openai_compatible | user-supplied | X-BYOK-Base-URL required; works with any OpenAI-compatible endpoint (must be a public host — see Security). |
ollama | http://localhost:11434/v1 default, or user-supplied | Intended for an endpoint reachable from SyntheticBrew. On the request-header path a private/internal base URL is rejected; in Enterprise, configure a private Ollama service as a saved model instead. |
azure_openai and google are not BYOK provider values. Configure Azure as a stored azure_openai model. For Gemini, use openai_compatible with Google’s public OpenAI-compatible endpoint, subject to the tenant allowlist and destination policy.
curl example
Section titled “curl example”curl -N "$SYNTHETICBREW_URL/api/v1/schemas/{name}/chat" \ -H "Authorization: Bearer bb_your_token" \ -H "Content-Type: application/json" \ -H "X-BYOK-Provider: anthropic" \ -H "X-BYOK-API-Key: sk-ant-customer-provided-key" \ -H "X-BYOK-Model: claude-sonnet-4-6" \ -d '{"message": "Hello, tell me about your capabilities"}'The agent’s system prompt, tools, and all other configuration remain unchanged. Only the LLM backend is overridden.
For an OpenAI-compatible endpoint, supply the base URL too:
curl -N "$SYNTHETICBREW_URL/api/v1/schemas/{name}/chat" \ -H "Authorization: Bearer bb_your_token" \ -H "Content-Type: application/json" \ -H "X-BYOK-Provider: openai_compatible" \ -H "X-BYOK-API-Key: sk-your-key" \ -H "X-BYOK-Base-URL: https://your-endpoint.example/v1" \ -H "X-BYOK-Model: your-model" \ -d '{"message": "Hello"}'JavaScript example
Section titled “JavaScript example”const response = await fetch(`${process.env.SYNTHETICBREW_URL}/api/v1/schemas/{name}/chat`, { method: 'POST', headers: { 'Authorization': 'Bearer bb_your_token', 'Content-Type': 'application/json', 'X-BYOK-Provider': 'openai', 'X-BYOK-API-Key': customerApiKey, 'X-BYOK-Model': 'gpt-5.4-mini', }, body: JSON.stringify({ message: userMessage }),});
const reader = response.body.getReader();// Process SSE stream...Enabling BYOK
Section titled “Enabling BYOK”BYOK is disabled by default. Enable it one of two ways.
Admin Dashboard
Section titled “Admin Dashboard”- Navigate to Admin Dashboard -> Settings.
- Under BYOK (Bring Your Own Key), turn on BYOK Enabled and select the providers to allow.
- Changes take effect immediately (no restart needed), and apply only to that tenant.
If no providers are selected, the hosted providers (openai, anthropic, openrouter) are allowed while BYOK is enabled. The custom-base-URL providers openai_compatible and ollama are never implied by an empty list — they must be selected explicitly, because they accept a user-supplied base URL. This keeps a freshly-enabled tenant from unintentionally exposing an internal endpoint.
Enterprise Helm values
Section titled “Enterprise Helm values”Manage BYOK from your chart values when it belongs in your GitOps flow instead of per-deployment Admin clicks:
config: byok: enabled: true allowedProviders: [openai, anthropic, openrouter, openai_compatible, ollama]When this block is set, SyntheticBrew applies these settings on every boot. The chart values override later Admin edits until you remove the block. Omit allowedProviders (or leave it empty) to use the safe hosted-provider default: openai, anthropic, and openrouter. Add openai_compatible or ollama explicitly because they accept a caller-supplied base URL. The corresponding environment variables are SYNTHETICBREW_BYOK_ENABLED and SYNTHETICBREW_BYOK_ALLOWED_PROVIDERS (comma-separated).
When to use BYOK
Section titled “When to use BYOK”| Scenario | BYOK useful? | Why |
|---|---|---|
| Multi-tenant SaaS | Yes | Each customer provides their own LLM key and pays their own API costs. |
| Internal team tools | Usually no | Use a shared organizational API key in a saved model configuration. |
| A/B testing models | Yes | Compare gpt-5.4 vs claude on the same agent without changing config. |
| Premium features | Yes | Let paying customers use a better model by providing their own key. |
| Development/staging | Yes | Developers test with their personal keys without affecting shared config. |
Security
Section titled “Security”- Keys are never stored as model credentials. SyntheticBrew uses the key for that single request and discards it afterward.
- Keys are never logged. Even at
debuglog level, API keys from BYOK headers are redacted. - BYOK is off by default. A Cloud workspace administrator or Enterprise deployment administrator must explicitly enable it. Enabling it for one workspace does not enable it for another.
- Request-scoped. SyntheticBrew does not cache or persist the key; it sends it only to the selected provider for that request.
- Provider validation. If the consumer specifies a provider that is not in the allowlist, the request is rejected with HTTP 403. A missing required header (
X-BYOK-Provider/X-BYOK-API-Key) is rejected with HTTP 400. - No base URL override for pinned providers.
openai,anthropic, andopenrouteruse fixed hosted endpoints; anX-BYOK-Base-URLfor them is rejected (HTTP 400). Onlyopenai_compatibleandollamaaccept a base URL. - Destination restriction (SSRF protection). A user-supplied base URL that resolves to a loopback, private, link-local, CGNAT, or cloud-metadata address is refused before any connection is made — the check runs on the resolved IP, so it is DNS-rebinding safe. In managed / Cloud deployments the same restriction also applies to operator-configured models. A refused destination returns a single opaque error (no address is echoed back), so the endpoint cannot be used to probe your internal network.