Show managed account host action for observers (#48748)

**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):

<img
src="https://raw.githubusercontent.com/raju249/fleet/screenshots-48077/before.png"
width="900" alt="Before: observer's Actions menu without Show managed
account" />

After (same host, same observer):

<img
src="https://raw.githubusercontent.com/raju249/fleet/screenshots-48077/after.png"
width="900" alt="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.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## 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.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Rajendra kadam
2026-07-07 14:38:50 +02:00
committed by GitHub
parent 9fcf65e4e8
commit 8a8fb685a2
3 changed files with 69 additions and 5 deletions
@@ -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.
@@ -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(
<HostActionsDropdown
hostTeamId={null}
onSelect={noop}
hostStatus="online"
hostMdmEnrollmentStatus="On (automatic)"
hostMdmDeviceStatus="unlocked"
hostScriptsEnabled
isConnectedToFleetMdm
hostPlatform="darwin"
isManagedLocalAccountEnabled
managedAccountStatus="verified"
/>
);
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(
<HostActionsDropdown
hostTeamId={1}
onSelect={noop}
hostStatus="online"
hostMdmEnrollmentStatus="On (automatic)"
hostMdmDeviceStatus="unlocked"
hostScriptsEnabled
isConnectedToFleetMdm
hostPlatform="darwin"
isManagedLocalAccountEnabled
managedAccountStatus="verified"
/>
);
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: {
@@ -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) => {