From 8a8fb685a2ef67e5e4dde9d07a66ea3e24a082d6 Mon Sep 17 00:00:00 2001 From: Rajendra kadam Date: Tue, 7 Jul 2026 18:08:50 +0530 Subject: [PATCH] Show managed account host action for observers (#48748) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Related issue:** Resolves #48077 Removes the admin/maintainer role gate from the "Show managed account" host action so observers see it too. The backend (`GetHostManagedAccountPassword`) authorizes any user who can read the host, so observers can already retrieve the managed local account password via the API — the UI gate only hid the action. `canShowManagedAccount` now matches the other "show secret" host actions (disk encryption key, Recovery Lock password), which are not role-gated; the premium / macOS / connected-to-Fleet-MDM / ADE-enrollment / managed-account-status conditions are unchanged. Before (global observer, ADE-enrolled macOS host with a verified managed account): Before: observer's Actions menu without Show managed
account After (same host, same observer): After: observer's Actions menu with Show managed
account # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests — two cases in the existing "Show managed account action" block asserting the action renders for a global observer and a team observer (they fail against the old gate). - [x] QA'd all new/changed functionality manually — ran a local server with a seeded ADE-enrolled macOS host carrying a verified managed local account row; logged in as a global observer: the action was absent before the change and present after (screenshots above), and opening the modal shows the managed account credentials, matching what the API already returns to observers. ## Summary by CodeRabbit * **Bug Fixes** * Expanded access to the **Show managed account** action for users with observer-level host read permissions. * The managed account option now appears correctly for global observers and team observers when other eligibility checks are met. * Improved consistency between what the interface shows and what backend permissions allow. --- .../48077-observer-managed-account-action.md | 1 + .../HostActionsDropdown.tests.tsx | 62 +++++++++++++++++++ .../HostActionsDropdown/helpers.tsx | 11 ++-- 3 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 changes/48077-observer-managed-account-action.md diff --git a/changes/48077-observer-managed-account-action.md b/changes/48077-observer-managed-account-action.md new file mode 100644 index 0000000000..ef4ac861b9 --- /dev/null +++ b/changes/48077-observer-managed-account-action.md @@ -0,0 +1 @@ +- Fixed observers not seeing the "Show managed account" action on a macOS host's details page, even though the API already allows them to view the managed local account password. diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx index 5011bd9af1..8aaf42da98 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/HostActionsDropdown.tests.tsx @@ -2108,6 +2108,68 @@ describe("Host Actions Dropdown", () => { expect(screen.getByText("Show managed account")).toBeInTheDocument(); }); + it("renders the action for a global observer (the API authorizes any host-reader)", async () => { + const render = createCustomRenderer({ + context: { + app: { + isGlobalObserver: true, + isPremiumTier: true, + currentUser: createMockUser(), + }, + }, + }); + + const { user } = render( + + ); + + await user.click(screen.getByText("Actions")); + + expect(screen.getByText("Show managed account")).toBeInTheDocument(); + }); + + it("renders the action for a team observer", async () => { + const render = createCustomRenderer({ + context: { + app: { + isTeamObserver: true, + isPremiumTier: true, + currentUser: createMockUser(), + }, + }, + }); + + const { user } = render( + + ); + + await user.click(screen.getByText("Actions")); + + expect(screen.getByText("Show managed account")).toBeInTheDocument(); + }); + it("hides the action when managed local account is not enabled", async () => { const render = createCustomRenderer({ context: { diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx index ff8104fee2..c312706ab2 100644 --- a/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx +++ b/frontend/pages/hosts/details/HostDetailsPage/HostActionsDropdown/helpers.tsx @@ -388,10 +388,6 @@ const canShowManagedAccount = (config: IHostActionConfigOptions) => { const { isPremiumTier, isConnectedToFleetMdm, - isGlobalAdmin, - isGlobalMaintainer, - isTeamAdmin, - isTeamMaintainer, hostPlatform, hostMdmEnrollmentStatus, isManagedLocalAccountEnabled, @@ -403,7 +399,12 @@ const canShowManagedAccount = (config: IHostActionConfigOptions) => { if (!isManagedLocalAccountEnabled && !config.managedAccountStatus) { return false; } - return isGlobalAdmin || isGlobalMaintainer || isTeamAdmin || isTeamMaintainer; + // Not role-gated: the backend authorizes this action for any user who can + // read the host (including observers), matching the other "show secret" + // actions above (disk encryption key, Recovery Lock password). Restricting + // it to admins/maintainers here hid the action from observers even though + // the API returns the managed account password to them. + return true; }; const canClearPasscode = (config: IHostActionConfigOptions) => {