Automatic Database Migration
If you are running Bifrost with a database (SQLite or Postgres), existing data is automatically migrated on startup. You do not need to manually update your database records. The following automatic migrations run on upgrade:- Provider keys with
models: []are converted tomodels: ["*"] - Virtual Key provider configs with
allowed_models: []are converted toallowed_models: ["*"] - Virtual Keys with no
provider_configsare backfilled with all currently configured providers (allowed_models: ["*"],key_ids: ["*"]) - Virtual Keys with no
mcp_configsare backfilled with all currently connected MCP clients (tools_to_execute: ["*"]) - Per-provider
deploymentsmaps (Azure, Bedrock, Vertex, Replicate) are migrated into the unifiedaliasesfield
config.json or the REST API — must follow the new semantics described below.
Breaking Change 1: Empty Array Now Means “Deny All”
v1.5.0 flips the meaning of empty arrays across all allow-list fields:| What you write | v1.4.x meaning | v1.5.0 meaning |
|---|---|---|
[] (empty array) | Allow all | Allow none |
["*"] (wildcard) | Not applicable | Allow all |
["a", "b"] | Only a and b | Only a and b (unchanged) |
| Field | Where |
|---|---|
models | Provider key |
allowed_models | Virtual Key provider config |
key_ids | Virtual Key provider config |
tools_to_execute | Virtual Key MCP config |
Provider key models
Before:
models: [] → key served all models
After:
Virtual Key allowed_models
Before:
allowed_models → all models allowed
After:
Virtual Key MCP tools_to_execute
Before:
Breaking Change 2: allowed_keys Renamed to key_ids
The field used to restrict which provider API keys a Virtual Key can use has been renamed from allowed_keys to key_ids. The deny-by-default rule also applies — omitting the field or setting it to [] now blocks all keys.
Unlike
allowed_models, there is no automatic database migration for key_ids. An empty or omitted key_ids disables all key selection. You must explicitly use ["*"] to restore allow-all behavior.Breaking Change 3: Virtual Key provider_configs is Deny-by-Default
In v1.4.x, a Virtual Key with no provider_configs had access to all providers. In v1.5.0, it blocks all providers.
Before: "provider_configs": [] → access to all providers
After: "provider_configs": [] → no provider access
To allow all providers, list each one explicitly:
provider_configs. However, any VK created after upgrading must include explicit provider configs.
Breaking Change 4: WhiteList Validation
Two new validation rules are enforced on all allow-list fields. The API returns HTTP 400 if either is violated. Rule 1: Wildcard cannot be mixed with other valuesmodels, allowed_models, key_ids, tools_to_execute, tools_to_auto_execute, allowed_extra_headers.
Breaking Change 5: weight is Now Nullable
The weight field on a Virtual Key provider config was previously a required float64. It is now an optional *float64.
weight: 0.5— provider participates in weighted load balancingweight: null/ omitted — provider is accessible for direct routing but excluded from weighted selection
weight may now be null. Update any client code that assumes it is always a number.
Breaking Change 6: Provider Keys API Separated
Provider key management now has dedicated endpoints. Thekeys field has been removed from all provider API requests and responses.
What changed
| Before (v1.4.x) | After (v1.5.0) |
|---|---|
GET /api/providers/{p} returns keys | keys field removed from provider response |
POST /api/providers accepts keys | keys field ignored — create keys separately |
PUT /api/providers/{p} accepts keys | keys field ignored — update keys via dedicated endpoints |
New endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /api/providers/{provider}/keys | List all keys |
GET | /api/providers/{provider}/keys/{key_id} | Get a single key |
POST | /api/providers/{provider}/keys | Create a key |
PUT | /api/providers/{provider}/keys/{key_id} | Update a key |
DELETE | /api/providers/{provider}/keys/{key_id} | Delete a key |
How to update
Creating a provider with keys: Before:curl localhost:8080/api/providers/openai | jq '.keys'
After: curl localhost:8080/api/providers/openai/keys | jq '.keys'
Updating / deleting keys:
Before: Bulk replace via provider update:
Breaking Change 7: Compact Plugin Restructured
Theenable_litellm_fallbacks option has been removed and replaced with three granular options.
Before:
| Old option | New option | Description |
|---|---|---|
enable_litellm_fallbacks | convert_text_to_chat | Text completion → chat completion fallback |
| (new) | convert_chat_to_responses | Chat completion → Responses API fallback |
| (new) | should_drop_params | Drop unsupported OpenAI-compatible params |
| Field | Change |
|---|---|
extra_fields.litellm_compat | Removed |
extra_fields.dropped_compat_plugin_params | Added — lists params dropped by this plugin |
extra_fields.converted_request_type | Added — the request type it was converted to |
Breaking Change 8: Replicate Image Edits Removed from Generations Endpoint
The/v1/images/generations endpoint on the Replicate provider no longer accepts image editing parameters (source image, mask). It now only handles text-to-image generation.
If you were passing image editing parameters to /v1/images/generations on Replicate, switch to /v1/images/edits.
Support for image editing via
/v1/images/edits on Replicate is also being removed in a follow-up release. Plan to migrate to an alternative provider.Breaking Change 9: Provider deployments Removed — Migrate to aliases
The per-provider deployments map has been removed from azure_key_config, vertex_key_config, bedrock_key_config, and replicate_key_config. A single top-level aliases field on each key replaces all of them. Aliases work across all providers and map any model name to a provider-specific identifier (deployment name, inference profile ARN, fine-tuned model ID, etc.).
The database migration runs automatically on startup, migrating existing deployment data into aliases. Only config.json files need to be updated manually.
Azure
Before:Bedrock
Before:Vertex
Before:Replicate
The Replicate key config is also restructured. Thedeployments map is gone. A new boolean use_deployments_endpoint controls whether requests are routed through the Deployments API (private, fixed hardware) or the standard Models API.
Before:
| Old field | New field | Notes |
|---|---|---|
replicate_key_config.deployments | Removed | Use top-level aliases |
| (new) | replicate_key_config.use_deployments_endpoint | bool, default false |
Breaking Change 10: Go SDK — ExtraFields Model Fields Renamed
ModelRequested string has been replaced by two fields on BifrostResponseExtraFields and BifrostErrorExtraFields.
Before:
BifrostErrorExtraFields.
JSON tag changes:
| Old | New |
|---|---|
"model_requested" | "original_model_requested" + "resolved_model_used" |
Breaking Change 11: Go SDK — StreamAccumulatorResult Field Renamed
Model string has been replaced by two fields on StreamAccumulatorResult (returned by tracer streaming accumulation methods).
Before:
Opting Out: version: 1 Compatibility Mode
If you are not ready to adopt the new deny-by-default semantics, you can add a single field to config.json to restore v1.4.x behavior for all allow-list fields loaded from that file:
| Value | Behavior |
|---|---|
2 (default, omitted) | v1.5.0 semantics — empty = deny all, ["*"] = allow all |
1 | v1.4.x semantics — empty = allow all |
version: 1 normalizes at startup (before any other processing):
| Field | Without version: 1 | With version: 1 |
|---|---|---|
Provider key models: [] | Deny all models | Allow all models (→ ["*"]) |
VK provider_configs: [] | No providers allowed | All configured providers added with allowed_models: ["*"] |
VK provider config allowed_models: [] | Deny all models | Allow all models (→ ["*"]) |
VK provider config key_ids: [] | No keys allowed | All keys allowed (→ key_ids: ["*"]) |
VK mcp_configs: [] | No MCP tools allowed | All configured MCP clients added with tools_to_execute: ["*"] |
version: 1 only applies to configuration loaded from config.json. Virtual Keys created or updated via the REST API always use v1.5.0 semantics regardless of this setting. The automatic database migration that runs on startup is also unaffected.Complete Migration Checklist
Update provider key models in config.json
Replace
"models": [] or missing models fields with "models": ["*"] on every provider key.Add allowed_models and key_ids to every VK provider config
Add
"allowed_models": ["*"] and "key_ids": ["*"] to every provider_configs entry (or list specific values). Rename any allowed_keys fields to key_ids.Ensure every VK has at least one provider config
Any Virtual Key with
"provider_configs": [] or no provider_configs will block all traffic.Update tools_to_execute for MCP configs
Replace
"tools_to_execute": [] with "tools_to_execute": ["*"]. Ensure every VK that needs MCP access has at least one mcp_configs entry.Handle nullable weight in API consumers
Update any client code that processes
weight to accept null in addition to numbers.Fix invalid WhiteList values
Ensure no list mixes
"*" with specific values (e.g., ["*", "gpt-4o"]) and no list has duplicate entries.Migrate key management to dedicated endpoints
Stop sending
keys in provider create/update payloads and stop reading keys from provider responses. Use /api/providers/{provider}/keys for all key operations.Update compact plugin config
Replace
enable_litellm_fallbacks with the appropriate combination of convert_text_to_chat, convert_chat_to_responses, and should_drop_params.Migrate provider deployments to aliases
Remove
deployments from azure_key_config, vertex_key_config, bedrock_key_config, and replicate_key_config. Move those mappings to the top-level aliases field on each key. For Replicate, set use_deployments_endpoint: true if you were using the deployments endpoint.Update Go SDK references to ExtraFields.ModelRequested
Replace
ExtraFields.ModelRequested with ExtraFields.OriginalModelRequested (and optionally read ExtraFields.ResolvedModelUsed). Update JSON consumers reading "model_requested" to use "original_model_requested" and "resolved_model_used".Troubleshooting
All requests returning 403/blocked after upgrade A provider key hasmodels: [], a Virtual Key has no provider_configs, or a provider config has allowed_models: []. Check Bifrost logs — a blocked request logs which rule denied it. Fix: add "models": ["*"] on provider keys, "allowed_models": ["*"] on VK provider configs.
MCP tools not being injected / tool calls blocked
The VK needs an mcp_configs entry for the MCP client with "tools_to_execute": ["*"] (or specific tools).
API returning 400 on VK create/update
A whitelist validation failure — either mixing "*" with specific values, or duplicate values in a list.
“No keys available” or key selection errors
A provider config with key_ids omitted or [] now blocks all keys (allow_all_keys: false). Add "key_ids": ["*"].
Provider create/update errors about keys field
The keys field has been removed. Remove it from provider payloads and use /api/providers/{provider}/keys instead.
Replicate requests failing after upgrade
If you used replicate_key_config.deployments, move the mappings to the top-level aliases field and set use_deployments_endpoint: true if you were targeting the Deployments API.
Go SDK compilation errors on ModelRequested or StreamAccumulatorResult.Model
Rename to OriginalModelRequested/ResolvedModelUsed on ExtraFields, and RequestedModel/ResolvedModel on StreamAccumulatorResult.
