NanoMDM is a minimalist Apple MDM server heavily inspired by MicroMDM

Related tags




NanoMDM is a minimalist Apple MDM server heavily inspired by MicroMDM.

Getting started & Documentation

  • Quickstart
    A quick guide to get NanoMDM up and running using ngrok.

  • Operations Guide
    A brief overview of the various command-line switches and HTTP endpoints and APIs available to NanoMDM.


  • Horizontal scaling: zero/minimal local state. Persistence in storage layers. MySQL backend provided in the box.
  • Multiple APNs topics: potentially multi-tenant.
  • Multi-command targeting: send the same command (or pushes) to multiple enrollments without individually queuing commands.
  • Migration endpoint: allow migrating MDM enrollments between storage backends or (supported) MDM servers
  • Otherwise we share many features between MicroMDM and NanoMDM, such as:
    • A MicroMDM-emulating HTTP webhook/callback.
    • Enrollment-certificate authorization
    • API-driven interaction (queuing of commands, APNs pushes, etc.)

$x not included

NanoMDM is but one component for a functioning MDM server. At a minimum you need a SCEP server and TLS termination, for example. If you've used MicroMDM before you might be interested to know what NanoMDM does not include, by way of comparison.

  • SCEP.
    • Spin up your own scep server. Or bring your own.
  • TLS.
    • You'll need to provide your own reverse proxy/load balancer that terminates TLS.
  • ADE (DEP) API access.
    • While ADE/DEP enrollments are supported there is no DEP API access.
  • Enrollment (Profiles).
    • You'll need to create and serve your own enrollment profiles to devices.
  • Blueprints.
    • No 'automatic' command sending upon enrollment. Entirely driven my webhook or other integrations.
  • JSON command API.
    • Commands are submitted in raw Plist form only. See the tool that helps generate raw commands
    • The micro2nano project provides an API translation server between MicroMDM's JSON command API and NanoMDM's raw Plist API.
  • VPP.
  • Enrollment (device) APIs.
    • No ability, yet, to inspect enrollment details or state.
    • This is partly mitigated by the fact that both the file and mysql storage backends are "easy" to inspect and query.

Architecture Overview

NanoMDM, at its core, is a thin composable layer between HTTP handlers and a set of storage abstractions.

  • The "front-end" is a set of standard Golang HTTP handlers that handle MDM and API requests. The core MDM handlers adapt the requests to the service layer. These handlers exist in the http package.
  • The service layer is a composable interface for processing and handling MDM requests. The main NanoMDM service dispatches to the storage layer. These services exist under the service package.
  • The storage layer is a set of interfaces and implementations that store & retrieve MDM enrollment and command data. These exist under the storage package.

You can read more about the architecture in the blog post Introducing NanoMDM.

  • Create operator guide

    Create operator guide

    The operator guide will document the sometimes opaque and non-intuitive command-line switches and options. It should cover most of the supported ways of running NanoMDM.

    opened by jessepeterson 1
  • Remove trailing commas from CREATE TABLE statements

    Remove trailing commas from CREATE TABLE statements

    What's up?

    Was having problems running the schema.sql file in MySQL 5.7.32. It was blowing up because of the trailing commas.

    Did some research on whether trailing commas are allowed in CREATE TABLE. The results didn't seem conclusive. Some RDBMS implementations deem it harmless and won't error on it.

    Wanted to check the SQL language spec next but since this file has some statement without trailing commas, I thought it's probably not intentional and it's easier to just remove it.

    opened by daemonsy 1
  • Setup GH Actions

    Setup GH Actions

    Setup some basic GH actions that do basic checks such as formatting, compiling, test running, etc.

    opened by jessepeterson 0
  • Fixed a couple of typos

    Fixed a couple of typos

    Nice project!

    opened by gmarnin 0
  • Remove command output from example

    Remove command output from example

    Probably not meant to be in the example?

    opened by daemonsy 0
  • Fix typo in token_hex check constraint

    Fix typo in token_hex check constraint

    There's no token column on enrollments, but there is a token_hex, so assuming this check constraint is a typo.

    If that's the case, wondering how that worked? Is MySQL constraints in some versions more forgiving?

    opened by daemonsy 0
  • Declarative Management initial work-in-progress

    Declarative Management initial work-in-progress

    Work-in-progress for declarative management "lite." All this does is extract the declarative management "endpoint" key and data and dispatch to another, real, HTTP server. Use the -dm switch and the Endpoint key will be appended to that URL. The enrollment ID is also passed along in a header. Again: this doesn't do actual Declarative Management, just forwards to another service to do that work.

    opened by jessepeterson 0
  • Attempt to make Quickstart easier to follow

    Attempt to make Quickstart easier to follow

    Found the two ngrok urls to be hard to grok :), have to keep going back to see if that was the SCEP one or nanomdm one. So I thought this adding the prefix makes it easier to follow.

    Also, ngrok supports multiple tunnels on one process on the free plan, but it's easy to overlook. Added a line on configuring multiple tunnels.

    opened by daemonsy 2
  • Pass URL parameters through request object

    Pass URL parameters through request object

    Support passing the MDM HTTP request parameters through the MDM request object to later be supplied to the webhook.

    opened by jessepeterson 0
  • Support a way to indicate an initial enrollment

    Support a way to indicate an initial enrollment

    The webhook currently will inform you about TokenUpdate events. However they are explicitly meant to be sent multiple times during the lifetime of a device's enrollment. Thus, a TokenUpdate doesn't necessarily indicate an enrollment—unless it is the very first one. Support a way to track and signifiy an initial TokenUpdate in the event sent out so that enroll-time actions can be undertaken only once.

    I imagine this would come in the form of a TokenUpdate counter that is reset every enrollment. In which case only the first TokenUpdate would represent the initial enrollment.

    opened by jessepeterson 0
  • Support Bootstrap Tokens

    Support Bootstrap Tokens

    opened by jessepeterson 0
  • Mode to recapture client certificate

    Mode to recapture client certificate

    By default NanoMDM will save the client identity certificate for a device enrollment during the Authenticate check-in message (for both the file and mysql backends). However if enrollments happened in such a way that client certificates were missed (say, via migration) then we should support a way to "recapture" client certificates in storage by saving the identity certificate. It would be wasteful to do this on every request so perhaps it would be only be turned on with a flag.

    opened by jessepeterson 0
  • Add NotNow tracking field

    Add NotNow tracking field

    As also mentioned in this discussion thread a field should be added to the MySQL backend that tracks when the last NowNow was seen for a command result. While this wouldn't affect any operation per se it would give insight into stats on NotNow commands.

    opened by jessepeterson 0
  • Queue (command) test framework

    Queue (command) test framework

    Create a basic testing framework for testing command queueing/de-queuing, NotNow-ing, etc. It should be storage backend agnostic.

    opened by jessepeterson 0
  • Support environment variable configuration

    Support environment variable configuration

    Currently we just use CLI flag parsing. Support configuring via environment variable fallback.

    enhancement good first issue 
    opened by jessepeterson 0
  • UserAuthenticate rejection

    UserAuthenticate rejection

    Currently the UserAuthenticate Check-in is missing and so it will receive a 400 response. We want stub out the UserAuthenticate request to reply with 410 (probably faciliated through a shared error and errors.Is() check) when we receive it. See micromdm/micromdm#379 for the corollary feature.

    opened by jessepeterson 0
