You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add Share Dashboard alongside the existing query-sharing feature.
The generated link must contain a self-contained snapshot of one Dashboard and all queries/specs required by its panels, so another user can open the link without access to the sender's workspace storage.
Feasibility and transport limit
This is feasible for small and medium Dashboards because the payload can live in the URL fragment. A fragment is handled by the browser and is not sent in the HTTP request, so nginx, ingress, proxy, and server request-line limits do not apply.
There is no universal URL-size guarantee across browsers and receiving applications. Current browser engines permit much more than ordinary messaging/share surfaces, but that theoretical limit is not an appropriate product contract:
Chromium navigation is capped at roughly 2 MiB;
WebKit applies a roughly 2 MiB URL/fragment limit;
Firefox standard URLs are capped at roughly 1 MiB, while its platform-share helper refuses URLs longer than 65,535 characters;
chat, mail, ticketing, QR, clipboard, and mobile share targets may impose smaller undocumented limits.
Use an application-level maximum of 65,535 characters for the complete generated URL, including origin, route, query string, separator, and fragment. Do not rely on the browser's larger navigation ceiling.
The existing query-share codec serializes JSON and applies uncompressed Base64, which expands bytes by about one third. Dashboard sharing must compress before Base64url encoding; otherwise even modest multi-query Dashboards will exceed the share cap.
If the final URL exceeds the cap, do not copy or present a link that may be truncated. Show a clear message and direct the user to the existing Export Dashboard JSON path instead.
Payload contents
Build the snapshot from the existing single-Dashboard portable dependency closure:
the selected Dashboard document;
exactly the saved queries referenced by its tiles;
each query's SQL, Spec version, and complete Spec;
Dashboard layout, panel order, presentation data, variable option SQL, and revision as already represented by the portable bundle.
Do not include:
unrelated Library queries;
other Dashboards;
workspace id/key/name;
query results or result caches;
ClickHouse session ids, credentials, tokens, or connection configuration;
runtime Dashboard variable values;
transient editor/tab state.
Reuse buildDashboardExportBundle and the portable-bundle validation/canonical encoding path rather than introducing a second Dashboard snapshot model.
The bundle's internal Dashboard/query/tile ids are required to preserve references inside the snapshot. They are payload-local while the link is open and must not be written directly into the recipient's workspace.
Wire format
Add a separate, versioned Dashboard-share envelope. Do not overload the existing query-share tag.
The encoding pipeline should be:
Build one Dashboard's portable dependency bundle.
Canonically encode and validate it, omitting optional schema hints/metadata where safe to reduce size.
Compress the UTF-8 JSON with one explicitly versioned algorithm supported by the application.
Encode the compressed bytes as unpadded Base64url.
Place the tagged payload in the URL fragment.
Measure the complete final URL and require it to be at most 65,535 characters before copying/sharing it.
The decoder must:
identify the Dashboard-share tag and version;
Base64url-decode;
decompress with a strict output bound;
decode through decodePortableBundleJson and the existing structural/semantic validators;
require exactly one Dashboard and its valid dependency closure.
Keep the existing portable decoded-size/depth limits. Decompression must abort once the decoded output would exceed the portable 20 MiB limit, so a short compressed fragment cannot act as a decompression bomb.
Malformed, unsupported, truncated, oversized, or semantically invalid payloads must fail closed with a useful error and must not partially open or persist resources.
Opening a shared Dashboard
Opening the link must create a temporary shared Dashboard session and render it in Dashboard View mode.
Do not automatically import or commit it into the current workspace.
Do not merge its queries with the Library.
Do not overwrite an existing Dashboard or query with the same id.
The sender's workspace route/key is not authoritative for the recipient.
Panel execution uses the recipient's current ClickHouse connection and permissions.
The UI should clearly indicate that this is a shared snapshot and is not saved locally.
An explicit Add to workspace action may use the existing portable import planner, including id remapping and conflict handling, but automatic import is forbidden. The first implementation may leave Add-to-workspace as a follow-up if the shared snapshot can be viewed and its panel queries can be opened safely without persistence.
Opening a panel query in the Workbench should create an unsaved/transient tab from the shared snapshot; it must not silently create a Library query or bind to an unrelated local query with the same id.
OAuth round trip
The fragment is lost when navigating to an OAuth provider. Generalise the existing shared-query OAuth stash so a Dashboard-share payload survives authentication:
stash the original tagged share payload in sessionStorage before OAuth navigation;
bind it to the OAuth attempt/state;
restore it only after a valid callback;
retain it on a recoverable failed callback/retry;
clear it after successful consumption or explicit logout;
never merge a query-share and Dashboard-share payload.
A Dashboard share opened while already signed in must not touch the OAuth stash.
Share UX
Add Share Dashboard to the Dashboard's existing share/action surface.
On success:
copy the complete link using the same user-visible confirmation as query sharing;
optionally use the native share sheet where already supported by the existing share flow;
warn that anyone with the link can read the embedded SQL and Dashboard configuration.
On oversize:
report the encoded URL length and the 65,535-character limit;
do not put the oversized value on the clipboard or invoke the native share API;
offer or point to Export Dashboard JSON.
Security and privacy
Treat the payload as untrusted input on decode.
The fragment is not sent to the web server, but it is visible to the recipient, browser history, extensions, clipboard managers, and any application through which the link is shared.
Make it explicit that the link is a bearer copy of the SQL/configuration and provides no access control or revocation.
Never include credentials, auth tokens, result data, or runtime parameter values.
Do not execute panel SQL before normal authentication, configuration, validation, and Dashboard execution gates complete.
Acceptance criteria
A Dashboard action generates a self-contained link containing the Dashboard and exactly its panel-query dependency closure.
The existing portable Dashboard export builder and validators are reused.
The payload uses a distinct versioned Dashboard-share tag.
Canonical JSON is compressed and encoded as unpadded Base64url.
The complete generated URL is rejected when longer than 65,535 characters.
Oversized Dashboards produce no copied/shared link and direct the user to Dashboard JSON export.
Decode enforces the existing 20 MiB decoded JSON and depth limits during decompression, not only after allocation.
Invalid, truncated, unsupported, or semantically invalid payloads fail closed.
Opening a link renders a temporary shared Dashboard without modifying the recipient's workspace or Library.
Shared payload ids cannot collide with or bind to local resources.
Panel queries use the recipient's connection and ordinary execution/security gates.
Opening a shared panel in the Workbench does not create or overwrite a Library query implicitly.
Dashboard-share payloads survive a required OAuth round trip and are consumed only by the matching callback.
Query sharing remains backward compatible and query/Dashboard payloads have deterministic precedence.
The UI states that the link embeds readable SQL/configuration and has no access control or revocation.
Unit tests cover canonical encoding, compression round trip, exact URL boundary, malformed/truncated data, decompression bounds, dependency closure, and OAuth restoration.
E2E tests share and open a multi-panel Dashboard without persisting it, plus verify the oversized fallback.
CHANGELOG.md and Dashboard sharing/security documentation are updated.
Non-goals
A server-hosted short-link or shared-object service.
Access control, expiry, revocation, or audit history for links.
Sharing query results or cached data.
Automatically importing the shared Dashboard into the recipient's workspace.
Raising the portable-bundle 20 MiB resource limit.
Related: existing query sharing and Dashboard portable import/export.
Goal
Add Share Dashboard alongside the existing query-sharing feature.
The generated link must contain a self-contained snapshot of one Dashboard and all queries/specs required by its panels, so another user can open the link without access to the sender's workspace storage.
Feasibility and transport limit
This is feasible for small and medium Dashboards because the payload can live in the URL fragment. A fragment is handled by the browser and is not sent in the HTTP request, so nginx, ingress, proxy, and server request-line limits do not apply.
There is no universal URL-size guarantee across browsers and receiving applications. Current browser engines permit much more than ordinary messaging/share surfaces, but that theoretical limit is not an appropriate product contract:
Use an application-level maximum of 65,535 characters for the complete generated URL, including origin, route, query string, separator, and fragment. Do not rely on the browser's larger navigation ceiling.
The existing query-share codec serializes JSON and applies uncompressed Base64, which expands bytes by about one third. Dashboard sharing must compress before Base64url encoding; otherwise even modest multi-query Dashboards will exceed the share cap.
If the final URL exceeds the cap, do not copy or present a link that may be truncated. Show a clear message and direct the user to the existing Export Dashboard JSON path instead.
Payload contents
Build the snapshot from the existing single-Dashboard portable dependency closure:
Do not include:
Reuse
buildDashboardExportBundleand the portable-bundle validation/canonical encoding path rather than introducing a second Dashboard snapshot model.The bundle's internal Dashboard/query/tile ids are required to preserve references inside the snapshot. They are payload-local while the link is open and must not be written directly into the recipient's workspace.
Wire format
Add a separate, versioned Dashboard-share envelope. Do not overload the existing query-share tag.
The encoding pipeline should be:
The decoder must:
decodePortableBundleJsonand the existing structural/semantic validators;Keep the existing portable decoded-size/depth limits. Decompression must abort once the decoded output would exceed the portable 20 MiB limit, so a short compressed fragment cannot act as a decompression bomb.
Malformed, unsupported, truncated, oversized, or semantically invalid payloads must fail closed with a useful error and must not partially open or persist resources.
Opening a shared Dashboard
Opening the link must create a temporary shared Dashboard session and render it in Dashboard View mode.
The UI should clearly indicate that this is a shared snapshot and is not saved locally.
An explicit Add to workspace action may use the existing portable import planner, including id remapping and conflict handling, but automatic import is forbidden. The first implementation may leave Add-to-workspace as a follow-up if the shared snapshot can be viewed and its panel queries can be opened safely without persistence.
Opening a panel query in the Workbench should create an unsaved/transient tab from the shared snapshot; it must not silently create a Library query or bind to an unrelated local query with the same id.
OAuth round trip
The fragment is lost when navigating to an OAuth provider. Generalise the existing shared-query OAuth stash so a Dashboard-share payload survives authentication:
sessionStoragebefore OAuth navigation;A Dashboard share opened while already signed in must not touch the OAuth stash.
Share UX
Add Share Dashboard to the Dashboard's existing share/action surface.
On success:
On oversize:
Security and privacy
Acceptance criteria
CHANGELOG.mdand Dashboard sharing/security documentation are updated.Non-goals
Related: existing query sharing and Dashboard portable import/export.