Most MDM products are black boxes: you click checkboxes in a vendor console and trust that the right profile landed on the right Mac. Fleet inverts that. It’s open source, it’s built on osquery, and every piece of device state is a queryable table. Here’s how to run macOS management on it without regretting your choices.
#Why Fleet for macOS
- Verifiable state. Don’t trust the console — query the device.
SELECT * FROM profiles;tells you what’s actually installed. - GitOps-native. Teams, policies, and profiles live in YAML in a repo. Config changes are pull requests, not console clicks.
- One agent, three jobs.
fleetdhandles MDM enrollment, osquery telemetry, and software orchestration. - No per-feature upsell. The open-source core covers most of what a Jamf shop pays tiers for.
#Architecture in One Breath
Fleet server (self-hosted or cloud) talks to Apple Push Notification service for MDM commands and to fleetd agents for everything else. Macs enroll via Automated Device Enrollment (ABM) for supervision, or manually for BYOD. Declarative Device Management (DDM) handles profile state; osquery handles truth.
#Step 1: Wire Up Apple Business Manager
- Generate the MDM push certificate (Fleet UI walks you through the CSR → Apple Push Certificates Portal loop).
- In ABM, create an MDM server pointing at your Fleet instance and assign device serials to it.
- Set your default team for ADE enrollments — new Macs land supervised, no touch.
# teams/workstations.yml
name: Workstations
mdm:
macos_setup:
bootstrap_package: https://pkgs.internal/base-tools.pkg
enable_end_user_authentication: true
macos_settings:
custom_settings:
- path: ../profiles/filevault.mobileconfig
- path: ../profiles/firewall.mobileconfig
- path: ../profiles/sso-extension.mobileconfig
#Step 2: Policies as Code
A Fleet policy is a SQL query that should return a row when the device is compliant:
# policies/disk-encryption.yml
- name: FileVault enabled
query: SELECT 1 FROM disk_encryption WHERE encrypted = 1 AND name = '/';
critical: true
- name: Firewall enabled
query: SELECT 1 FROM alf WHERE global_state >= 1;
- name: OS up to date (macOS 15+)
query: SELECT 1 FROM os_version WHERE major >= 15;
Wire fleetctl gitops into CI and your device posture is now code-reviewed:
fleetctl gitops --config ./fleet --dry-run # PR check
fleetctl gitops --config ./fleet # merge to main = apply
#Step 3: Visibility That Answers Real Questions
The questions IT actually gets asked, answered in one query each:
-- Who still runs the vulnerable Chrome build?
SELECT hostname, bundle_version FROM apps
WHERE bundle_identifier = 'com.google.Chrome'
AND bundle_version < '126.0.6478.127';
-- Which Macs haven't rebooted in 30+ days?
SELECT hostname, days FROM uptime WHERE days > 30;
Schedule these as saved queries, route failures to Slack, and you’ve replaced a compliance dashboard subscription.
#Migration Notes (from Jamf, mostly)
- Run both agents side by side during transition; they don’t conflict. Migrate MDM enrollment team by team — Fleet’s migration assistant handles the unenroll/re-enroll dance on ADE devices without a wipe.
- Rebuild profiles rather than exporting them. Jamf-exported
.mobileconfigfiles carry years of cruft; a clean DDM-first profile set is smaller and auditable. - Expect the long tail: 90% of Macs migrate in the first two weeks, and the last 5% (sabbaticals, drawer laptops, executives) take a quarter. Plan the comms accordingly.
#The Honest Caveats
Fleet won’t hand you a curated app catalog UI as polished as Jamf’s Self Service, and complex Setup Assistant customization still needs supplementary tooling. If your org’s Mac management maturity is “we click around once a quarter,” a black box may genuinely serve you better. But if you want device management that behaves like the rest of your infrastructure — declarative, versioned, verifiable — this is the way it should have always worked.