v2.1.46
Changelog
- Removed GitHub App authentication from GitHub Copilot provider keys: Bifrost now ignores
github_copilot_key_config(app_id,installation_id,repository_id,private_key,github_domain). Migrate before upgrading: put a fine-grained personal access token (github_pat_…, with the Copilot Requests account permission, from an account with an active Copilot plan or assigned Copilot seat) or a GitHub OAuth token (ghu_…/gho_…) in the key’svalue; a key that relied on the App fields no longer authenticates. - Added
bifrost.mcp.maxProtocolVersion(mcp.max_protocol_version), one ofauto,2026-07-28,2025-11-25or2025-06-18: the newest MCP protocol version offered to MCP servers.bifrost.mcp.clientConfigs[].maxProtocolVersion(mcp.client_configs[].max_protocol_version) overrides it for one server. Upgrading a deployment that already has MCP servers caps them at2025-06-18, the version they used before; setautoto offer the newest version. bifrost.mcp.clientConfigs[].tokenExchange(mcp.client_configs[].token_exchange) withoutclientIdis now refused unlessuseIdpCredentials: trueorprofile: id_jag. Such a config never worked: Bifrost’s own config validation rejected what the chart rendered.- Added
profile: id_jagtobifrost.mcp.clientConfigs[].tokenExchange(mcp.client_configs[].token_exchange.profile) for Cross App Access to MCP servers (Enterprise): Bifrost gets an ID-JAG for the user from the identity provider and redeems it at the MCP server’s authorization server. Setaudienceto that authorization server’s issuer andresourceClientId(resource_client_id) to Bifrost’s client there.resourceTokenEndpointis discovered from the issuer when left empty. AddresourceClientSecretorresourcePrivateKeyunless Bifrost is a public client. - Added
bifrost.mcp.clientConfigs[].promptsToExposeand.resourcesToExpose(mcp.client_configs[].prompts_to_expose/resources_to_expose): which of an MCP server’s prompts and resources the MCP gateway serves,["*"]for all and[]for none. A new server serves everything when the field is omitted; on an existing server, omitting it keeps the stored list. - Added
openapias abifrost.mcp.clientConfigs[].connectionType, configured byopenapiConfig.spec,.specFile,.specUrl,.baseUrl,.securityCredentials,.includeDeprecatedand.maxResponseBytes. Renders intomcp.client_configs[].openapi_config.spec/spec_file/spec_url/base_url/security_credentials/include_deprecated/max_response_bytes. Bifrost builds an MCP server from an OpenAPI or Swagger document, with each API operation as a tool; operations the document marks deprecated are skipped unlessincludeDeprecated: true.specFileis read relative tobifrost.appDir, so mount it withvolumes/volumeMounts.authTypecan only benone,headersorper_user_headers. The connection type existed in Bifrost but had no Helm path, so it could only be added from the dashboard. - Added
storage.logsStore.objectStorage.formatand.compression(logs_store.object_storage.format/compression) to write offloaded log payloads as Parquet instead of JSON.formatisjsonorparquet;compressionisnoneorgzipfor JSON, andnone,gzip,snappyorzstdfor Parquet. Parquet works on S3 and Azure; GCS stays JSON-only. - Added
azureas atypeforstorage.logsStore.objectStorageandbifrost.auditLogs.objectStorage(logs_store.object_storage/audit_logs.object_storage):bucketis the Azure Blob container, with eitherendpoint(Azure identity) orconnectionString. For logs,existingSecretwithconnectionStringKeyreads the connection string from a Kubernetes Secret. - Added
storage.logsStore.matviewRefreshTempFileLimit(logs_store.config.matview_refresh_temp_file_limit), for example"10GB": Postgrestemp_file_limitfor materialized-view refreshes. The cap applies to each Postgres process, and parallel workers each get it, so keep cap × (workers + 1) well under free disk. It needs superuser orGRANT SET ON PARAMETER temp_file_limit. - Added
postgresql.primary.extraArgs(server settings such as["-c", "max_connections=200"]; changing them restarts the PostgreSQL pod),postgresql.primary.persistence.annotationsandpostgresql.primary.persistence.volumeAttributesClassNameto the bundled PostgreSQL. Pod-spec only, no config.json change. - Added
bifrost.relays(top-levelrelays): raw HTTP relays to non-LLM APIs such as Tavily, Exa or AWS Textract, served at/relay/{name}/.... Bifrost adds the relay’s credential, prices each counted call and charges it to the caller’s budgets. Entries render as written. WithsourceOfTruth: config.json, an explicit list (including[]) removes stored relays it doesn’t name, and their grants with them; leave the key out to keep stored relays. A repeated name fails the render. Grants are checked for identified callers only: withbifrost.client.enforceAuthOnInference: false, a request that carries no credential is relayed without any grant check. - Added
relay_grants: [{relay_name: ...}]tobifrost.governance.virtualKeys[],bifrost.governance.projects[]andbifrost.accessProfiles[](relay_grants), the relays a caller can reach. Like the rest of the entry, the list in your values is the whole list whenever that key, project or profile syncs from config.json: when its entry changes, or on every start withsourceOfTruth: config.json. Leavingrelay_grantsout then means no grants, so list any grant made in the dashboard that should stay. A grant naming a relay that doesn’t exist is skipped with a warning on a virtual key; a project or access profile naming one is skipped as a whole. A virtual key whose team, customer or user is governed by an access profile (Enterprise) takes its relays from that profile, and its ownrelay_grantsare not applied; grant the relay on the profile. - Added
podDisruptionBudget(top-level value):enabled: truekeeps at leastminAvailable(default1) Bifrost pods running through node drains and cluster upgrades. SettingmaxUnavailablereplacesminAvailable, somaxUnavailable: "100%"lets every replica be evicted. Rendered only in cluster mode, and needs at least 2 replicas. No config.json change. - Added
bifrost.scim.config.crossAppAccess(scim_config.config.crossAppAccess, every identity provider; Enterprise): lets AI clients your identity provider admits sign in to Bifrost as the user, by exchanging the provider’s ID-JAG for a Bifrost token. Takesenabled,accessTokenTtl(60-86400 seconds, default one day) andprovisionUsers. It needsbifrost.client.oauth2ServerConfig.issuerUrl, the governance plugin, and an identity provider that issues ID-JAGs (such as Okta). Previously both the values schema and config.schema.json rejected it, so it could only be set from the dashboard. - Added
bifrost.scim.config.tokenExchangeHosts(scim_config.config.tokenExchangeHosts, Enterprise): the hosts, besides the identity provider’s own, that an MCP server’s token exchange may be sent to. Previously both the values schema and config.schema.json rejected it, so it could only be set from the dashboard. - Added
bifrost.scim.config.accessProfileResolutionStrategy(scim_config.config.accessProfileResolutionStrategy, Enterprise):ordergrants only the profiles of the first attribute rule a user matches; the default,all, grants every match. Previously both the values schema and config.schema.json rejected it, so it could only be set from the dashboard. - Added
bifrost.scim.config.syncAllUsers(scim_config.config.syncAllUsers, Okta, defaulttrue): which users Okta directory sync keeps.truekeeps every user assigned to the Okta app except suspended and deactivated ones;falsekeeps active users only. Directory sync runs only whenapiTokenis set. Previously the values schema rejected it, so it could only be set from the dashboard. - Added
bifrost.client.skipAccessProfileUserVirtualKeyCreationand.skipAccessProfileUserVirtualKeyDeletion(client.skip_access_profile_user_virtual_key_creation/skip_access_profile_user_virtual_key_deletion, Enterprise):truestops giving users a virtual key with their first access profile, and keeps their virtual keys when their last profile is removed. - Added
disable_content_loggingtobifrost.governance.projects[](governance.projects[].disable_content_logging): turns request and response content logging on or off for a project’s traffic, overriding the virtual key. Omit it to inherit. - Added the
sagemakerprovider (Amazon SageMaker real-time endpoints) tobifrost.providers(providers.sagemaker). Setsagemaker_key_config.region; leave outaccess_keyandsecret_keyto use the default AWS credentials (for example IRSA). Models are endpoint names. - Added
use_speech_endpointsanduse_voice_live_endpointstoazure_key_config(providers.azure.keys[].azure_key_config):truesends speech and transcription to Azure AI Speech, and realtime sessions to Azure Voice Live. An alias can override either. - Added
bifrost.providers.<name>.passthrough.allowed_routes(providers.<name>.passthrough.allowed_routes): limits which HTTP passthrough routes reach a provider, bypath(*and/**globs) and optionalmethods. An empty list forwards nothing. - Added
bifrost.warp(top-levelwarp): configures the dashboard’s Warp assistant (model and provider, limits, embeddings, log search and topics). Warp also needsbifrost.featureFlags.warp.enabled: trueand a vector store. - Added
bifrost.disableOnboarding(disable_onboarding):truehides the dashboard’s setup checklist for every user. It is read from config.json on every start, so it holds on stateless deployments.