macOS MDM and related services
⚡ HTTP/2 Apple Push Notification Service (APNs) push provider for Go — Send push notifications to iOS, tvOS, Safari and OSX apps, using the APNs HTTP/2 protocol.

APNS/2 APNS/2 is a go package designed for simple, flexible and fast Apple Push Notifications on iOS, OSX and Safari using the new HTTP/2 Push provide

Adam Jones 2.5k Jun 11, 2021
A push notification server written in Go (Golang).

gorush A push notification micro server using Gin framework written in Go (Golang) and see the demo app. Contents gorush Contents Support Platform Fea

Bo-Yi Wu 5.5k Jun 12, 2021
Chanify is a safe and simple notification tools. This repository is command line tools for Chanify.

Chanify is a safe and simple notification tools. For developers, system administrators, and everyone can push notifications with API.

Chanify 515 Jun 12, 2021
:notes: Minimalist websocket framework for Go

melody ?? Minimalist websocket framework for Go. Melody is websocket framework based on that abstracts away the tedious p

Ola 2.1k Jun 12, 2021
🔊Minimalist message bus implementation for internal communication

?? Bus Bus is a minimalist event/message bus implementation for internal communication. It is heavily inspired from my event_bus package for Elixir la

Mustafa Turan 210 Jun 12, 2021
websocket based messaging server written in golang

Guble Messaging Server Guble is a simple user-facing messaging and data replication server written in Go. Overview Guble is in an early state (release

Sebastian Mancke 148 Jun 3, 2021
Uniqush is a free and open source software system which provides a unified push service for server side notification to apps on mobile devices.

Homepage Download Blog/News @uniqush Introduction Uniqush (\ˈyü-nə-ku̇sh\ "uni" pronounced as in "unified", and "qush" pronounced as in "cushion") is

Uniqush 1.3k Jun 2, 2021
Glue - Robust Go and Javascript Socket Library (Alternative to

Glue - Robust Go and Javascript Socket Library Glue is a real-time bidirectional socket library. It is a clean, robust and efficient alternative to so

DesertBit 377 Jun 3, 2021
Machinery is an asynchronous task queue/job queue based on distributed message passing.

Machinery Machinery is an asynchronous task queue/job queue based on distributed message passing. V2 Experiment First Steps Configuration Lock Broker

Richard Knop 5.3k Jun 14, 2021
Golang client for NATS, the cloud native messaging system.

NATS - Go Client A Go client for the NATS messaging system. Installation # Go client go get # Server go get

NATS - The Cloud Native Messaging System 3.4k Jun 13, 2021
An easy-to-use CLI client for RabbitMQ.

buneary, pronounced bun-ear-y, is an easy-to-use RabbitMQ command line client for managing exchanges, managing queues and publishing messages to exchanges.

Dominik Braun 47 May 16, 2021
HARAQA - High Availability Routing And Queueing Application

haraqa is designed to be a developer friendly, scalable message queue for data persistence and real-time data streaming between microservices. Haraqa provides high-throughput, low-latency, fault-tolerant pipelines for architectures of any size.

null 49 Apr 22, 2021
golang long polling library. Makes web pub-sub easy via HTTP long-poll server :smiley: :coffee: :computer:

golongpoll Golang long polling library. Makes web pub-sub easy via an HTTP long-poll server. New in v1.1 Deprecated CreateManager and CreateCustomMana

J Cuga 554 May 29, 2021
Simple, high-performance event streaming broker

Styx Styx is a simple and high-performance event streaming broker. It aims to provide teams of all sizes with a simple to operate, disk-persisted publ

Dataptive 21 Jun 18, 2021