Changelog
What's new in QueryDesk
Features, improvements and fixes in every release, newest first.
Features
- A TerraDesk Reservation can be held by a Role, and an Approval from any one member of that Role satisfies it.
- A Database has its own AI timeout, so AI queries no longer run under a credential's Timeout.
Improvements
- Schema syncs run in the background, so the query page and agent tools open from the stored schema without waiting on the database.
- Invalid SQL errors give the line and column in the text you sent, in the editor and in agent query results.
Bug Fixes
- A member with several roles is now redacted by all of their roles' Data protection policies combined. Before, one role's policy was picked and redaction could differ between runs.
- Deleting a Database deletes its Shared queries, so the Shared queries page opens again.
- A failed GitHub token request (suspended or uninstalled GitHub app, or a GitHub outage) no longer crashes imports, webhooks, and TerraDesk plans.
Bug Fixes
- SQL that cannot be parsed under a data protection policy now fails with a readable "Invalid SQL" error that points to the position in the statement.
Bug Fixes
- The service account token dialog now appears in Safari after creating or rotating a token.
Features
- Super admins can set connection parameters on a Postgres database, such as
pgdog.role=replica. Also available through the API and the Terraform provider. - Admins can issue a scoped service account token for unattended MCP agents.
- A lightweight tunnel agent that only handles network access, published as its own image and versioned with Devhub.
Improvements
- Redesigned navigation and modals.
- The QueryDesk audit log names who approved each query and when.
- Members without the Auditor permission see only their own queries in the QueryDesk audit log.
- A database that refuses a connection, or whose tables can't be listed, now says why.
- Refusing a filter on a CTE or derived-table output names the redacted column behind it, and the Data protection panel opens on the refused query.
- Applying a Postgres connection string keeps the database's other credentials and reports which settings were applied.
- Pending queries show the error when an approved query is rejected by the database.
- Connected apps leads with distinct users and counts each session once.
- A TerraDesk resource policy's approval count replaces the workspace baseline for the resources it governs.
- The helm chart's default
POOL_SIZEis higher.
Bug Fixes
EXPLAIN (GENERIC_PLAN)on a statement with$nplaceholders returns the plan instead of failing silently.- SQL the tokenizer rejects shows a readable error in QueryDesk instead of crashing.
- Two schema syncs of the same database at once both finish without an error.
- An inherited data protection policy always redacts exactly as its source policy does.
- The Workflow API returns
group, so Terraform stops re-planning it.
- Super admins can set connection parameters on a Postgres database, such as
Features
- Roles can now grant super admin, manager, or billing admin to everyone in the role.
- Seat automation: billing admins can reveal a license key under Settings > Billing and use it to add or remove seats from automated flows such as Okta workflows.
Improvements
- QueryDesk now shows Postgres tables from every schema, not just
public, across autocomplete, the table list, structure view, data protection policies and the AI assistant. Tables outsidepublicare grouped into schema folders. - The QueryDesk AI assistant now knows which columns are redacted, so it no longer writes queries against data it can't read. It can also tell a masked value from an empty one.
- The QueryDesk AI assistant and query completion now know today's date in your timezone.
- Database settings now confirm when a change has been autosaved.
Bug Fixes
- Queries against Postgres views now run under data protection instead of failing.
- Deleting a database no longer fails when data protection policies are assigned to it or inherited by it.
- System tables on an AI policy's allowlist are no longer redacted in AI queries.
- Unredaction requests and QueryDesk Slack messages now show a user's email when the user has no name.
- License calls from organizations with many seats no longer fail with a "header too large" error.
Bug Fixes
- Role settings pages no longer error when a role grants access to a resource that has since been deleted or archived.
- Deleting a database now removes the role permissions that referenced it, so they no longer linger.
Features
- TerraDesk workspaces can now declare additional trigger paths, so a push or pull request that touches files outside the workspace's own folder still starts a plan. Configurable from workspace settings and via the Terraform provider.
- QueryDesk flags databases whose last connection attempt failed, with a warning icon in the database list that updates live as connections recover or fail.
Bug Fixes
- Databases dialed by IP address with certificate verification enabled no longer fail the TLS handshake.
- Queries using a
VALUESclause as a table no longer have its columns masked, which previously produced wrong results — notably join predicates that silently returned no rows.
Improvements
- Terraform runner jobs now talk to Devhub over the internal cluster network instead of the public address, so plans work on installs behind an authenticating proxy and plan files never leave the cluster.
- Terraform runner pods no longer carry a Kubernetes service account token into Terraform runs.
Bug Fixes
- Retrying a Terraform plan no longer collides with the job left behind by the previous attempt.
- A plan upload or download that gets rejected now fails the run immediately with a clear error, instead of appearing to succeed and failing confusingly later.
- An apply that can't start now says so on the plan itself rather than only going red.
- Google workload identity settings are validated when saved: the provider ID must be a real one (not the pasted-in template) and can't be enabled with missing values.
- Saving workspace settings without changing any field no longer errors.
- Failed init containers no longer flood the server log with errors.
- Users whose email isn't all lowercase are now correctly matched to their license seat.
- On a linked install, someone who already holds a seat can sign in instead of being stuck as pending.
Bug Fixes
- License seats that were assigned without an email can now be identified and revoked from the users settings page, so you're no longer billed for seats you can't release.
Features
- OIDC group claim and requested scopes are now configurable, so providers like Okta that send group membership under a different claim (or only when asked for) can drive Devhub roles. Both can be set in Settings or declaratively through the Helm chart.
Improvements
- License seats are now identified by email, so one person takes a single seat across installs that sign in through different identity providers. The users list shows seat holders by email address instead of an opaque provider ID.
- Connected Applications and refresh-token reuse settings are now grouped per application rather than per connection, so revoking access signs an app out on every machine, and allowing reuse keeps covering the app as it re-registers. The list shows how many registrations and users are behind each app, and an allowance stays visible so it can be switched off even when nobody is currently connected.
- Users with no name (common with OIDC logins) now show their email address wherever a name was expected — approvers, avatars, and the policy people picker — and can be searched by it.
Bug Fixes
- OIDC logins now send and verify a state parameter, protecting the sign-in callback from forged requests.
Bug Fixes
- Fixed users signing in through header-based authentication being repeatedly bounced back to the home page after logging out once.
Features
- Drifted resources on a drift run now expand to show Terraform's own diff for each one, so you can see exactly what changed outside Terraform without digging through the raw log.
Improvements
- The drift detection list links each workspace to its drift run, so you can open the run behind any status — including one still in progress.
- Starting a drift run from workspace settings takes you straight to the run, where its log streams live.
- Drift results are now grouped and badged the same way plan changes are, with modules collapsing under a header and a badge for replaced resources.
Bug Fixes
- The drift schedule summary in workspace settings updates immediately after saving instead of continuing to say drift detection is off.
Features
- Drift detection for Terraform workspaces. Turn on a schedule per workspace and Devhub runs a refresh-only check against your default branch, reporting exactly what changed outside Terraform. A new Drift detection page groups every workspace by standing — needs attention, checking now, in sync, not checked — and each workspace page gets drift tiles showing the current count, when it was last checked, and how many resources it manages. Drift runs never apply and never wait on approval; to fix drift, tick the affected resources and start a targeted plan that goes through the normal approval gate. Optional Slack notification posts only when drift is actually found, and drift settings are configurable through the Terraform provider.
Improvements
- Applying a plan now cancels every other pending plan in that workspace, on any branch, since they were all built against state the apply moves. A new plan on a branch no longer cancels a targeted plan someone scoped to a handful of resources.
- The resource inventory is now rebuilt from Terraform's own state after every apply, so it's exact rather than inferred — including after targeted applies. A failed apply automatically refreshes the inventory it may have left inconsistent.
- User pickers for approvals, dashboards, roles, workflows, and resource policies now only offer people who can actually sign in. Someone already named on a policy who has since been archived stays visible, marked "No longer active", so they can be removed.
Bug Fixes
- Workspace commands that override the image entrypoint (e.g.
op run -- terraform) are now used when listing state, so those workspaces can read their inventory. - Failed Kubernetes pods with no container status no longer crash log retrieval.
- A query that fails before it runs is recorded as failed history instead of lingering as a pending query.
Features
- Terraform resource policies — set stricter approval requirements for specific Terraform resources, matched by address pattern or picked by hand, on top of a workspace's baseline. Each action (create, update, delete, replace) gets its own approval count and named approvers, and plans show exactly which policy is holding an apply back and why. People named on a policy can approve the changes it governs even without workspace approve permission.
- Download query results as CSV — AI-run queries can return an expiring download link so result rows can be pulled straight into a file or script instead of read inline.
- Data protection rules can match any enum column — one rule now covers every enumerated column in a database, rather than needing a rule per enum type.
- Databases are reachable by their API id — links like
/querydesk/databases/pr-1234/querywork for databases created through the API, with no lookup needed. - Allow refresh token reuse per connected app — admins can exempt a specific OAuth client from being signed out when it replays an already-rotated refresh token, for clients that would otherwise be permanently unable to reconnect.
Improvements
- Redesigned the Terraform plan page: resource changes are now a filterable table showing what each change does, which policy governs it, and how many approvals it needs.
- Redesigned the targeted plan picker with search, collapsible modules, and per-resource approval requirements.
- Workspace settings are now split into General, Variables, and Approvals tabs, with resource policies togglable per workspace and a live count of governed resources.
- Refreshing a workspace's Terraform inventory no longer blocks the page while it runs.
Bug Fixes
- ClickHouse queries now respect their configured timeout instead of running unbounded, and a timed-out query is no longer silently re-run on a new connection.
- Queries selecting from a CTE built on a UNION (or with an explicit column list) no longer have those columns wrongly redacted.
Features
- TerraDesk workspaces can now post to a Slack channel when a plan finishes and is waiting on a human, with reactions tracking the plan's progress (✅ ready to apply, 🚀 applied, ❌ canceled). Choose whether every plan notifies or only plans on the repository's default branch.
Features
- TerraDesk workspaces can now run custom init containers before Terraform and override the image entrypoint with a custom command (e.g. wrap Terraform in
op run), configurable in workspace settings and the Terraform provider. - TerraDesk secrets can be marked "raw" to be exposed under their literal name instead of the
TF_VAR_prefix, for tooling that reads its own environment. - TerraDesk posts a Slack message when a plan needs approval and reacts on it as the plan is approved (✅), applied (🚀), or canceled (❌); the channel and whether to notify for all plans or only default-branch plans are set per workspace.
Improvements
- Tables keep their horizontal scroll position when you sort, so you stay looking at the same columns.
Bug Fixes
- Slack notifications for long queries and plans no longer fail to send; oversized text is truncated instead of Slack rejecting the whole message.
- TerraDesk workspaces can now run custom init containers before Terraform and override the image entrypoint with a custom command (e.g. wrap Terraform in
Features
- New organizations are now guided through a one-screen setup that walks them through connecting their first real database — pick the engine, enter connection details, test the connection, and finish — before the app opens. Teammates without permission to connect a database see a waiting message instead. Cloud installs are told which IP address their database must allow, and can create a network agent right from the setup screen.
Improvements
- Attempting to expand a masked column into rows (for example with
UNNESTorjsonb_array_elements) now returns a clear message naming the offending column instead of an error from the database.
Bug Fixes
- Signing out now fully ends your session on the server, so a session captured before logout can no longer be used to stay signed in.
- Fixed the passkey approval prompt appearing on the wrong item when multiple approvals were on screen; the prompt is now tied to the specific action you clicked.
- Columns produced by a
LATERALsubquery in QueryDesk are no longer incorrectly masked. - Fixed the query toolbar clipping its settings dropdown; the toolbar buttons now scroll while the dropdown stays fully visible.
- Attempting to expand a masked column into rows (for example with
Improvements
- Running a workflow action from a dashboard now keeps you on the dashboard and shows a "View run" button that opens the run in a new tab, instead of navigating you away from your data.
Bug Fixes
- A slow or stalled query parser now returns a clear timeout error instead of crashing the query submission, and can no longer hold up other queries.
- Fixed a race where a newly connected agent could briefly report as offline to anything checking its status right as it connected.
Bug Fixes
- Uptime monitoring now automatically resumes checking a service if its recurring check was ever lost (for example, after a service was re-enabled or a background worker stopped mid-check), so services no longer silently stop being monitored.
Features
- Bypass a required review on a query. A super admin can now run their own query that hasn't met its review requirement by explicitly acknowledging the override. Every bypass is recorded against the query, called out in the pending queue and audit log (which can now be filtered to bypasses only), and posted to the database's Slack channel. It's off by default per database, configurable in database settings, the REST API, and Terraform.
Improvements
- Uptime monitoring no longer requires the separate request-tracer sidecar service, so self-hosted deployments have one fewer container to run.
Bug Fixes
- Uptime checks now record a service as down — and keep checking it on schedule — when a request can't complete (connection refused, DNS no longer resolves, expired certificate), instead of erroring out.
- Data protection policies now apply to
EXPLAIN/EXPLAIN ANALYZEqueries, closing a path that could otherwise reveal protected data. - Fixed SSL/TLS connections to MySQL and SQL Server databases, both when testing a connection and when running queries.
- Fixed the Postgres proxy failing to connect when a client's SSL request arrived in the same packet as the handshake.
- Oracle table browsing now applies sorting before the row limit, so you get the correct rows rather than an arbitrary set.
- Query result columns holding vector (pgvector) and composite types now display correctly.
- Query plan view now shows hash-join conditions and CTE names.
- SQL Server table filters using "contains"/"does not contain" now handle column names correctly.
- Dashboard editor now reflects the new value when you edit an action's input mapping, instead of showing the stored one.
- The "lines changed" metric can be filtered by file extension again.
- In workflows requiring multiple approvals, the approve button now targets the step that's actually awaiting approval.
- OAuth authorization for connected AI/MCP clients now rejects redirect URLs containing a fragment and correctly blocks IPv4-mapped IPv6 addresses that resolve to private hosts.
- AI chat now surfaces an error if a conversation or message fails to save, rather than failing silently.
Features
- Added AI assistant tools for query sharing: create a shareable link to a query (optionally with its results), list and open shared queries, and delete a share to revoke its link.
- Added an AI assistant tool to retrieve the saved results of one of your own past queries.
Improvements
- The share-query dialog now remembers all of your choices — restricted access, whether to include results, and the expiry toggle and timeframe — so they carry over the next time you share a query.
Bug Fixes
- Workflow API steps now wait up to five minutes for a response instead of timing out after 15 seconds, and a connection failure is recorded on the step instead of crashing the run and silently re-running the step.
Bug Fixes
- Running a query that was deleted before it could execute now fails cleanly instead of crashing.
- TerraDesk no longer runs Terraform plans for archived workspaces when a push or pull request comes in.
Bug Fixes
- Fixed a crash when displaying query variables for a workflow run, including runs with older-format parameters or a deleted database credential.
- OAuth token refresh no longer fails when two refresh requests race; the conflicting request now retries automatically instead of erroring.
Features
- Added a per-policy allowlist for system tables, letting admins grant specific catalog tables (e.g.
pg_stats,information_schema) an exception from data masking when a tool genuinely needs them. - Added a "Verify server hostname" option for database SSL connections (Postgres
sslmode=verify-full), requiring the server certificate's hostname to match the connection host.
Improvements
- Database SSL connections now validate the server's certificate chain against a configured CA certificate instead of only encrypting the connection.
Bug Fixes
- A single slow query no longer blocks other queries running against the same database credential.
- Data protection now fails closed: queries the masking engine can't fully model (such as
PREPARE,COPY,DO,CALL, and cursor statements) are rejected rather than passed through unmasked. - The QueryDesk Postgres proxy now rejects function-call and COPY messages that could return data outside a maskable query, and closes connections on oversized or unexpected messages.
- Hardened Postgres proxy authentication: unknown users and bad passwords now return the same error to prevent user enumeration, clients requiring channel binding are properly refused, and the authentication nonce is verified.
- Fixed AI chat error handling so failed or crashed query recommendations show a clear error, and results from an old conversation no longer leak into a newly started one.
- Added a per-policy allowlist for system tables, letting admins grant specific catalog tables (e.g.
Features
- Row actions on dashboard panels — add buttons to each row of a query panel that trigger a workflow, mapping values from the row's columns or prompting the user for input when the button is clicked.
- Table structure view in QueryDesk — a new "Structure" tab for any table showing its columns, full declared types, defaults, constraints (primary keys, foreign keys, not-null), and indexes across Postgres, MySQL, SQL Server, Oracle, and ClickHouse.
- Browse referenced records — foreign key columns in the table view now show a link that opens the record the key points to.
- Date range shortcuts — the dev portal date picker gains one-click presets (This quarter, Last quarter, Year to date, Last 30 days, Last 90 days).
- Labels when saving a query — the Save Query dialog now lets you assign existing labels or create new ones inline.
Improvements
- Dev portal remembers your filters — the selected team and date range now carry across My portal, Change lead time, Throughput, Quality, Planning, and Export instead of resetting on each page.
- Query history infinite scroll — the query history panel now loads pages as you scroll rather than showing only a fixed list.
- Filter the audit log by database user — a new filter narrows audit log entries to the database login a query ran as, scoped to the selected database. The in-app AI assistant can filter audit-log searches the same way.
- Responsive QueryDesk layouts — the query view, AI chat, query library, and table list now adapt to smaller screens with collapsible sections instead of fixed panels.
- Export defaults to your last-used date range rather than a fixed window.
Bug Fixes
- Large LiveView payloads (big SQL scripts, large cell edits) no longer crash the connection due to WebSocket size limits.
- Retrying an OAuth token refresh whose response was never received no longer revokes the whole session; a short grace period re-issues tokens instead, while disconnecting an app or detecting real token reuse still revokes immediately.
- The data protection panel no longer lingers over results from a later query that isn't covered by a policy.
- TerraDesk jobs now provide a writable home directory so tools like Helm no longer fail trying to cache to a read-only location.
Features
- Data protection transparency and access requests: After running a query, a new data protection panel shows which columns a policy redacted, with a before/after view of the query. You can request access to any redacted column directly from the query or table view — an admin is notified in Slack and can approve or deny the request from the policy page. Approving a request reveals the column going forward. The AI assistant can also file the same access request on your behalf when you ask it to.
- Set up a database from a connection string: Database settings now let you paste a connection string (e.g.
postgresql://user:pass@host/db) to auto-fill the connection fields for Postgres, MySQL, ClickHouse, SQL Server, and Oracle. - Delete TerraDesk workspaces: Super admins can now delete a workspace from its settings page; deleted workspaces are archived and removed from workspace lists.
- OIDC via Helm chart: Self-hosted installs can configure OIDC single sign-on through the Helm chart. When managed this way, the OIDC settings page becomes read-only so it's clear the values come from your deployment.
Improvements
- Workflow run details now display the parameter values used for each query step.
- The account timezone picker now uses the full, current list of time zones from your browser.
Bug Fixes
- Fixed an error when syncing the schema of databases with a very large number of columns or indexes.
Features
- AI data protection policy for databases — you can now assign a data protection policy that applies to every AI query against a database. It combines with the acting user's own policy, with the stricter redaction winning per column, so the AI can be limited regardless of who it acts as (including super admins).
Improvements
- Shared queries now use a relative expiry (e.g. "30 Days" or "6 Hours") instead of picking an exact date and time, and your chosen timeframe is remembered and pre-filled the next time you share a query.
Bug Fixes
- Closed a privilege-escalation hole: only super admins can now grant elevated permissions or assign roles. Managers and other users can no longer escalate permissions when inviting, creating, or updating users.
- The role settings page no longer errors when a role includes members imported from GitHub or Linear who don't have a login account; they now display by their integration name.
- Locked onboarding steps can now be skipped, so onboarding is no longer a dead-end.
Features
- Data protection now allows selecting columns from derived-table subqueries used in
FROM/JOINclauses, so queries that aggregate over inline subqueries run without being blocked.
Bug Fixes
- Fixed primary key detection during database schema introspection so key columns are identified correctly, including when tables with the same name exist in different schemas.
- Fixed a data protection gap where a CTE or subquery reusing a real table's name could expose that table's protected columns; masking is now applied correctly in all cases.
- Data protection now allows selecting columns from derived-table subqueries used in
Improvements
- Added in-app instructions for connecting an external AI client (such as Claude or Cursor) to DevHub over MCP, including a copyable MCP endpoint on the Connected Apps settings page and a "Connect via MCP" option in the QueryDesk AI chat.
- Cell value previews in the data table now open in a copyable, scrollable modal instead of a hover tooltip, making it easier to read and copy long values.
- MCP clients now see which AI tools are read-only versus write-capable, so they can flag state-changing actions before you approve them.
- The license sharing settings now list every installation sharing a license (highlighting the primary install), show linked installs what they're connected to, and only offer the relevant linking controls for each install.
Features
- Connect external AI clients (such as Claude Desktop or Cursor) to Devhub through a new MCP server with OAuth authorization, letting an AI assistant run queries, sample tables, browse schema, search saved queries, and review query history and audit logs — all bound by the same per-user permissions, redaction, and approvals as a person.
- Added a guided onboarding experience for QueryDesk: a welcome prompt and a persistent checklist that walks new users through running their first query, connecting a database, inviting teammates, and setting up approval flows.
- Added a Connected Apps settings page where you can see the applications you've authorized and revoke their access.
- You can now share one license (and its seat pool) across multiple installations by generating a link token, so users are only billed once across installs.
- Query results can now be retained and re-opened later from query history, with a configurable retention period per database.
Improvements
- You can now invite a brand-new user (and assign them a license) directly from the access screens for users, dashboards, databases, roles, and workflows, instead of having to invite them separately first.
- Databases now have AI configuration controls: enable or disable AI access, cap the rows an AI query may return, set a result-memory limit, and choose which credentials the AI may use.
- Database credentials can now have their own query timeout that caps how long any query (or AI query) may run.
- Data protection rules can now match columns by type (for example, allowlist every boolean column), in addition to matching by name.
- AI-generated queries are now badged as "AI" in pending queries and the audit log so you can tell them apart from human-run queries.
- Added a Help menu and a keyboard-shortcuts reference to the navigation.
- Added clearer empty-state guidance (with documentation links) across QueryDesk pages including dashboards, labels, shared queries, the audit log, the query library, pending queries, and AI chat.
Bug Fixes
- Fixed a data protection bypass where referencing a whole row (via
row_to_json,to_jsonb, casts, or bare row aliases) could expose values from columns that should have been redacted.
- Fixed a data protection bypass where referencing a whole row (via
Features
- Inherit data protection policies across databases — define a policy once on a primary database, mirror it to replicas, and changes propagate automatically by matching tables and column names.
Improvements
- Press Cmd/Ctrl+Enter from a variable input in the Query Library to run the query.
- Specify a custom branch when running a targeted Terraform plan instead of always using the repository's default branch.
Bug Fixes
- AI chat copy button now copies the formatted message exactly as displayed, preserving SQL formatting.
- Long data protection policy edit modals now scroll properly on smaller screens instead of being cut off.
Bug Fixes
- Fix bug with query selection
Features
- Reserve a Terraform workspace so that no
applycan run on it without your explicit approval. Reservations are visible on the workspace and plan pages, indicated with a lock icon in the workspaces list, and can be released by the reserver or a super admin.
- Reserve a Terraform workspace so that no
Features
- Database transactions — Start an explicit transaction from the query editor (Postgres and MySQL), run one or more queries inside it, then Commit or Rollback as a single atomic unit.
Bug Fixes
- Multi-statement streaming queries now stop on the first error rather than continuing to execute subsequent statements.
- Query errors during streaming are now correctly recorded on the query record.
Bug Fixes
- Fix an issue with queries running slow when there are lots of permissions and data protection policies
Features
- Coverbot now supports uploading coverage data per subdirectory and consolidates results across them, so monorepos can report a single coverage figure per commit.
- Multi-statement SQL queries are now first-class and properly detected: each statement is tracked individually, executed with its own parameters, and shown together in run results, history, audit logs, and pending query views.
- Database pickers now group databases (with optional priority pinning) and sort entries alphabetically with user-pinned items first.
Improvements
- Query editor: pressing Enter now inserts a newline instead of accepting an autocomplete suggestion.
- Run-query modal cleanup: removed the "combine to single query" toggle and only shows the Analyze option when running a single statement.
- Default query limits are now applied by injecting a dialect-aware
LIMIT/FETCH FIRST/TOPinto the SQL itself, with comments preserved on each returned statement. - Cursor-based query selection is more accurate, including handling of leading comments, dollar-quoted function bodies, and ranges spanning multiple statements.
Bug Fixes
- The Postgres proxy now returns a proper Postgres
ErrorResponsewhen query protection fails, instead of crashing the connection. - Query history streaming no longer drops empty result sets — tables render correctly even when a query returns no rows.
- Failed queries now record the actual error message instead of a generic "Failed to parse query" string.