go-apple-dm

module
v0.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT

README

go-apple-dm

Release CI Go Reference Go Version License

Go packages for Apple's MDM protocol, declarative device management (DDM), enrollment, certificate issuance and Apple service clients. The repository also contains a reference server and an admin CLI. It does not provide an inventory UI or a fleet management product.

The root module contains protocol libraries, generated schema types, storage contracts and in-memory implementations. The server module adds SQL stores, the service layer, HTTP adapters and application wiring. Both modules require Go 1.27. The API is pre-1.0 and may change between minor versions.

Quick start

Install the library in your own module:

go get github.com/deploymenttheory/go-apple-dm

Applications using the service layer or SQL backends also import the server module:

go get github.com/deploymenttheory/go-apple-dm/server

From a repository checkout, run a local development server:

DM_ROLE=all DM_STORAGE=inmem DM_ADMIN_TOKEN=dev-token go run ./server/cmd/dmserver

In another terminal:

curl http://localhost:8080/healthz
go run ./server/cmd/dmctl -server http://localhost:8080 -token dev-token status

This configuration loses state on restart. Device enrollment additionally requires a public HTTPS endpoint, a matching push topic and certificate, and a configured enrollment identity issuer. Read enrollment security operations before enabling enrollment. Behind a TLS proxy, restrict certificate-header trust to that proxy.

DM_ADMIN_TOKEN grants unrestricted administrative access and bypasses policy. To use scoped credentials, enable the principal store, create principals and policies, then remove the bootstrap token and restart. dmctl status reports accepted authorization modes.

The schema can also be inspected offline:

go run ./server/cmd/dmctl explain DeviceInformation
go run ./server/cmd/dmctl explain DeviceInformation -target macos:15.0,supervised
go run ./server/cmd/dmctl explain com.apple.configuration.softwareupdate.enforcement.specific

For embedding examples, see the package documentation and the executable scenarios in server/e2e and simulator.

The reference-server bench combines simulated scenarios, process acceptance, and live-device testing. It covers certificate inspection, app alert/background pushes, MDM vendor CSR signing, and testing both paths on a Mac. Real credentials and test evidence stay in the gitignored test-lab/local/ directory. Use make bench-init, make bench-up, and make bench-run; see the testing guide and API/configuration additions.

Architecture

go-apple-dm modules and protocol services

Open the interactive architecture diagram.

The architecture guide describes implemented capabilities, module boundaries and limitations. The 31 interactive diagrams show component relationships, protocol exchanges and lifecycle transitions.

Capabilities

  • Generated MDM commands, responses, check-in messages, profiles, declarations and status types from a pinned Apple schema, with validation and platform support metadata.
  • Enrollment lifecycle, certificate pinning, command queues, hooks and typed events. Account-driven enrollment associates authenticated accounts with issued certificates.
  • Profile-based enrollment, Automated Device Enrollment, account-driven Device Enrollment and account-driven User Enrollment, with user-channel and Shared iPad handling.
  • SCEP and ACME identity issuance, Managed Device Attestation verification, and optional certificate revocation services. Hardware support and trust policy require configuration.
  • Declarative device management with versioned declaration snapshots, sets, membership, status reports, subscriptions and synchronization notifications.
  • APNs, device enrollment service (dep), software lookup (gdmf) and Apple Business Manager and Apple School Manager API (axm) clients, with test servers.
  • In-memory, SQLite, PostgreSQL and MySQL persistence; column sealing and key rotation for selected secrets; optional shared security state and inbound rate limits.
  • A device simulator, an admin API with scoped credentials and Cedar policies, and projected event sinks and audit records.

Simulator tests verify the modeled protocol exchanges. Physical-device interoperability, hardware attestation and deployment-specific trust configuration require separate validation.

Reference server

