Skip to main content
v2.1.1

Changelog

v2.1.1 moves the enterprise gateway onto OSS transports v2.1.1 and fixes two governance problems. Dead-node archival no longer loops forever on a foreign-key violation when a snapshot still references a budget that config.json reconciliation deleted. The virtual-key creation policy endpoint now resolves the caller’s role by user ID, so RBAC-whitelisted routes stop treating every user as ungoverned. The OSS base adds Claude Cowork proxy support, an opt-in per-component overhead histogram, and upstream-authenticated identity for MCP server auth.

✨ Features

  • Access Profile Budgets Include Active Overrides - The agent usage endpoint now reports an access profile’s budget limit and available amount from the effective limit (base limit plus any active budget override), so a granted override is visible to the edge agent instead of only the base cap.
  • MCP JWT Passthrough on Slug Routes - Bifrost-issued MCP tokens sent to /mcp/<slug> now pass through inference middleware to the MCP gateway handler under enforce-auth, matching the existing behaviour on the base /mcp path. Sibling routes that only share the /mcp prefix (for example /mcp-other) are still rejected with 401.
  • SCIM Discovery Error Details - When the identity provider rejects a token exchange during SCIM OAuth discovery, the RFC 6749 error and error_description fields are surfaced in the API error and the wizard UI, for example Token exchange failed: invalid_grant (Authorization code expired).
  • Guardrail Provider Rename - The Lakera guardrail provider is presented as Checkpoint across the guardrails configuration views, sheets, and form fragments in the enterprise UI.

🌎 Open Source Features

  • Claude Cowork Proxy Support - claude-cowork user agents are identified as the Claude Cowork app in logs and dashboards, and text documents that Cowork sends as base64 data URLs (text/* and JSON media types) are decoded into Anthropic text document sources on both the chat and Responses paths instead of being forwarded as opaque base64.
  • Overhead Component Histogram - New opt-in bifrost_overhead_component_microseconds histogram in the Prometheus and OTel exporters, split by overhead_component and enabled with overhead_breakdown_enabled on the telemetry and OTel plugin config. It is off by default and requires active tracing because it is computed from completed spans. The Prometheus and OTel observability forms gain the toggle, and the UI latency breakdown renames the scheduling category to miscellaneous. Docs
  • Upstream-Authenticated Identity in MCP Server Auth - When an upstream auth layer has already verified the bearer and stamped the user onto the request, the MCP server accepts that identity first instead of rejecting the foreign JWT on an unknown key ID. OAuth strict mode is excluded and still verifies every token itself.
  • Standalone Virtual Key RBAC Operation - New CreateStandalone RBAC operation on virtual keys decides whether a role may create keys outside access-profile governance. The virtual key sheet locks the governance fields and applies the access profile for roles without it.

🐞 Fixed

  • Dead-Node Archive Foreign-Key Loop - Archiving a dead governance node failed forever with a governance_node_archives foreign-key violation when the node’s usage snapshot still referenced a budget or rate limit that boot-time config.json reconciliation had deleted. The archive transaction now locks candidate parent rows with FOR KEY SHARE, skips rows whose parent is gone, persists the survivors, and folds baselines only from what was written. A node whose rows are all stale is archived as empty and evicted. Affected clusters self-heal on the first cleanup tick after upgrade.
  • Virtual Key Creation Policy on Whitelisted Routes - The getMyVKCreationPolicy check used the request-context role ID, which RBAC-whitelisted routes never hydrate, so every user was reported as ungoverned. Permissions are now resolved by user ID through a new HasUserPermission method; a user whose role is not yet in the RBAC cache is treated as lacking the permission.
  • API-Key Users Got Local-Admin Permissions Without SCIM - getCurrentUserPermissions now falls through to the role-based response when no SCIM provider is enabled but the request carries an authenticated user ID, so API-key owners receive their actual role permissions and entity DAC instead of the all-data local-admin defaults.
  • Bedrock Tool Result Documents - Document blocks inside tool results are preserved when converting to Bedrock Converse instead of being dropped; explicitly unsupported formats, or required documents with neither inline data nor a fetchable URL, are rejected up front.
  • MCP JWT Identity per Token Mode - MCP JWTs no longer record every mode as an MCP token credential on the grant: vk-mode tokens settle as the virtual key they name, user-mode tokens attribute the request to the user, and session-mode tokens record nothing so they are refused when authentication is enforced.
  • Streaming First-Chunk Peek Ignored Context - The wait for a stream’s first chunk now observes the request context, so a cancelled request returns 499 and an expired deadline returns 504 immediately instead of pinning the provider worker until stream_idle_timeout_in_seconds elapsed.
  • Dependency Upgrades - google.golang.org/grpc bumped to v1.83.2 across all Go modules.

🗄️ Database Migrations

  • No new database migrations in this release.

🐙 Closed OSS Issues

  • #5661 - Anthropic document blocks are dropped from Bedrock tool results
  • #6974 - Streaming first-chunk peek and drain wait ignore context, pinning workers for up to stream_idle_timeout

📀 Base OSS version

transports/v2.1.1 (pinned as github.com/maximhq/bifrost/transports v1.6.12-0.20260909115640-b013460d4dd1), with core v1.8.6, framework v1.6.2, governance v1.7.2, and logging v1.7.2.

🔌 If you are compiling plugin against this release - use following deps