Skip to content

Add custom MDM commands to global and host activity #45021

@noahtalerman

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:
    • New type: "Ran custom MDM command"
    • Global and host activity (main feed, not behind MDM commands toggle)
  • 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:
  • First draft of test plan added
  • Once shipped, requester has been notified
  • Once shipped, dogfooding issue has been filed

Engineering

  • Test plan is finalized
  • Contributor API changes: TODO
  • Feature guide changes: TODO
  • Database schema migrations: TODO
  • Load testing: TODO
  • Pre-QA load test: TODO
  • Load testing/osquery-perf improvements: TODO
  • This is a premium only feature: Yes / No

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

Risk assessment

  • Requires testing in a hosted environment: TODO
  • Requires load testing: TODO
  • Risk level: Low / High TODO
  • Risk description: TODO

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."
  • 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.
  • 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}."
  • 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."

MDM

  • Turn Android, 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)

Host

  • Enroll to Fleet using Fleet's agent (fleetd): Verify activity appears for standard enrolled hosts
  • Enrolled via osquery (no orbit / fleetd): Edge case: custom MDM commands shouldn't be possible here, confirm no broken state
  • Wiped host / Locked host: Verify that custom EraseDevice/DeviceLock commands show distinct activity from the built-in wipe/lock actions
  • Online host / Offline host: Command is queued regardless; activity should appear immediately on send
  • Deleted from Fleet: Verify activity still renders gracefully if the target host is later deleted (host_display_name fallback)

User Permissions

  • Global user (Admin, Maintainer, Observer, Observer+, API only): 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: Custom MDM commands are Premium; verify Free users get a clear error and no activity is logged

Activities

  • Verify the new activity type appears in:
    • Global activity feed (dashboard)
    • Host past activities tab
    • Correct chronological ordering

User

  • API-only user: Verify that when an API-only user runs a custom command, the activity shows the actor name correctly (or "API" attribution)

UI

  • Verify that all UI changes specified in the Figma wireframes are correctly implemented
  • Verify expected UI states (loading, empty, error states if applicable)

API

  • Test all API endpoints added or modified in the API changes section of this issue
  • Verify any new API endpoints appear in the list when adding an API-only user. The API endpoints display name, method, and path is the same as listed in the API reference docs
  • Verify error handling for invalid inputs where applicable

GitOps (generate + run)

  • Configure the feature through the UI and run fleetctl generate-gitops
  • Confirm the generated .yml includes the expected fields (compare with YAML changes in the Product section)
  • Modify the generated .yml and run fleetctl gitops
  • Confirm the configuration updates correctly in Fleet
  • Enable GitOps mode and verify the feature behaves correctly

Permissions

  • Verify role restrictions are applied correctly for global roles
  • Verify role restrictions are applied correctly for fleet-level roles

Edge cases

  • TODO
  • TODO
  • TODO

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 / No
    • If yes, filed a follow-up issue in the :help-qa project with status "Needs automation": TODO

Metadata

Metadata

Assignees

Labels

#g-mdmMDM product group:productProduct Design department (shows up on 🦢 Drafting board)customer-figalistoryA user story defining an entire feature

Type

No type

Projects

Status

🐣 In progress

Status

No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions