Skip to main content

🔔 Notable Changes

  • MCP access policy — Previously, an MCP session could reach whatever the connecting user’s own permissions allowed, with no workspace-level control. You can now choose what MCP sessions may do in the workspace under Integration > MCP > Access policy: Disabled, Read-only, or Read-write. Each user’s own permissions still cap every call.
    • New workspaces start at Read-only. A workspace that has never set a policy stays at Read-write until an admin sets one, so check the setting after upgrading.
    • No mode lets an MCP session change workspace settings, approve issues, or touch credentials. A policy change also applies to clients that are already connected.
    • When you connect an MCP client, the sign-in page shows the workspace policy, and Allow is available only when the policy is Read-only or Read-write.
    • See MCP docs and change details.
  • Inline comments on Plan review — Previously, review feedback lived in the Review Activity feed, detached from the SQL it was about. You can now comment on specific lines of the statement in the Plan detail editor: select lines in the gutter, write the comment, and it starts a thread with replies and Resolve/Reopen, shown both inline and in Review Activity.
    • When the SQL is edited, comments stay on the lines that did not change. Comments on lines that changed or were deleted are marked outdated and kept in Review Activity.
    • You can comment once the issue is submitted for review. A counter shows how many threads are still open, and you can jump from one to the next.
  • Workload identities: any OIDC provider and a required audience — Previously, workload identities supported only GitHub Actions and GitLab CI. You can now use any OIDC issuer, so more of your automation can authenticate without a service account key.
    • An optional JWKS URL covers issuers that do not publish a discovery document.
    • Existing GitHub and GitLab identities: tokens must now carry an audience on the identity’s allowed list, and a wildcard subject pattern must name at least the owner or group (repo:my-org/*, not repo:*). Upgrading adds the audiences that Bytebase-generated and documented pipelines request, so those keep working. An identity whose pipeline requests another audience, such as the GitHub Enterprise Server default, or whose pattern is broader stops authenticating until you update it.
    • The Terraform provider can now authenticate as a workload identity, and bytebase_workload_identity now requires issuer_url, allowed_audiences, and subject_pattern. See the Terraform section.
    • See change details.
  • Audit log: actor identity and refused calls — Two changes for anyone exporting, filtering, or shipping the audit log.
    • The actor of each entry now shows whether it was a user, a service account, or a workload identity (users/{email}, serviceAccounts/{email}, workloadIdentities/{email}); before, everyone was recorded as a user. In the API and exports, the user field is renamed actor, so filter with actor == 'users/bb@bytebase.com' instead of user.
    • Requests denied by a permission check, or blocked outright by the MCP access policy, are no longer saved in the audit log; a query the Read-only MCP policy refuses is still saved, as WARNING. If Enable audit logging to stdout is on (self-hosted only), every refusal is written to stdout as WARNING. Searching the audit log is now itself logged.
    • See audit log docs and change details.
  • API changes — Several v1 API methods are renamed, stricter, or paginated: the login-page restriction endpoint is renamed, listing identity providers now requires authentication, the four BatchGet methods are all-or-nothing, Update methods reject requests whose body disagrees with update_mask, ListTaskRuns is paginated, and GET /v1/mcp/info is removed. Review change details before upgrading an integration.
  • PostgreSQL: data-modifying queries in SQL Editor need DML permission — Some statements look like reads but write data: a SELECT whose WITH clause runs INSERT, UPDATE, or DELETE, and EXPLAIN ANALYZE of a write, which actually executes it. These now need DML permission; query permission (bb.sql.select) alone is no longer enough. See change details.
  • Oracle database link queries now require access to the linked database — Reading a table through a database link (schema.table@link) in SQL Editor, export, or MCP now needs the same grant as querying that database directly. Links to another instance, or to a database Bytebase does not manage, are not supported and are refused before the query runs. See change details.

🚀 Features

  • Query plan visualizer in SQL Editor — Query plans now show in the result pane instead of a pop-up, as text, a diagram, a grid, or a summary, for PostgreSQL, SQL Server, and Spanner. Running EXPLAIN yourself also shows the visual plan, including FORMAT JSON, XML, YAML, and ANALYZE on PostgreSQL. A new maximize button expands the result pane to the full editor height.
    • The SQL Server plan view keeps working after Chrome drops XSLT support in November 2026.
    • The Visualize Explain pop-up action is removed; the plan opens inline. API: explain_format replaces mssql_explain_format — see change details.
  • Last plan editor cannot approve their own change — The user who last edited a plan’s SQL can no longer approve that plan. This is controlled by the project setting Allow approval by the person who last changed the plan: off in new projects, left on for existing projects so nothing changes until you turn it off. When it is off, the last editor is also left out of approval-request notifications. See approval docs.

🎄 Enhancements

  • Instance connection setup is redesigned, with a single Authentication dropdown and inline validation before you submit.
  • Open SQL Editor is now the primary action on the database page, with secondary actions moved into a More menu on narrower screens.
  • Data masking — Built-in semantic types are available without adding them manually, and configuring a column’s semantic type takes one dialog instead of two.
  • Self-hosted — Set annotations on the Bytebase pod with the Helm value bytebase.podAnnotations, for example for Prometheus scraping, and schema sync puts less load on the metadata database.
  • Service accounts: resetting a key is a single step, and a service account can no longer sign in to the web console.
  • SQL Editor AI assistant: chat history is kept per workspace and user (the last 20 conversations), conversation titles are edited inline, and the chat window layout is refreshed.
  • MySQL — gh-ost migrations gain an opt-in Skip metadata lock check option, off by default, with a warning that enabling it can lose writes during cut-over.
  • OceanBase — Approval rules and risk levels that check the SQL type (statement.sql_type) now work for OceanBase changes.

🐞 Bug Fixes

  • Fix wrong affected-rows estimates in plan checks, release checks, and approval and SQL review rules that use statement.affected_rows. Previously, TiDB always reported 0 and CockroachDB reported nothing.
  • SQL Editor — Fix opening SQL Editor by URL or from the API immediately saving an empty “Untitled” saved query.
  • Fix Submit anyway not working when plan checks failed or were canceled and Enforce SQL review is off.
  • MySQL — Fix false syntax errors on Aurora MySQL’s LOAD DATA FROM S3, LOAD XML FROM S3, and SELECT ... INTO OUTFILE S3; on statements that use a keyword such as status as a name, for example SET status = 1 in a stored procedure; and on nested /* comments.
  • MySQL — Fix Aurora and RDS IAM connections intermittently failing during large rollouts because the RDS CA bundle was downloaded on every connection. Bytebase now downloads it once, and uses your own ssl_ca instead when one is set.
  • PostgreSQL — Fix SQL Editor breaking a LIMIT ... OFFSET query when its LIMIT is higher than the SQL Editor row limit.
  • SQL Server — Fix prior backup failing on UPDATE and DELETE with a WITH clause; SQL Editor crashing on stored procedures that return rows and on statements with an OUTPUT clause, and hanging on results over the row limit; and unique indexes syncing as non-unique, which made schema diffs keep proposing to recreate them. The first sync after upgrading shows a one-time diff for those indexes.
  • Oracle/Redshift — Fix viewing the definition of views, functions, procedures, and sequences failing with an unsupported-engine error, and Oracle view definitions missing their INSTEAD OF triggers.
  • TiDB — Fix SQL Editor queries that select _tidb_rowid failing with a data-masking error and triggering a full schema sync on every attempt.
  • Spanner — Fix queries that start with WITH failing in SQL Editor whenever a row limit applies.
  • Doris — Fix schema sync failing on Doris and SelectDB versions that no longer support SHOW FUNCTION STATUS, which left the SQL Editor object browser empty.

🏗️ Terraform

  • Upgrade to provider 3.23.0 after upgrading the server — Migration Guide. No state migration is required.
    • New: bytebase_workload_identity accepts provider_type = "OIDC" and an optional jwks_url.
    • New: the provider can sign in as a workload identity instead of with a service account key: set workload_identity_email plus workload_identity_token or workload_identity_token_file.
    • Now required on bytebase_workload_identity: issuer_url, allowed_audiences, and subject_pattern.

📃 Change Details

MCP

  • GET /v1/mcp/info (WorkspaceService.GetMCPInfo) is removed. Read mcpSetting from GET /v1/actuator/info (ActuatorService.GetActuatorInfo), which requires authentication; an MCP token is not accepted there. The modes, methods, engines, and data_masking_available fields have no replacement.
  • MCP requests larger than 4 MiB are refused with HTTP 413.
  • Upgrading from 3.21 or earlier: each MCP client must sign in again. Sign-ins from before 3.22.0 cannot be refreshed and fail with invalid_grant once the current access token expires. Remove the server from the client and add it again. An MCP capability set through the 3.21 API is not carried over.

Workload Identity

Every workload identity — GitHub, GitLab, or OIDC — now carries the same requirements: an issuer whose keys can be fetched, at least one non-blank allowed audience, and a subject pattern that does not match everything. A pipeline that requests an audience not on the identity’s list stops authenticating; add that audience to the list, or change the pipeline to request one that is. Existing identities get a provider_type based on their subject pattern, and new identities must set provider_type, issuer_url, allowed_audiences, and subject_pattern.

Audit Log

Actor. AuditLog.user is renamed AuditLog.actor (same field number; the JSON key changes from user to actor). Values are users/{email}, serviceAccounts/{email}, or workloadIdentities/{email}; before, every principal was written as users/{email}. In SearchAuditLogs, filter on actor == 'users/bb@bytebase.com' — a filter on user is rejected. The export’s column header changes from user to actor. What is stored, what is streamed. 3.22 stored calls the MCP policy blocked outright in the database; 3.23 streams them instead. A SIEM that reads stdout now sees every refused attempt; the database keeps calls that ran and queries the Read-only policy refused.

API Changes

PostgreSQL SQL Editor Permissions

A SELECT whose WITH clause runs INSERT, UPDATE, or DELETE, EXPLAIN ANALYZE of such a SELECT, and EXPLAIN ANALYZE of a MERGE are classified as DML; bb.sql.select alone no longer runs them. EXPLAIN ANALYZE of a write is authorized per target table, so a table-scoped DML grant covers it. CockroachDB behaves the same. Before 3.23.0, a query that read a table through a database link ran on Oracle; if Bytebase could not find the link’s target, the query failed after running. Now the linked table is checked before the query runs: Under a read-only data source whose Oracle account owns private database links, every linked read is refused. Use the admin data source, or remove that account’s private links.

⚙️ Install and Upgrade

Before upgrading: 1) Back up the metadata — in-place downgrade is not supported. 2) Do not run multiple containers on the same data directory. 3) Terraform users: upgrade Bytebase server first, then apply the new Terraform config.