Repository navigation
feat(dashboard): open the dashboard to every user and gate widgets by permission - #1103
Merged
sfmskywalker merged 5 commits intoOct 1, 2026
Merged
Conversation
… permission Every signed-in user can open the Dashboard (#1099): the page and its menu item no longer require dashboard:view. Each widget is shown only to users permitted to see its data, and hidden from everyone else. - DashboardWidgetDescriptor gains an init-only RequiredPermissions (visible with any of them; none declared means everyone) and AddDashboardWidget a trailing requiredPermissions parameter. Built-in widgets declare dashboard:view or the view permission of their data (workflows/instances, diagnostics/structured-logs, diagnostics/console-logs); the OpenTelemetry widget, which loads from its own API, declares diagnostics/opentelemetry:view. - The page requests only what its visible widgets need, from endpoints the user may call (elsa-core#8561): nothing without a widget, the overview for any widget, and the workflow instance endpoints only with dashboard:view or workflows/instances:view. - A section the backend withholds (Capability Unauthorized, now also on the runtime and workflow instance sections) is left out rather than reported. The runtime chip needs dashboard:view or workflows/runtime:view. - A user with no visible widget gets a welcome panel with shortcuts to the pages they can open, in navigation order, or the no-pages notice. - IFeatureService.IsInitialized lets the page tell widgets that are still being registered from no widgets at all, so the welcome panel does not flash while remote features initialize. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on refused instance endpoints - Stop waiting for feature initialization after a few seconds so hosts that never initialize them settle on the welcome. - Load the overview for a user who may only read the runtime status and show it above the welcome shortcuts. - Keep the overview when an instance endpoint answers 401/403; the widgets needing the refused part show nothing. - Cache the permitted widgets, degrade the welcome when the menu fails, and have GetPages return normalised hrefs. - Keep the original AddDashboardWidget signature and add a permissions overload; pin WorkflowRuntime to WorkflowPermissions.Runtime. - Share one StubFeatureService across the dashboard tests and add the page-level permission matrix. - Reconcile the PRD, blueprint and README with the final behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…age lifetime - Re-check disposal inside the queued callback and swallow the exceptions of a torn-down dispatcher. - Load the instance endpoints only when a permitted widget declares workflows/instances:view. - Keep the OpenTelemetry widget gated by diagnostics/opentelemetry:view only, and document it. - Reword the welcome copy, cover its menu-failure branch, hide a withheld backend label. - Inject TimeProvider (registered by the module); simplify WhenRefusedAsync and RequiredScope. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
…e same scope Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 1, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1099
The Dashboard, the landing page, was all-or-nothing:
dashboard:viewor an access-denied page. Now every signed-in user can open it, and each widget shows only to users permitted to see its data. The design decisions are recorded on #1099: hidden rather than disabled, gated by the data's own permission, and a welcome panel when nothing is visible.Requires elsa-workflows/elsa-core#8562, which gates the dashboard API per section. Merge that first or together with this. Against an older core, restricted users with a visible widget would get "No access" from the overview.
Change
Access: the Dashboard page and its menu item no longer require
dashboard:view.Widget permissions:
DashboardWidgetDescriptorgainsRequiredPermissions(init-only). A widget is visible when the user holds any of them; none declared means everyone; unknown permissions fail open, as everywhere in Studio.AddDashboardWidgetkeeps its signature and gains an overload that takes the permissions, so already-compiled callers keep working.UserPermissions.HasAnyis new.Built-in widgets declare
dashboard:viewplus the permission of their data:workflows/instances:viewfor the instance metrics, trends, recent activity and needs-attention widgets;diagnostics/structured-logs:viewanddiagnostics/console-logs:viewfor the log summaries.The OpenTelemetry widget declares only
diagnostics/opentelemetry:view, because its figures come from the OpenTelemetry API, whichdashboard:viewnever opened. The README records this.Runtime status (the header chip) shows with
dashboard:vieworworkflows/runtime:view, including for a user with no widget.Only the data the page needs. The overview loads for any visible widget or the runtime chip. The four workflow-instance endpoints load only when a visible widget declares
workflows/instances:viewand the user holds it ordashboard:view.Nothing refused is shown as an error.
Unauthorizedis left out.Welcome panel. A user with no visible widget sees "No dashboard widgets are available to your role" with shortcuts to the pages they can open, in navigation order (
MenuServiceExtensions.GetPages, returningMenuPage). With no pages at all, the existing no-pages notice shows. If the menu fails, the panel shows without shortcuts and logs a warning.Late widgets.
IFeatureService.IsInitialized(a default interface member, forwarded byEnvironmentAwareFeatureService) tells "still registering" apart from "none".TimeProvider, registered by the module), so hosts that never initialize features settle to the welcome panel. Widgets that register later still appear.Page lifetime. The page re-checks disposal inside its queued callback, and disposes its timer and subscription on disposal.
PermissionPageGuard's landing redirect (feat(shell): send users who can't view the landing page to their first accessible page #1093) stays as a generic fallback for hosts whose/is another gated page. The Dashboard no longer triggers it.The Dashboard README (permission mapping for widget authors),
doc/DASHBOARD_ARCHITECTURE_BLUEPRINT.mdandspecs/007-operational-dashboard/prd.mddescribe the access model.Tests
DashboardPagePermissionTestschecks, for each case, which widgets render and which endpoints are called:dashboard:view, including on a host with only diagnostics widgets (overview only);DashboardWelcomeTestscovers the menu failing.DashboardWidgetRegistrationTestshas a theory over every built-in widget's permissions, plus pin tests tying the mirrored workflow permission constants toWorkflowPermissions.UserPermissions.HasAnyandIsInitializedin both feature services.InvokeAsyncinline, so that window can't be reproduced, and the guard is covered by review.dotnet test Elsa.Studio.sln -f net10.0: all green (Dashboard 106). The touched multi-targeted projects build for net8.0.🤖 Generated with Claude Code