Skip to content

Add custom MDM commands to global and host activity #45021

Description

@noahtalerman

Goal

User story
As a Fleet user looking at the dashboard (global activity), Host details > Activity, or Fleet API,
I want to see who ran a specific MDM command (the actor) via the "run MDM command" API or fleetctl mdm run-command
so that I can investigate who ran a command (e.g. who locked a host).

Changes

Product

  • Changes:
    • Surface in Global and host activity feed when actor runs custom MDM commands
    • Include custom Windows MDM commands
  • UI changes: Figma
  • CLI (fleetctl) usage changes: No changes
  • YAML changes: No changes
  • REST API changes: No changes Use existing /commands/results and /activities
  • Fleet's agent (fleetd) changes: No changes
  • Fleet server configuration changes: No changes
  • Exposed, public API endpoint changes: No changes
  • fleetdm.com changes: No changes
  • GitOps mode UI changes: No changes
  • GitOps generation changes: No changes
  • Activity changes:
  • Permissions changes: No changes
  • Changes to paid features or tiers: No changes
  • My device and fleetdm.com/better changes: No changes
  • Usage statistics: No changes
  • Other reference documentation changes: No changes
  • First draft of test plan added
  • Once shipped, requester has been notified
  • Once shipped, dogfooding issue has been filed Dogfood: ____Add custom MDM commands to global and host activity #49684

Engineering

  • Test plan is finalized
  • Contributor API changes: No changes
  • Feature guide changes: No changes
  • This is a premium only feature: No

ℹ️  Please read this issue carefully and understand it. Pay special attention to UI wireframes, especially "dev notes".

Risk assessment

  • Risk level: Low

Test plan

Make sure to go through the list and consider all events that might be related to this story, so we catch edge cases earlier.

Core flow

  • Send custom Apple MDM command via API or fleetctl:
    • Confirm a new activity of type "ran_custom_mdm_command" appears with the correct actor name, host display name, command UUID, request type (e.g. "DeviceInformation"), and platform set to "darwin."
    • Make sure an iOS or iPadOS device(either one) shows the correct platform too.
    • Send a command to an offline host. Verify the command shows but not its result and the right pending state is displayed
    • Send a command to an ADE-enrolled host then re-enroll it(clearing the past commands). Verify it properly shows the error state for nonexistent command
  • Send custom Windows command via API or fleetctl:
    • Confirm the same activity structure appears with platform set to "windows" and the appropriate request type extracted from the SyncML.
    • Send a command to an offline host. Verify the command shows but not its result and the right pending state is displayed
  • Check dashboard global activity feed:
    • The new activity card should read like "{actor_full_name} ran {request_type} as a custom MDM command on {host_display_name}."
    • If {request_type} is empty: "{actor_full_name} ran a custom MDM command on {host_display_name}."(not sure if this is possible, modify the DB and Engineer note the query in the test plan comment, or say how you did it)
  • Check host activity feed:
    • The new activity card should read like "{actor_full_name} ran {request_type} as a custom MDM command on this host."
    • If {request_type} is empty: "{actor_full_name} ran a custom MDM command on {host_display_name}."

MDM

  • Turn Windows or Apple MDM on. Verify activities appear for both Apple and Windows custom commands
  • Turn multiple MDM on. Ensure activity renders correctly when both Apple and Windows MDM are enabled
  • Single host turn MDM off. Confirm graceful handling if a host's MDM is turned off after a command was run (activity should still render)
  • Turn all MDM off. Verify the activities still display. Verify UI doesn't completely break if you try to click on one

Host

  • Enroll to Fleet using Fleet's agent (fleetd): Verify activity appears for standard enrolled hosts
  • Enrolled via osquery/orbit but no MDM: Edge case: custom MDM commands shouldn't be possible here, confirm no activity is created when you try to run a command and it errors
  • Wiped host / Locked host: Verify that custom EraseDevice/DeviceLock commands create MDM command activities(specific customer ask)
  • Online host / Offline host: Command is queued regardless; activity should appear immediately on send
  • Deleted from Fleet: Verify activity still renders if the target host is later deleted (host_display_name fallback)

User Permissions

  • Global user: Only Admins and Maintainers can run commands; verify Observers see the activity in the feed but can't trigger it
  • Fleet-level user: Same permission checks scoped to team
  • Premium vs. Free: Verify that custom MDM commands are allowed on Fleet Free

Activities

  • Verify the new activity type appears in:
  • Correct chronological ordering
  • Confirm long {request_type} names are truncate d- Do we actually do this anywhere in the UI for Windows LocURIs? If not drop a thread in g-MDM and MDM-group and we'll figure out what should happen here
  • Confirm pending, failed, and deleted commands match experience in Figma.

Edge cases

  • Confirm activity continues to display the name of a no longer existing actor/user (deleted user, API-only user, GitOps)

Supplemental testing

Testing notes

Confirmation

  1. Engineer: Added comment to user story confirming successful completion of test plan (include any special setup, test data, or configuration used during development/testing if applicable).
  2. QA: Added comment to user story confirming successful completion of test plan.
  3. QA: Determined whether this story needs Playwright automation.
    • Needs automation: Yes
    • If yes, filed a follow-up issue in the :help-qa project with status "Needs automation": TO DO

Metadata

Metadata

Assignees

Labels

#g-apple-at-workProduct group focused on Apple devices:help-customersCustomer success issue.:productProduct Design department (shows up on 🦢 Drafting board)customer-figalistoryA user story defining an entire feature

Type

No type

Projects

Status
Done
Status
Done
Status
Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions