Skip to main content
The live schema is published at https://www.getbifrost.ai/schema. Add "$schema": "https://www.getbifrost.ai/schema" to your config.json for IDE autocomplete and inline validation, or point it to a mirrored HTTP(S) URL, file:// URL, or filesystem path in isolated deployments. You can also set the BIFROST_SCHEMA_URL environment variable, which takes precedence over the $schema value. When mirroring, snapshot a schema published by a Bifrost release that supports custom $schema values; older schema copies pin $schema to the public URL and will flag a mirrored location as invalid in IDEs.
This page is a concise reference for every top-level key in config.json. Click the Guide links for full field-by-field documentation.

Top-Level Keys


version

Controls how empty arrays in the allow-list fields of provider keys (models) and virtual keys (allowed_models, key_ids, tools_to_execute) are interpreted: Omitting version uses v2 semantics. Set "version": 1 only if you are migrating from v1.4.x and need the old behaviour temporarily. Projects declared under governance.projects are not covered by this switch: their key_ids and tools_to_execute always treat an empty or omitted array as granting nothing, under either value.

source_of_truth

Controls how config.json is reconciled with the config store at startup. Missing and empty sections behave differently when source_of_truth is "config.json". A missing section leaves DB rows untouched; a present empty section is authoritative and can prune matching DB rows.
The example above makes the plugins section present and empty, so stored plugins are removed on startup. See Source of Truth & Reconciliation for section-by-section behavior.

client

Controls the worker pool, logging pipeline, security, and SDK shims. All fields are optional. Full documentation: Client Configuration.

providers

Keyed by provider name. Each entry contains a keys array and optional network_config, concurrency_and_buffer_size, proxy_config. Supported provider keys: anthropic, azure, bedrock, bedrock_mantle, cerebras, cohere, deepseek, gemini, groq, mistral, ollama, opencode-go, opencode-zen, openai, parasail, perplexity, sgl, vertex, openrouter, elevenlabs, huggingface, nebius, xai, replicate, vllm, runway, runware, fireworks, sarvam, wafer, databricks. Full documentation: Provider Setup.

governance

Seeds governance resources at startup. All sub-keys are optional arrays. Full documentation: Governance.

guardrails_config

Enterprise-only. Two sub-keys: guardrail_providers (array) and guardrail_rules (array). Full documentation: Guardrails.

alerting

Enterprise-only. Supports channels (array), rules (array), history_retention_days, evaluation_interval_seconds, and webhook_network. Full documentation: Alerting.

access_profiles

Enterprise-only. Defines access profile templates that can later be attached to roles/users.
A profile grants MCP access through two keys:
virtual_mcp_id is accepted as an alternative to virtual_mcp_name and wins when both are set. Ids are assigned by the database, so prefer the name in a file that has to be portable across environments.
mcp_tool_groups, mcp_servers, and mcp_tool_overrides are the deprecated former spellings. They are still read and folded into virtual_mcps / mcp_configs at load time, with a warning in the startup logs. mcp_tool_groups is ignored when virtual_mcps is present; mcp_servers becomes a ["*"] allowlist for each listed client, except where mcp_configs already names that client. The new model has no exclude concept, so an mcp_tool_overrides entry with "action": "exclude" only narrows the tools Bifrost can enumerate for that client.

governance.roles

Enterprise-only. Declares RBAC roles, the access profiles they grant, their data access scope, and their permissions.
Resource and operation names must match Bifrost’s own spelling exactly. Resources are PascalCase - VirtualKeys, PromptRepository, Teams, Customers, BusinessUnits, AccessProfiles, Users, RBAC, APIKeys, Logs, AuditLogs, MCPGateway, RoutingRules, GuardrailsConfig, and so on. Operations are normally Create, View, Update, and Delete; a few resources add their own, such as Reveal on Logs, Download on AuditLogs, and CreateStandalone on VirtualKeys.
A permission Bifrost does not recognise is skipped with a warning in the startup logs, not rejected. A misspelling like virtual_keys or read leaves the role without that permission instead of failing the sync, so check the logs after editing this section.
The access_profiles list is the full set of profiles the role grants. On each sync Bifrost attaches any that are missing and removes any that are no longer listed, so editing the list is how you change what a role grants. Note that an explicit empty list ("access_profiles": []) means “grant nothing” and removes every profile from the role — leaving the field out entirely is different, and falls back to the deprecated access_profile.
Switching a role from access_profile: "X" to access_profiles: ["X"] is a no-op — Bifrost treats the two as the same declaration, so nothing re-syncs on upgrade.

governance.business_units

Enterprise-only. Declares business unit definitions and their governance.
This section defines business units, not who belongs to them. Members are users, and they are added by an admin or by your identity provider — not from config.json, which cannot reference users that do not exist yet at startup. See User Provisioning.

cluster_config

Enterprise-only clustering settings for multi-node deployments. Full documentation: Cluster.

config_store, logs_store, vector_store

Storage backends. Each has enabled (boolean), type (string), and config (object). Full documentation: Storage.

framework

Controls model pricing catalog sync and background model discovery:

Background model discovery

Each provider’s model list is fetched at startup and whenever you add, edit, or delete a key. live_models_sync_interval additionally re-fetches it on a timer, so a model a provider starts serving after the gateway booted becomes routable without a restart. Every node runs its own refresh, because the model list is cached in process memory rather than in the database. Each pass costs two list models calls per enabled key, per provider, so raise the interval if a provider meters that endpoint. The interval is jittered by ±10% to keep replicas that booted together from calling every upstream at the same instant. Set it to 0 to turn the timer off entirely. Model discovery then happens only at startup and on key edits, and you can trigger it on demand from the Providers page.

mcp

Declares the catalog of MCP servers Bifrost connects to. Each entry in client_configs is one MCP server.
Common fields on each client_configs entry: Auth-type-specific fields: The schema enforces these pairings: oauth_config is rejected on non-OAuth auth types, per_user_header_keys is rejected on any auth type other than per_user_headers, and token_exchange is rejected on any auth type other than token_exchange — a misplaced block fails $schema validation instead of being silently ignored.
Enterprise only: auth_type: "token_exchange" in config.json is rejected on OSS — the client is skipped entirely at boot with an error logged naming it. Declare token_exchange clients via the API/Web UI on an enterprise deployment instead if you need them in a non-enterprise config.json environment during a migration.
Migration note: oauth_config_id is no longer a valid field on MCP client entries in config.json. Older guidance for shared OAuth suggested checking it in after completing an OAuth flow — remove it from existing config files (declare an oauth_config block instead, or leave the client to the dashboard). Bifrost now ignores the field if present (with a warning at boot): the OAuth link is managed server-side and survives restarts and config re-syncs on its own, and $schema-based editor/CI validation rejects the field.
Clients declared with auth_type in {oauth, per_user_oauth, per_user_headers, token_exchange} boot into a pending_verification state. The MCP Gateway UI surfaces an Authorize / Verify CTA on each pending row; one admin click runs the same verification flow the Web UI Create form uses, after which the client transitions to healthy. The same steps are scriptable via POST /api/mcp/client/{id}/initiate-verification (OAuth types), POST /api/mcp/client/{id}/verify-headers (per-user headers), or POST /api/mcp/client/{id}/verify-exchange (token exchange). Verified state is server-side and survives restarts and config re-syncs. Immutable fields (auth_type, connection_type, connection_string, stdio_config, oauth_config) cannot be changed after creation — file edits to them are ignored with a boot warning naming the fields, matching the update API; delete and re-declare the client to change them. See MCP Auth and Connections, States & Lifecycles.

mcp.virtual_mcps

Virtual MCPs bundle tools from one or more client_configs into a single endpoint served at /mcp/<endpoint_slug> and attachable to virtual keys. Reconciled into the config store at load.
When source_of_truth is config.json and mcp.virtual_mcps is present, it is authoritative for vMCPs: any stored vMCP absent from it is removed, and an explicit "virtual_mcps": [] prunes them all. Omitting mcp.virtual_mcps leaves stored vMCPs unchanged. In split mode the file creates and updates vMCPs but never prunes runtime-managed ones. See Source of Truth.
mcp.tool_groups is the deprecated former name for this key, kept for backward compatibility. It carries legacy attachment arrays (team_ids, customer_ids, user_ids, provider_names, api_key_ids) and does not expose endpoint_slug. Prefer mcp.virtual_mcps; when both are present, mcp.virtual_mcps wins and mcp.tool_groups is ignored.

websocket

Optional tuning for the WebSocket gateway (Responses API WebSocket mode, Realtime API). WebSocket is always enabled.

Minimal Valid Config