v2.1.44
Changelog
- Added
bifrost.auditLogs.omitIpAddresses(defaultfalse) to stop recording client IP addresses in audit logs while keeping the rest of the audit trail. IPs stored before the flag was turned on are hidden from the API, filter data, search and exports, and archive copies written after the change omit them, but they stay in the database and in archive objects already written. Renders intoaudit_logs.omit_ip_addresses. - Added
excluded_attributesto the OTEL, Datadog, Kafka, Pub/Sub, Splunk and BigQuery plugin configs (bifrost.plugins.<connector>.config.excluded_attributes, andprofiles[*].excluded_attributesfor OTEL). Names span attributes to leave out of exported traces, matched exactly (e.g.gen_ai.request.tools), for dropping large attributes that are not needed downstream. Unmatched names are ignored. On BigQuery these are column names (tools) rather than attribute names, because BigQuery writes typed columns; the column stays in the table schema and is left empty, andtrace_id/timestampare rejected. Renders intoexcluded_attributes. - Added
bifrost.plugins.bigquery.config.export_raw_payloadsandbifrost.plugins.otel.config.export_raw_payloads(alsoprofiles[*].export_raw_payloads), defaultfalse. Stores the raw provider request and response bodies. Requires the provider’sstore_raw_request_responseand is suppressed bydisable_content_logging. Previously the field existed in Bifrost but had no Helm path, so it could not be enabled from a declarative install. Renders intoexport_raw_payloads. - Added
bifrost.agents[]— declarative A2A agent registrations rendered into the config.jsonagentssection. Each entry takesname,agent_card_url, and optionallytenant,enabled,allow_by_default,forward_accepted_credential,forward_accepted_credential_overrides_auth,discovery_auth,runtime_auth,extension_uris, andvirtual_key_ids. Reconciled by name on startup: created if absent, updated when the declaration changes, and left alone otherwise (merge mode). Whenbifrost.sourceOfTruthisconfig.jsonandagentsis present, stored registrations absent from the rendered list are removed; setagents: []to remove all stored registrations. - Added
bifrost.client.a2aExternalClientUrl(a2a_external_client_url) — Bifrost’s public base URL for served agent cards and A2A push-notification callback URLs. Push notifications stay disabled while unset. Supportsenv.syntax. - Added
bifrost.server.a2aGrpcBaseDomain(a2a_grpc_base_domain) andbifrost.server.a2aGrpcPort(a2a_grpc_port) — enable the shared A2A gRPC listener; per-agent hostnames are advertised as<agent-name>.<base-domain>:<port>. gRPC stays disabled while either is unset. - Added
bifrost.server.a2aAllowPrivatePushCallbacks(a2a_allow_private_push_callbacks) — lets A2A push delivery reach loopback and private network callback targets. Off by default; intended only for controlled development and test environments. - Added
storage.logsStore.clickhouse.maxQuerySize(renders intologs_store.config.max_query_size), the ClickHousemax_query_sizesetting in bytes. Defaults to 16 MiB so team-scoped log reads with thousands of member and virtual key ids no longer fail against the 256 KiB server default. - Added
bifrost.governance.complexityAnalyzerConfig.decision(renders intocomplexity_analyzer_config.decision): a decision-model classifier for the complexity router.providerandmodelselect the decision model (defaulttypesafe/jev-latest). Supported providers are Typesafe (Jev), OpenAI (gpt-6-luna, also on a custom provider withbase_provider_type: openai), OpenRouter (the decision models it serves, such as~typesafe/jev-latest), Cloudflare (Clef:@cf/cloudflare/clef,@cf/cloudflare/clef-flash), Perplexity (pplx-decider-*), and Ollama (locally pulled System One models:nimble,tev1,clef,clef-flash,laya). Laya and Nimble (by Bespoke) can also be served by a custom provider withbase_provider_type: typesafe. Requests go through Bifrost’s/v1/decisionsto the selected provider’s native decisions endpoint, using that provider’s own credentials.criteriaholds per-tier overrides of the shippeddefinition,signals, andexamples, keyed bySIMPLE,MEDIUM, orCOMPLEX(exact case). Any tier or field left out sends the shipped default; a definition is at most 500 characters, and each list at most 12 items of 300 characters. - Added the
cloudflareprovider (Cloudflare Workers AI) tobifrost.providers. Every key needscloudflare_key_config.account_id(supportsenv.); the base URL defaults tohttps://api.cloudflare.com/client/v4. It serves chat completions, Responses, embeddings, model listing, and Clef decisions (@cf/cloudflare/clef,@cf/cloudflare/clef-flash). - Added
bifrost.mcp.toolManagerConfig.maxInstructionsPerClientand.maxInstructionsTotal(max_instructions_per_client/max_instructions_total) to bound forwarded MCP server instructions in bytes; 0 keeps the built-in defaults. - Added
access_profiletobifrost.governance.customers[],.teams[], and.businessUnits[](renders intogovernance.{customers,teams,business_units}[].access_profile), the enterprise access profile the entity holds in place of its own budgets and rate limit. bifrost.governance.roles[].dacand.entity_dacnow acceptbusiness-unit-dataandcustomer-data(governance.roles[].dac/entity_dac).- Documented
ttft_timeout_msonbifrost.governance.routingRules[].targets[](governance.routing_rules[].targets[].ttft_timeout_ms) in the values schema. - Added
bifrost.proxyConfig(renders into the top-levelproxy_config): the global outbound proxy from the dashboard’s proxy settings page, includingenableForScim(enable_for_scim),enableForInferenceandenableForApi; reconciled with the same config hash as the other sections. - Added
bifrost.scim.config.attributeProjectMappings({ attribute, value, project }, every SSO provider) — renders intoscim_config.config.attributeProjectMappings. Every matching rule adds the user to that project by name (projects are never auto-created); memberships a rule added are removed when it stops matching, while members added from the dashboard are kept. - Added
bifrost.scim.config.bulkSyncInterval(default24h, every SSO provider) — renders intoscim_config.config.bulkSyncInterval. How often the directory reconcile deprovisions users the IdP no longer returns: whole days or h/m/s pairs (12h,1h30m,7d), between 1h and 30d. Inert when SCIM is enabled or the provider has no directory API access. - Added
bifrost.mcp.toolManagerConfig.codeModeLimits(maxSourceBytes,maxSteps,maxMemoryBytes,maxLogBytes,maxToolCalls,maxValueBytes,maxNestingDepth) to tune the limits on each code mode execution; an omitted or 0 field keeps the built-in default. Renders intomcp.tool_manager_config.code_mode_limits. Code mode no longer limits concurrent executions. - Added a template-time guard: the chart now fails to render when
bifrost.client.mcpServerAuthModeisoauthorbothandbifrost.client.oauth2ServerConfig.issuerUrl(client.oauth2_server_config.issuer_url) is empty or unset, instead of letting the pod crash-loop on Bifrost’s startup check.env.VAR_NAMEreferences pass. - Added
storage.logsStore.objectStorageExcludeRequestTypes(renders intologs_store.object_storage_exclude_request_types): request types (e.g.list_models) whose logs stay in the logs database in full instead of being offloaded to object storage. Hidden logs are still offloaded. - Added
ignore_provider_costtobifrost.providers.<name>andbifrost.governance.providers[](providers.<name>.ignore_provider_cost/governance.providers[].ignore_provider_cost): ignore the provider-reportedusage.costand price the request from Bifrost’s model pricing and pricing overrides. - Added
storage.configStore.statementTimeout/.idleInTransactionSessionTimeoutand the same pair onstorage.logsStore(config_store.config.statement_timeout,idle_in_transaction_session_timeout, and thelogs_store.configequivalents). Server-side Postgres timeouts on every runtime pool connection, default120s;"0"keeps the server default. - Added
bifrost.client.compat.forceReasoningOnlyModelsToResponses(client.compat.force_reasoning_only_models_to_responses, defaulttrue): routes chat requests to the Responses API for models that cannot reason with tool calls, so reasoning is kept. - Added
bifrost.client.deleteExpiredVirtualKeys(client.delete_expired_virtual_keys, defaultfalse) and per-keydelete_after_expireonbifrost.governance.virtualKeys[]: a daily job deletes virtual keys pastexpires_at; the per-key value overrides the client setting. - Added
disable_content_loggingandbusiness_unit_idtobifrost.governance.virtualKeys[](governance.virtual_keys[]): a per-key content-logging override and the owning business unit (mutually exclusive withteam_id/customer_id). Grant agents to a key from the agent side withbifrost.agents[].virtual_key_ids. - Added
bifrost.client.oauth2ServerConfig.allowedRedirectUris(client.oauth2_server_config.allowed_redirect_uris): exact remote OAuth client callback URIs to allow. Loopback and Cursor callbacks need no entry; other remote callbacks are denied by default. - Added
bifrost.mcp.clientConfigs[].requirePublicTarget(mcp.client_configs[].require_public_target): every connection to the MCP server must resolve to a public address. Once stored as true it is never cleared. - Added
cache_tool_call_responsestobifrost.plugins.semanticCache.config(semantic_cacheplugin config): cache responses that carry tool calls. Off by default, since a replayed tool call runs in another caller’s agent loop. bifrost.governance.routingRules[].fallbacksentries now accept an object{ provider, model, provider_key_name }that pins a provider key, alongside theprovider/modelstring form (governance.routing_rules[].fallbacks).- Added
displayNameto the generic OIDCbifrost.scim.config(scim_config.config.displayName): the login button label (Sign in with <displayName>), defaultSSO. - Added
topologySpreadConstraints(top-level value): pod topology spread constraints rendered into the Bifrost Deployment or StatefulSet pod spec, to spread replicas across nodes and zones. A constraint without alabelSelectordefaults to the release’s server pod labels, so only Bifrost’s own replicas are counted. - Added
extraContainers(top-level value): regular sidecar containers appended to the Bifrost pod after the Bifrost container. Native sidecars (Kubernetes 1.29+) follow the Kubernetes convention, aninitContainersentry withrestartPolicy: Always, and the chart now refuses to render one on clusters older than 1.29 instead of leaving the pod blocked on an init container that never exits.

