Repository navigation
MDM Assessment
Status: Proposed, October 2026. Pending a discovery gate (see section 7). This page explains what Mobile Device Management (MDM) is, what it would let us enforce that we can't today, what it would really take, and the order to do it in. The sequencing is reflected in the Roadmap.
On Apple platforms (and on Windows), MDM enforcement is done by a client already built into the operating system: mdmclient on macOS, the OMA-DM client on Windows. That client:
- enrolls by installing an enrollment profile that points at an MDM server,
- is woken up through Apple Push Notification service (APNs),
- checks in with the server over HTTPS, receives commands and configuration profiles, and applies them with OS authority.
So "turning SentinelGo into an MDM" is mostly new backend work: MDM endpoints in our existing backend. It is not a change to the Go agent. The agent stays useful next to the MDM: MDM enforces, SentinelGo observes, verifies and reports (inventory, posture, audit logs, drift). Commercial products use the same split (e.g. Fleet pairs an MDM server with an osquery-based agent).
┌──────────────────────────┐
Apple APNs ◀────│ MDM endpoints (new, in │◀── admins / policy model
│ push │ our backend) │
▼ │ check-in, cmds, profiles│
┌─────────┐ └────────────▲─────────────┘
│ macOS │ HTTPS check-in │
│ mdmclient├────────────────┘
│ (built-in) ┌──────────────────────┐
│ SentinelGo agent ───────────────▶│ Supabase (existing) │
└─────────┘ inventory, posture, │ heartbeat, tasks │
compliance, drift └──────────────────────┘
| Platform | Can our root/SYSTEM agent enforce OS policy today? | Is MDM the only route? |
|---|---|---|
| macOS | Mostly no. Since macOS 11, configuration profiles can't be installed silently from the command line; they need MDM or a manual user approval in System Settings. Privacy (TCC) permissions, system-extension approval, and making login/background items non-removable all need MDM. | Yes |
| Windows | Mostly yes. As SYSTEM the agent can set policy registry keys, BitLocker, firewall, Defender and USB storage directly. | No. Agent-side enforcement covers most needs. |
| Linux | Yes. Root can configure everything; there is no MDM standard. | No. Agent-side enforcement is the only option. |
So the proposal is really "policy enforcement across the fleet": MDM on macOS, agent-side enforcement on Windows and Linux, all driven by one policy model (see Roadmap → Desired-state compliance and Enforcement with drift correction).
| Capability | Mechanism | Value |
|---|---|---|
| Enforce FileVault and escrow the recovery key | FileVault payload + recovery key escrow | Recover locked Macs; prove encryption to auditors |
| Passcode / screen-lock policy | Passcode payload | Baseline compliance |
| Firewall, Gatekeeper, restrictions | Configuration profiles | Baseline compliance |
| Grant SentinelGo Full Disk Access silently | Privacy Preferences Policy Control (PPPC/TCC) payload | Agent sees more (e.g. audit logs) without prompting users |
| Stop users disabling the agent | Managed login/background items payload (macOS 13+) | Tamper resistance |
Install / update the SentinelGo .pkg
|
InstallEnterpriseApplication command |
Fleet deployment without zip + script |
| OS update enforcement | Declarative Device Management (DDM) software-update declarations | Patch compliance |
| Lock / erase a lost device | MDM commands | Incident response |
| Zero-touch setup for new Macs | Automated Device Enrollment (ADE) via Apple Business Manager | Supervised, non-removable management from first boot |
There are two different Apple relationships, and they often get mixed up:
- Becoming an MDM vendor. To run our own MDM server we need an APNs MDM push certificate. That requires a CSR signed with an MDM vendor signing certificate, which comes through an organisation Apple Developer account once Apple approves it. Historically this was tied to the Enterprise Program; confirm the current terms with Apple before planning around a date. The APNs certificate then has to be renewed every year with the same Apple Account. If it lapses or is renewed under a different account, every enrolled device must re-enroll. This is the classic MDM operational failure.
- Apple Business Manager (ABM) for the customer organisation. ABM lets company-owned devices bought through Apple or an authorised reseller auto-enroll into our MDM (ADE) and be supervised. Devices outside ABM can still enroll manually ("user-approved MDM"), but the user can remove that enrollment.
Separately, we need an Apple Developer ID to sign and notarize the SentinelGo binary and .pkg. That is required for MDM package deployment and for PPPC grants, which identify the app by its code-signing requirement. Today our releases carry our own ed25519 update signatures but no Apple Developer ID / Authenticode signatures, so this is a hard prerequisite.
Decision (Oct 2026): build the MDM endpoints in our existing TypeScript backend. We don't want to run a second backend language. Off-the-shelf Go MDM servers (NanoMDM, MicroMDM, Fleet) were rejected for that reason, but NanoMDM stays a useful reference implementation to read when checking protocol details.
Our backend has two runtimes, and the MDM work is split between them by what each piece needs:
- Backend app server (Node): long-running, full Node APIs, outbound HTTP/2 with client certificates.
- Supabase edge functions (Deno): short, stateless request handlers next to the database.
Apple's MDM protocol is ordinary request/response HTTPS with property-list bodies, so most of it fits either runtime.
| Piece | Implementation | Runs in | Difficulty |
|---|---|---|---|
Check-in endpoint (Authenticate, TokenUpdate, CheckOut, DeclarativeManagement) |
Parse plist; store device identity, push token and PushMagic in Postgres |
Edge function or app server | Easy |
Command endpoint (device reports Idle → server returns the next queued command → device reports Acknowledged / Error / NotNow) |
Command-queue table in Postgres | Edge function or app server | Easy |
| Request authentication | Enable SignMessage: devices send a detached CMS signature in the Mdm-Signature header, verified against certificates we issued. Works behind TLS-terminating proxies and gateways, unlike mTLS |
Same place as check-in/command | Medium–hard |
Signed enrollment profiles (.mobileconfig) |
CMS signing | Edge function or app server | Medium |
| Device identity certificates | Pilot: per-device PKCS#12 identity embedded in the enrollment profile. Later: a SCEP endpoint, or ACME with hardware device attestation | Edge function or app server | Hard (main crypto effort) |
| Declarative Device Management | JSON declarations served over the check-in channel | Same place as check-in | Medium |
| APNs push to wake devices | HTTP/2 to api.push.apple.com with the MDM push certificate as the TLS client certificate. MDM push only supports certificate auth, not APNs token auth |
App server (needs HTTP/2 + client certificates, which edge functions don't reliably support) | Medium |
| Admin side: policy authoring, queueing commands, rollout rings | Normal backend features | App server | Medium |
| Apple Business Manager / ADE sync (later) | OAuth1 client + decryption of the ABM server token (PKCS#7); runs on a schedule | App server, or a scheduled edge function | Medium |
Implementation rules:
-
A stable device-facing URL is mandatory. The MDM server URL is baked into every enrolled device, and changing it means re-enrolling the whole fleet. Devices must talk to a dedicated, permanent hostname we control (e.g.
mdm.<domain>), routed to whichever runtime implements each endpoint. They must never use a raw*.supabase.co/functions/v1/...URL. This also keeps the edge-function-vs-app-server choice reversible later. -
Edge-function specifics: device-facing functions must have gateway JWT verification turned off, because devices can't send a Supabase token. The
Mdm-Signaturecheck is the authentication, so it must run before any other logic. Watch the per-request CPU limits for key generation (pilot PKCS#12 identities); move that step to the app server if it gets close. -
Crypto library: PKI.js (
pkijs) with@peculiar/x509, not node-forge. node-forge has had several signature-verification vulnerabilities, and its crypto is implemented in pure JavaScript. PKI.js builds CMS/PKCS#7/PKCS#12 on the platform's WebCrypto API, so the same code runs unchanged in Node and in Deno edge functions. Pin versions and track advisories like any other security-critical dependency. -
Types: payload and command types are generated from Apple's published schemas (
apple/device-management, YAML), not hand-written. - Testing: Apple-silicon macOS VMs (e.g. UTM, Tart) support manual enrollment, which is enough for the pilot. ADE needs real, ABM-registered hardware.
| # | Prerequisite | Why MDM needs it | Roadmap item |
|---|---|---|---|
| 1 | Finish the open agent security-hardening work | MDM raises the stakes: a backend compromise could then push profiles or wipe devices, not only run tasks | Security hardening |
| 2 | Signed task execution | Same reason. Every remote-action path must be integrity-protected before we add more powerful ones | Security hardening |
| 3 | Generic installers + enrollment tokens | MDM installs one generic, signed .pkg; the per-device config.json zip model can't work through MDM |
Enrollment v1 |
| 4 | Apple Developer ID signing + notarization (and Authenticode on Windows) | Package deployment, PPPC grants, Gatekeeper | Platform code signing |
| 5 | Policy model + compliance reporting | Defines what we enforce and lets us measure drift before and after enforcement | Desired-state compliance |
- Blast radius. One bad profile or command reaches every enrolled Mac. We need staged rollout (pilot group → ring → fleet), dry runs, and two-person approval for destructive commands (erase, lock).
- Certificate operations. APNs certificate (yearly), SCEP CA, profile-signing certificates: each one that expires silently can break management fleet-wide. Monitoring and runbooks are mandatory.
- Removability. Without ABM/ADE, users can remove MDM enrollment on non-supervised Macs. Enforcement is then advisory, so the agent must detect and report "MDM removed".
- Apple platform churn. Apple is moving management to Declarative Device Management and has deprecated parts of the legacy command set (e.g. software-update commands). Build new features on DDM where possible.
- Privacy / BYOD. Personal devices need User Enrollment (limited management), a different scope and a separate policy.
- How many macOS devices are in the target fleet, and are they company-owned and in Apple Business Manager?
-
Does the organisation already license an MDM (Intune, Jamf, Kandji, …)?Answered (Oct 2026): no existing MDM, so building our own stays the plan. - Can we obtain the MDM vendor signing certificate and a Developer ID, and who owns the Apple Account (it must outlive any one employee)?
- Who operates the MDM server (on-call, certificate renewals, incident response)?
- Which 5–10 policies matter most? These become the first policy set in Desired-state compliance.
If the answers turn out to be "few Macs" or an MDM is adopted elsewhere first, the plan becomes integrate, don't build: SentinelGo reports MDM enrollment and profile state as part of compliance.
SentinelGo
Repository docs