The browser dashboard supports login, fleet review, policy and content management, command dispatch, and audit review.
The screenshots in this guide are real captures from the implemented dashboard using sample data. Regenerate them with the tooling in docs/tools/admin-dashboard-screenshots.
- Start the XMDM server.
- Open
/admin/login. - Enter the admin username and password.
- Select
Login. - After login, the dashboard redirects to
/admin.
Access rules:
- All dashboard pages except
/admin/loginrequire a valid admin session cookie. - Read pages require
admin.read. - Create, update, retire, upload, publish, revoke, and send actions require
admin.write. - Browser mutations require the
xmdm_csrfcookie and matchingcsrfTokenform field. - Use
Logoutin the top bar to end the session.
The left navigation is grouped by operator task:
| Section | Path |
|---|---|
| Overview | /admin |
| Fleet | /admin/devices, /admin/policies, /admin/groups, /admin/commands |
| Content | /admin/apps, /admin/managed-files, /admin/certificates |
| Identity | /admin/users, /admin/roles |
| Operations | /admin/audit |
The overview is the fleet command center. It combines:
- a fleet health banner with active, pending, retired/wiped device counts, active policy count, command acknowledgement summary, and recent audit activity
- quick actions for managing devices, reviewing policies, and viewing the audit log
- live health cards for device readiness, policy library, content readiness, command health, and audit activity
- metric cards for device-info freshness, pending enrollment, command acknowledgement rate, and content items, each with a compact visual indicator
- a needs-attention panel that surfaces active operational issues such as pending enrollment, stale active devices, failed commands, and commands awaiting acknowledgement
- device-focused charts for status distribution, device-info activity, device-info freshness, and model breakdown
- command-focused panels for delivery volume over time and delivery status breakdown
- content library and recent activity panels at the bottom of the page
Use this page to confirm the control plane has current fleet data, spot operational issues quickly, and jump into the resource-specific pages for deeper investigation.
Identity covers operator accounts and permission sets.
Use /admin/users to manage operator accounts.
The users list follows the scan-first pattern:
CreatedIDEmailRoleStatus
Open the user email to reach the detail page.
- Open
/admin/users. - In
Create user, enter:EmailPasswordRole
- Select
Create user. - Confirm the user appears in the table.
- Open the user link in the table.
- Review the current user record.
- Edit the detail page fields:
EmailPasswordif you want to replace the current hashRole
- Select
Update user. - Select
Retire userfrom the same page when the account should no longer be active.
When Password is left blank during update, the backend preserves the existing
stored password hash. When a new password is supplied, the backend derives and
stores the replacement hash; the dashboard keeps stored password hashes hidden.
Use /admin/roles to manage operator permission sets.
The roles list follows the scan-first pattern:
CreatedIDNamePermissionsStatus
Open the role name to reach the detail page.
- Open
/admin/roles. - In
Create role, enter:NamePermissions JSON array
- Example permissions:
["admin.read"]["admin.read","admin.write"]
- Select
Create role.
- Open the role link in the table.
- Review the current role record.
- Edit the detail page fields:
NamePermissions JSON array
- Select
Update role. - Select
Retire rolefrom the same page when the permission set should no longer be active.
Invalid permission JSON is rejected before the role is saved.
Device setup is policy-bound. The policy owns the managed apps, managed files, and managed certificates that a device receives.
Use /admin/policies to define the device configuration bundle.
The policies list follows the scan-first pattern:
CreatedIDNameKioskStatus
Open the policy name to reach the detail page.
- Open
/admin/policies. - In
Create policy, enter:Name- optional
Kiosk app package - optional
Enable kiosk mode Kiosk exit passcodewhen kiosk is enabledAllow packagesone package per lineBlock packagesone package per lineSuspend packagesone package per line- optional
Keep screen on - optional
Stay awake while plugged in - optional
Unlock on boot
- Select
Create policy.
- Open the policy name in the table.
- Review the policy summary and current restriction inputs.
- Toggle
Enable kiosk modeas needed. - Update the generated restriction inputs.
- Use the
Managed apps,Managed files, andManaged certificatessections to enable or disable content for this policy. - Select
Update policywhen finished. - Select
Retire policyfrom the same page when the policy should no longer be active.
Policy detail pages manage the content bindings. Devices only receive the managed apps, managed files, and certificates that are enabled on their linked policy.
Use /admin/apps to review the app catalog and publish versions for predefined managed-app rows in a scan-first list.
The apps list follows the scan-first pattern:
CreatedIDNamePackageLatest publishedStatus
Open the app name to reach the detail page.
- Open
/admin/apps. - Enter:
Package nameNameVersion code
- Choose the APK file to upload.
- Select
Create managed app.
Use this flow only for the first app record. The dashboard seeds the standard
launcher app row during bootstrap, so the launcher package already exists on a
fresh database and only needs new versions published later.
The dashboard derives the artifact storage key, checksum, and file record from the uploaded APK on the server.
The server derives the app version name from the version code for this flow, so operators only need to supply the code.
The dashboard always publishes the new APK as another version for that app instead of creating a duplicate app row.
Device enrollment QR generation uses the latest published version of the seeded
launcher app package, com.xmdm.launcher, and serves it from
/api/v1/enrollment/agent.apk.
- Open the app name in the table.
- Review the app summary.
- Use
Publish new versionto upload a new APK without retyping the package or app name. Provide the version code and APK file; the server derives the version name from the code when you leave it blank. - Use
Download latest APKto retrieve the published artifact. - Review the published versions history.
- If the app is system-owned, the detail page is publish-only and hides metadata edits and retire actions.
- Select
Update apporRetire appfrom the detail page only for non-seeded app rows.
Use /admin/managed-files to upload a managed file and bind it to a device path in one step.
Uploading the same device path again replaces the existing binding with the new file content.
The managed-files list follows the scan-first pattern:
CreatedIDPathFileTemplateStatus
Open the path to reach the detail page.
- Open
/admin/managed-files. - Enter the
Device path. - Select
Replace variablesif the file should be templated. - Choose the file to upload.
- Select
Upload managed file.
- Open the managed-file path in the table.
- Review the current managed-file binding.
- Select
Download fileto fetch the uploaded content. - Select
Retire managed filewhen the binding should no longer apply.
Managed files appear in signed device config snapshots when active.
Use /admin/certificates to upload certificate artifacts for devices.
The certificates list follows the scan-first pattern:
CreatedIDNameArtifactStatus
Open the name to reach the detail page.
- Open
/admin/certificates. - In
Upload certificate, enter:Name
- Choose the certificate file.
- Select
Upload certificate.
The dashboard derives the storage key, checksum, size, and MIME type from the uploaded file.
- Open the certificate name in the table.
- Review the current certificate record and artifact metadata.
- Select
Download certificateto retrieve the uploaded artifact. - Select
Retire certificatewhen the certificate should no longer be active.
Policy detail pages also let you enable or disable certificates for a policy. Devices only receive the certificates that are enabled on their linked policy.
Use /admin/devices to create the device record that enrollment binds to.
The device list follows the scan-first pattern:
CreatedNameStatusBatteryLast reportPolicy
Open the device name to reach the detail page.
Use the search field above the table to narrow the list by device name, then use the filter chips to switch between All, Low battery, and Stale report devices.
- Open
/admin/devices. - Enter:
Display namePolicy- optional
Groups
- Select
Create device.
The groups selector only shows active groups, uses a scrollable checkbox list, and keeps the labels compact so long group lists stay usable.
- Open the device name in the table.
- Review the device record and the linked active policy.
- Review recent logs, recent device info, and pending commands from the same page.
- Edit the device display name or linked policy as needed.
- Select
Update device. - Select
Retire devicefrom the same page when the device should no longer be active.
The dashboard creates the device record first, with the selected policy linked to
it. New devices are created in pending state. The device has a
server-generated immutable device ID for enrollment and runtime auth, plus a
separate display name for operators. Device secrets are generated server-side
and stored as hashes.
The device detail page also keeps the assigned groups editable, and the command selectors only show active or enrolled devices and active groups.
- Open a pending device detail page.
- Select
Generate QR. - Review the QR JSON and PNG preview directly below the button.
- Scan the QR from the target device to start enrollment.
- Complete enrollment on the device so it can fetch its linked policy and managed content.
The QR is generated from the pending device detail page and carries the immutable device ID automatically. The device stays in the dashboard as pending until enrollment completes.
When the premium remote-control plugin is enabled and the operator has admin:remote-control, the device detail page exposes the Remote Control device action.
- Select
Remote Controlfrom the device actions area. - The dashboard opens the premium remote-control viewer for that device and shows
connectedwhen the relay attaches. - If a pending session is already active, the page first shows the blocked state and offers
Cancel session and retry,Refresh, andBack to device.
Groups are device cohorts for command targeting.
Use /admin/groups to organize devices.
The groups list follows the scan-first pattern:
CreatedIDNameStatus
Open the group name to reach the detail page.
- Open
/admin/groups. - Enter the group
Name. - Select
Create group.
- Open the group link in the table.
- Review the group record and the member devices list.
- Edit the detail page fields:
Name
- Select
Update group. - Select
Retire groupfrom the same page when the cohort should no longer be active.
The group detail page shows the devices that belong to the group.
Use /admin/commands to send and inspect device commands.
For command delivery behavior, statuses, and troubleshooting signals, see
Commands.
The commands list follows the scan-first pattern:
CreatedIDTypeDeviceStatusExpires
Open the command ID to reach the detail page.
- Open
/admin/commands. - Enter command
Type, for exampleping,reboot,sync_config, orexit_kiosk. - Choose
Target type:devicegroup
- Select the target device or group from the dropdown.
- Enter optional payload JSON.
- Enter optional expiry.
- Select
Send command.
Invalid payload JSON or invalid expiry is rejected before enqueue. The dashboard UI exposes device and group targeting for commands.
- Open the command ID in the table.
- Review the command row, device link, payload JSON, result JSON, and ack timestamp.
- Use the status to confirm whether the command is queued, sent and awaiting acknowledgement, acked, failed, or expired.
Use /admin/audit to inspect immutable admin activity.
Audit rows show:
- created time
- actor
- action
- resource type and ID
- details JSON
Audit events are append-only and should be used to confirm who changed what.






















