-
Notifications
You must be signed in to change notification settings - Fork 0
Manifests
A manifest is the document BootstrapMate downloads and executes. It lists every package and script a freshly enrolled Mac should receive, grouped into three stages. This page covers what a manifest is, the two file formats, how BootstrapMate fetches one, and how to check a manifest before you point a fleet at it.
Note the vocabulary collision: this is not a Munki manifest. BootstrapMate's manifest is the bootstrap document in the InstallApplications sense — see Glossary.
A manifest is a single document with three optional top-level arrays: preflight,
setupassistant and userland. Each array holds items, and each item is one package or
one script. The stages always run in that order. Every field is documented in
Manifest Reference; the stages themselves in Stages.
There is no include, import or nesting mechanism. One URL yields one document, and that document is the whole run.
BootstrapMate accepts both, and picks the parser from the path extension of the manifest URL, not from the content:
-
.yamlor.yml— parsed as YAML. -
.json— parsed as JSON. - Any other extension, or none — parsed as JSON first, then retried as YAML if that fails.
Query parameters after the path do not affect detection. The two formats express exactly
the same schema, so bootstrap.json and bootstrap.yaml are interchangeable as long as
the key names match. Serving YAML from a URL that ends in .json still works, because the
JSON attempt fails and the YAML fallback succeeds — but naming the file for its format is
less surprising.
Key names are the Swift property names verbatim, so they are camelCase: skipIf,
followRedirects, expectedTeamID, allowUnsigned. Snake-case spellings such as
skip_if are not recognised and are silently ignored by both decoders.
Point BootstrapMate at the manifest with --jsonurl, or set jsonUrl (aliases url,
jsonurl, JsonUrl, ConfigURL, ManifestURL) in the com.github.bootstrapmate
managed-preference domain. The LaunchDaemon installed by the package passes no arguments,
so on an MDM-driven run the URL must come from the profile. See
Preferences and Deployment.
The fetch has a 60-second ceiling. If it fails — HTTP error, timeout, or a document that
will not decode — the run logs Failed to decode BootstrapManifest: … and exits 1. Nothing
is retried at this level; manifest retry settings apply to item payloads, not to the
manifest itself.
Serve manifests over HTTPS. If the origin needs authentication, supply a complete header
value with --headers or the authorizationHeader preference (aliases headers,
Headers, AuthorizationHeader); it is sent as the Authorization header on the manifest
fetch and on every item download. There is no separate username/password option and no
per-item header. Details in
Serving Manifests and Packages.
HTTP status codes are not inspected on item downloads. A 404 error page is written to the
item's file path and then fails the SHA-256 check, so a broken URL surfaces as a hash
mismatch rather than as a 404.
Confirm the document parses and the hashes are right before an enrolled Mac depends on it. Parse it locally first:
python3 -c 'import json,sys; json.load(open("bootstrap.json"))'
Compute each item's hash from the exact bytes you are serving:
shasum -a 256 munkitools.pkg
Then run the CLI against the URL on a test Mac with output on the console:
/usr/local/bootstrapmate/managedbootstrapinstall --jsonurl https://example.com/bootstrap.json --verbose --no-dialog --dry-run
--dry-run suppresses downloads only — each item logs [Dry Run] Would download <name>.
The install and script steps are still attempted, so a dry run against a real manifest will
report failures for payloads it never fetched. It is a way to confirm the document decodes
and the stages and item list are what you expect, not a full no-op rehearsal.
A real end-to-end test needs a machine you can re-run: the bootstrap LaunchDaemon removes itself after any completed run, so re-testing means re-installing the package or invoking the CLI by hand.