server/cmd/dmserver supports all, mdm and ddm roles. all runs the device service and DDM engine together. mdm serves device traffic and can forward DDM requests to the ddm role through DM_DDM_URL. The private proxy protocol requires request and response HMAC keys; requires HTTPS and shared replay protection. It is specific to this project's adapters.

Configuration is read from DM_* environment variables. This table groups the main settings; server/internal/app/env.go defines their parsing and defaults.

Variables Purpose
DM_ROLE, DM_LISTEN, DM_STORAGE, DM_DSN Role, listen address, backend (sqlite, postgres, mysql, inmem), and DSN
DM_ADMIN_STORE Open the admin principal and Cedar policy store on this process's database, so dmctl principals and dmctl policies work. Disabled by default; enables principal and policy management routes
DM_ADMIN_TOKEN Break-glass bearer token for /admin/v1/. Authenticates as root and bypasses policy, has no expiry, and cannot be revoked without a restart. It exists because an empty principal store authenticates nobody: set it to create the first principals, then unset it and restart. Its use is audited under the actor break-glass, and dmctl status reports whether it is still accepted
DM_STORAGE_KEYS, DM_STORAGE_KEY_<NAME>, DM_SECRETS_DIR, DM_STORAGE_KEYS_STRICT Keys sealing the secret columns of a persistent store: escrow and private keys, raw check-ins and command/results, protocol state and credential-bearing declarations. DM_STORAGE_KEYS lists key names active-first, and the material comes from DM_STORAGE_KEY_<NAME> or from files in DM_SECRETS_DIR. A rotation prepends a name and runs Rewrap; DM_STORAGE_KEYS_STRICT then refuses any row still in clear. A persistent backend will not start without this
DM_ALLOW_REENROLL Permit a changed certificate during Authenticate. Disabled by default in both the reusable service and reference server. Enable only with an enrollment authorization policy that permits the replacement; certificate chain validation alone does not bind a certificate to an enrollment identifier
DM_DDM_URL, DM_DDM_SEND_KEY, DM_DDM_RECV_KEY, DM_DDM_ROOT_CA_FILE, DM_DDM_SUBSCRIPTIONS The split-deployment hop and synthesized status subscriptions. Independent random keys of at least 32 bytes and HTTPS are required: the hop carries a check-in verbatim and the receiving role trusts the enrollment id in that body
DM_CA_FILE, DM_CERT_HEADER, DM_TRUSTED_PROXIES Verified direct mTLS/CMS or a trusted socket peer forwarding one validated certificate; protect the backend with TLS or loopback
DM_PUBLIC_URL, DM_PUSH_TOPIC Turn on the enrollment routes; the server URL devices are given and the push topic
DM_ENROLL_CA_CERT_FILE, DM_ENROLL_CA_KEY_FILE, DM_ENROLLMENT_POLICY_FILE Persistent CA material and explicit device/account admission policy. Empty policy denies issuance. SCEP profiles carry expiring random credentials bound to one CSR. Only memory storage permits an ephemeral development CA
DM_IDENTITY Where an enrolled device's identity comes from: scep (the default) or acme
DM_ACME_POLICY, DM_ACME_KEY, DM_ACME_HMAC_KEY, DM_ACME_ANCHOR_FILE, DM_ACME_ALLOW_UNATTESTED, DM_ACME_IDENTIFIER_TTL Which devices may enroll (any, dep, sip), the key the device generates (ec256, ec384, rsa2048, rsa4096), the key that mints client identifiers, extra attestation anchors for a lab, whether a device that cannot attest may enroll, and how long a client identifier stays usable
DM_PROFILE_IDENTIFIER, DM_ORGANIZATION Enrollment profile identity
DM_DISCOVERY, DM_ACCOUNT_DRIVEN_METHOD Service discovery per user type (Mac=mdm-adde,iPhone=mdm-byod) and the account-driven flow (apple-as-web or apple-oauth2)
DM_OIDC_ISSUER, DM_OIDC_CLIENT_ID, DM_OIDC_CLIENT_SECRET The identity provider behind the ADE web view and account-driven pages
DM_ADE_ANCHOR_FILE, DM_ADE_AUDIT, DM_REQUIRE_USER_AUTH Extra MachineInfo signing anchors, audit-only signature policy, and the requirement for a stored UserAuthenticate token on eligible user-channel TokenUpdate requests
DM_RETURN_TO_SERVICE Enable the ReturnToService response that authorizes erasure and re-enrollment. Disabled by default; device eligibility follows Apple's protocol requirements
DM_AXM_CLIENT_ID, DM_AXM_KEY_ID, DM_AXM_KEY_FILE, DM_AXM_SCOPE, DM_AXM_BASE_URL, DM_AXM_TOKEN_URL Apple Business Manager API credentials; enables /admin/v1/axm/
DM_AUDIT_STORE, DM_AUDIT_RETENTION Persist projected events to the audit trail on this process's database, and how long to keep records (unset keeps them forever). Read it at GET /admin/v1/audit or with dmctl audit list --since 1h
DM_AUDIT_LOG, DM_WEBHOOK_URL, DM_WEBHOOK_HMAC_KEY Event sinks: a projected slog record per state change, and a MicroMDM-compatible webhook with an optional SHA-256 body signature. Both off by default. The webhook envelope matches MicroMDM and NanoMDM except that it carries no raw_payload, because theirs is the raw check-in body and a TokenUpdate body contains the device unlock token
DM_DEP_BASE_URL, DM_DEP_SYNC_INTERVAL, DM_DEP_ASSIGN_INTERVAL, DM_DEP_PROFILE_URL, DM_DEP_USE_PUT Device enrollment service endpoint, the background sync worker, and the DEP profile URL (defaults to this server)
DM_PUSH_SOURCE, DM_PUSH_CERT_FILE, DM_PUSH_KEY_FILE, DM_PUSH_HOST, DM_PUSH_COALESCE, DM_PUSH_CERT_TTL Where APNs credentials come from and how pushes are shaped: off, file (the PEM pair, selected implicitly when a certificate file is configured) or store (the push certificate store). The APNs topic is derived from the push certificate; DM_PUSH_TOPIC separately configures the enrollment profile topic; DM_PUSH_HOST overrides the APNs endpoint for a lab, DM_PUSH_COALESCE is the window repeated pushes collapse into (negative disables it), and DM_PUSH_CERT_TTL how long a store-backed certificate is cached before its version is rechecked
DM_PKI_REVOCATION, DM_RATE_LIMITS Certificate revocation is enabled by default; inbound rate limiting requires configuration. See enrollment security operations for their configuration and operational requirements.

