Skip to main content
v1.4.13
Breaking changes in v1.4.0. See the v1.4.0 Migration Guide for full before/after examples, automatic migration details, and a step-by-step checklist before upgrading.

Changelog

Built on transports/v1.5.16, this release adds richer observability and cost attribution, makes SCIM provisioning durable and resumable, surfaces clearer conflict errors across the dashboard, and tightens access-profile and cluster behavior.

✨ Features

  • Business-unit & user attribution in traces - The BigQuery and Datadog plugins now carry business_unit_id, business_unit_name, user_id, and user_name, so cost and usage can be sliced by org unit and by individual. Fields are added to the BigQuery TraceRow schema/proto/Save() map and as Datadog metric and span tags.
  • Durable background job runner for SCIM provisioning - Provisioning (user import, team sync, business-unit sync) now runs as resumable background jobs via a new sidekiq runner that persists state to a sidekiq table and checkpoints after each page. Every IdP (Okta, Entra, Google, Keycloak, Zitadel, SailPoint) gains a paginated FetchUsersPage. The import/sync handlers return 202 with an operation_id, and GET /api/scim/provision/jobs/{operation_id} exposes job status; progress is still broadcast over WebSocket and relayed to peer nodes in clustered deployments.
  • Datadog session-grouped traces - A new group_traces_by_session option groups all requests sharing the same x-bf-session-id header into a single Datadog APM trace, by pinning each request’s root span to a deterministic trace ID derived from the session ID via SHA-256. An inbound W3C traceparent always takes precedence.
  • Cluster node region exposed - Each node’s region (from gossip metadata) is now returned by the cluster API and rendered in the node card footer and dead/orphan side panel in the UI (omitted when empty).
  • Update permission on the Logs resource - Adds (Logs, Update) to RBAC and grants it to Admin so POST /api/logs/recalculate-cost is reachable. Ships with the ent_add_logs_update_permission migration to grant it on existing installs.
  • Inline name-conflict errors - 409 conflict responses now render inline beneath the name input for access profiles, API keys, MCP tool groups, prompt deployments, roles, business units, and teams, instead of a generic toast. The error clears when the name is edited or the sheet is reopened.
  • Auto-assign access profile to existing role members - When a role’s access profile is set via config-file reconciliation, existing holders of that role now get virtual keys created and the access profile assigned, matching the API handler path.
  • Group search in sync filters - The provisioning sync sheet gains a real-time group search input, a “No groups match your search” empty state, a total group count on “Sync from all”, and an X of Y groups selected indicator.

🐞 Fixed

  • Governance access-profile reload ghost rebase - Access-profile reloads no longer double-count ghost-node usage after save/propagate. Reloads now split into a per-node config/mapping refresh and a leader-only usage baseline rebase.
  • 409 Conflict on duplicate names - Unique-constraint (duplicate name) violations across resource create/update endpoints now return 409 Conflict instead of 500 (API keys, business units, guardrail rules, MCP tool groups, RBAC roles, users, teams).
  • Okta provisioning robustness - Multi-group users are deduplicated so Processed counts unique users; the client honors Okta’s Retry-After on 429 (falling back to exponential backoff); and getNextLink uses PeekAll to handle multiple separate Link headers.
  • List Models access-profile filtering - ListModelsRequest now bypasses provider/model allowlist enforcement (skipProviderCheck), fixing spurious “model not allowed” errors and AP model filtering when no virtual key is present.

📀 Base OSS version

transports/v1.5.16

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