server/cmd/dmctl provides typed commands for enrollments, queued commands, push certificates, declarations, sets, notifications, principals, policies and audit records. dmctl routes lists the active server routes; dmctl api <METHOD> <path> accesses routes without a typed command. Availability depends on the role and enabled services.

Development

git submodule update --init
make verify       # deterministic schema regeneration and exported-name guard
make test         # both modules, race detector and coverage
make testdb-up     # PostgreSQL and MySQL integration databases in Docker
make test-storage # requires the TEST_*_DSN values printed by testdb-up
make test-e2e     # simulator scenarios
make fuzz-smoke
make coverage     # checks the collected coverage profiles

Use make help for target details. The coverage floor is 95% overall and per non-exempt package. See CONTRIBUTING.md, the test scenarios and the threat model.

Sources

Apple's Device Management documentation and the pinned device-management schema define the protocol. The reference catalogue records additional sources. Design decisions explain this project's implementation choices.

License

MIT. See LICENSE.

Directories

Path Synopsis
appleplatformservices
axm
Package axm provides a typed client for the Apple Business Manager and Apple School Manager APIs.
Package axm provides a typed client for the Apple Business Manager and Apple School Manager APIs.
axm/axmtest
Package axmtest provides an in-process Apple Business Manager and Apple School Manager API fake.
Package axmtest provides an in-process Apple Business Manager and Apple School Manager API fake.
dep
Package dep implements Apple's device enrollment service client, token exchange, device synchronization and profile assignment.
Package dep implements Apple's device enrollment service client, token exchange, device synchronization and profile assignment.
dep/deptest
Package deptest provides a device enrollment service fake, store contract suites and failure injection.
Package deptest provides a device enrollment service fake, store contract suites and failure injection.
gdmf
Package gdmf reads Apple's software lookup catalog and selects operating system versions for devices.
Package gdmf reads Apple's software lookup catalog and selects operating system versions for devices.
gdmf/gdmftest
Package gdmftest supplies a fixture catalog, HTTP server and in-memory software Lookup for tests.
Package gdmftest supplies a fixture catalog, HTTP server and in-memory software Lookup for tests.
push
Package push defines notification targets, results, certificate sources and coalescing for MDM pushes.
Package push defines notification targets, results, certificate sources and coalescing for MDM pushes.
push/apns
Package apns implements certificate-authenticated APNs HTTP/2 clients for MDM wake-ups and ordinary app alert/background notifications.
Package apns implements certificate-authenticated APNs HTTP/2 clients for MDM wake-ups and ordinary app alert/background notifications.
push/pushtest
Package pushtest provides a scripted push.Pusher and an in-process APNs server.
Package pushtest provides a scripted push.Pusher and an in-process APNs server.
Package clock abstracts time with a real clock and a manually advanced concurrent-safe fake.
Package clock abstracts time with a real clock and a manually advanced concurrent-safe fake.
cmd
admgen command
Package main implements the admgen schema-generation command.
Package main implements the admgen schema-generation command.
internal
canonjson
Package canonjson implements the JSON Canonicalization Scheme defined by RFC 8785.
Package canonjson implements the JSON Canonicalization Scheme defined by RFC 8785.
cbor
Package cbor encodes and decodes the CBOR subset used by Managed Device Attestation objects.
Package cbor encodes and decodes the CBOR subset used by Managed Device Attestation objects.
layout
Package layout builds repository import graphs for dependency-boundary tests.
Package layout builds repository import graphs for dependency-boundary tests.
scepwire
Package scepwire builds SCEP CMS messages with per-message algorithms.
Package scepwire builds SCEP CMS messages with per-message algorithms.
schemagen
Package schemagen generates schema types, registries, validators, support metadata and conformance tests from Apple's YAML.
Package schemagen generates schema types, registries, validators, support metadata and conformance tests from Apple's YAML.
mdmprotocol
cms
Package cms signs and verifies attached and detached CMS signatures used by Apple device management.
Package cms signs and verifies attached and detached CMS signatures used by Apple device management.
ddm
Package ddm implements declarations, membership, snapshots, synchronization tokens and status handling for declarative device management.
Package ddm implements declarations, membership, snapshots, synchronization tokens and status handling for declarative device management.
ddm/predicate
Package predicate parses and evaluates a subset of NSPredicate syntax for declarative device management activations.
Package predicate parses and evaluates a subset of NSPredicate syntax for declarative device management activations.
dmhook
Package dmhook defines service-operation metadata and the hook interface for observing or vetoing operations.
Package dmhook defines service-operation metadata and the hook interface for observing or vetoing operations.
enroll
Package enroll builds MDM enrollment profiles and serves the over-the-air Profile Service protocol.
Package enroll builds MDM enrollment profiles and serves the over-the-air Profile Service protocol.
enroll/accountdriven
Package accountdriven implements account-driven Device Enrollment and account-driven User Enrollment authentication.
Package accountdriven implements account-driven Device Enrollment and account-driven User Enrollment authentication.
enroll/ade
Package ade serves Automated Device Enrollment profiles after parsing and verifying signed MachineInfo.
Package ade serves Automated Device Enrollment profiles after parsing and verifying signed MachineInfo.
enroll/adetest
Package adetest constructs signed MachineInfo and its request carriers for Automated Device Enrollment tests.
Package adetest constructs signed MachineInfo and its request carriers for Automated Device Enrollment tests.
enroll/discovery
Package discovery serves account-driven enrollment service discovery at /.well-known/com.apple.remotemanagement.
Package discovery serves account-driven enrollment service discovery at /.well-known/com.apple.remotemanagement.
enroll/webauth
Package webauth implements an OpenID Connect relying party for enrollment browser authentication.
Package webauth implements an OpenID Connect relying party for enrollment browser authentication.
enroll/webauth/webauthtest
Package webauthtest supplies an OpenID Connect provider and browser-flow helpers for enrollment tests.
Package webauthtest supplies an OpenID Connect provider and browser-flow helpers for enrollment tests.
event
Package event provides an in-process bus for typed events with enrollment, actor and timestamp metadata.
Package event provides an in-process bus for typed events with enrollment, actor and timestamp metadata.
mdm
Package mdm defines enrollment identities and decodes Apple MDM check-in, command and response envelopes.
Package mdm defines enrollment identities and decodes Apple MDM check-in, command and response envelopes.
plist
Package plist wraps XML and binary property-list encoding and bounded decoding.
Package plist wraps XML and binary property-list encoding and bounded decoding.
profile
Package profile composes, signs and parses Apple configuration profiles.
Package profile composes, signs and parses Apple configuration profiles.
Package paging defines cursor-page requests, generic results and shared page-size bounds.
Package paging defines cursor-page requests, generic results and shared page-size bounds.
pki
acme
Package acme serves the ACME protocol used by Apple device identity payloads, including device-attest-01.
Package acme serves the ACME protocol used by Apple device identity payloads, including device-attest-01.
acme/attest
Package attest parses and verifies Managed Device Attestation certificate chains and objects.
Package attest parses and verifies Managed Device Attestation certificate chains and objects.
acme/attest/attesttest
Package attesttest generates Managed Device Attestation test chains and property extensions.
Package attesttest generates Managed Device Attestation test chains and property extensions.
acme/jose
Package jose parses, verifies and produces the JWS and JWK forms used by ACME.
Package jose parses, verifies and produces the JWS and JWK forms used by ACME.
ca
Package ca defines certificate signing, issuance storage and policy for enrollment identities.
Package ca defines certificate signing, issuance storage and policy for enrollment identities.
pushcert
Package pushcert inspects APNs certificates, validates MDM and app identities, and generates customer CSRs and Apple vendor-signed portal requests.
Package pushcert inspects APNs certificates, validates MDM and app identities, and generates customer CSRs and Apple vendor-signed portal requests.
revocation
Package revocation records issuance and irreversible revocation and publishes issuer-signed CRL and OCSP status.
Package revocation records issuance and irreversible revocation and publishes issuer-signed CRL and OCSP status.
scep
Package scep serves SCEP enrollment and renewal and provides a client for identity issuance.
Package scep serves SCEP enrollment and renewal and provides a client for identity issuance.
Package ratelimit implements optional atomic GCRA quotas with bounded, expiring state.
Package ratelimit implements optional atomic GCRA quotas with bounded, expiring state.
schema
checkin
Package checkin holds the MDM check-in messages generated from Apple's device management schema: 9 schema files and 14 types.
Package checkin holds the MDM check-in messages generated from Apple's device management schema: 9 schema files and 14 types.
commands
Package commands holds the MDM commands and their responses generated from Apple's device management schema: 65 schema files and 220 types.
Package commands holds the MDM commands and their responses generated from Apple's device management schema: 65 schema files and 220 types.
ddm
Package ddm holds the declarative device management declarations generated from Apple's device management schema: 52 schema files and 113 types.
Package ddm holds the declarative device management declarations generated from Apple's device management schema: 52 schema files and 113 types.
ddmproto
Package ddmproto holds the declarative device management protocol messages generated from Apple's device management schema: 3 schema files and 7 types.
Package ddmproto holds the declarative device management protocol messages generated from Apple's device management schema: 3 schema files and 7 types.
errors
Package errors holds the enrollment error response bodies generated from Apple's device management schema: 5 schema files and 10 types.
Package errors holds the enrollment error response bodies generated from Apple's device management schema: 5 schema files and 10 types.
internal/conformance
Package conformance supplies encoding round-trip and validation helpers for generated schema tests.
Package conformance supplies encoding round-trip and validation helpers for generated schema tests.
other
Package other holds the other device management data formats generated from Apple's device management schema: 5 schema files and 10 types.
Package other holds the other device management data formats generated from Apple's device management schema: 5 schema files and 10 types.
profiles
Package profiles holds the configuration profile payloads generated from Apple's device management schema: 127 schema files and 230 types.
Package profiles holds the configuration profile payloads generated from Apple's device management schema: 127 schema files and 230 types.
status
Package status holds the declarative device management status items generated from Apple's device management schema: 48 schema files and 80 types.
Package status holds the declarative device management status items generated from Apple's device management schema: 48 schema files and 80 types.
support
Package support queries generated platform, version, channel and enrollment-context metadata.
Package support queries generated platform, version, channel and enrollment-context metadata.
validation
Package validation collects constraint failures from generated schema validators.
Package validation collects constraint failures from generated schema validators.
Package secrets provides named credential sources and a value type that redacts formatted output.
Package secrets provides named credential sources and a value type that redacts formatted output.
server module
Package simulator exercises modeled Apple MDM and enrollment flows as a device-side test client.
Package simulator exercises modeled Apple MDM and enrollment flows as a device-side test client.
Package state defines transactional, expiring byte records for protocol state.
Package state defines transactional, expiring byte records for protocol state.
Package storage defines MDM persistence contracts and shared sentinel errors.
Package storage defines MDM persistence contracts and shared sentinel errors.
acme/acmetest
Package acmetest defines ACME store contracts, fixtures and controlled failures.
Package acmetest defines ACME store contracts, fixtures and controlled failures.
acme/inmem
Package inmem implements a mutex-protected in-memory acme.Store.
Package inmem implements a mutex-protected in-memory acme.Store.
crypt
Package crypt seals byte values with AES-256-GCM using named keys from secrets.Provider.
Package crypt seals byte values with AES-256-GCM using named keys from secrets.Provider.
ddm/ddmtest
Package ddmtest defines transactional declaration-store contracts and fixtures.
Package ddmtest defines transactional declaration-store contracts and fixtures.
ddm/inmem
Package inmem implements a mutex-protected in-memory ddm.Store.
Package inmem implements a mutex-protected in-memory ddm.Store.
dep/inmem
Package inmem implements a mutex-protected in-memory device enrollment service store.
Package inmem implements a mutex-protected in-memory device enrollment service store.
inmem
Package inmem implements a mutex-protected MDM store for tests and development.
Package inmem implements a mutex-protected MDM store for tests and development.
storagetest
Package storagetest defines the contract suites every MDM storage backend runs.
Package storagetest defines the contract suites every MDM storage backend runs.
Package telemetry provides explicit OpenTelemetry configuration, bounded vocabularies and outbound HTTP measurement.
Package telemetry provides explicit OpenTelemetry configuration, bounded vocabularies and outbound HTTP measurement.
telemetrytest
Package telemetrytest records OpenTelemetry measurements and spans for assertions.
Package telemetrytest records OpenTelemetry measurements and spans for assertions.
Package testpki creates ephemeral certificate authorities and identities for tests and the device simulator.
Package testpki creates ephemeral certificate authorities and identities for tests and the device simulator.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL