-
Notifications
You must be signed in to change notification settings - Fork 0
Serving Manifests and Packages
BootstrapMate needs one manifest URL and one URL per payload, all reachable from a Mac that is still inside Setup Assistant. This page covers what the host has to do, what BootstrapMate does and does not check about the response, and how to prove a host is serving correctly before you point a fleet at it.
The manifest URL comes from the url preference or --jsonurl; each payload URL comes from the
url field of its manifest item. Both are fetched with a plain HTTP GET.
The file extension of the URL path decides how the manifest is parsed. A path ending .yaml
or .yml is parsed as YAML, .json is parsed as JSON, and anything else is tried as JSON first
and YAML second. Query parameters do not interfere with that detection, so a signed URL such as
https://example.com/bootstrap/manifest.json?token=… still parses as JSON. The response's
Content-Type is never consulted, so a host that serves the manifest as
application/octet-stream still works.
Payload URLs have no extension requirement. Each item's file field decides where the bytes
land on disk, and the hash field decides whether they are accepted.
Serve everything over HTTPS. Nothing in the tool enforces it, and there is no certificate pinning, but the manifest is neither signed nor hash-checked and its contents are executed as root, so a manifest fetched in plaintext is an open invitation. See Security and Package Verification.
Redirects are always followed, on the manifest and on payloads alike. The
--follow-redirects flag and the matching followRedirects preference and manifest field are
read but have no effect in either direction, so you cannot turn redirect-following off. See
Troubleshooting and Gotchas.
Two things follow from that. A host that redirects https://example.com/bootstrap/manifest to
https://example.com/bootstrap/manifest.json works, but the parser sees the requested URL,
not the final one, so the extension on the URL you configure is the one that matters. And a
redirect to a different origin is followed silently, taking the Authorization header with it.
BootstrapMate supports exactly one credential for downloads: the complete value of an
Authorization header, supplied as --headers or the headers preference. Set it to the whole
header value, including the scheme:
Bearer YOUR_AUTH_TOKEN_HERE
Basic BASE64_OF_USER_COLON_PASSWORD
There is no way to send any other header, no way to send more than one credential, and no way to scope a credential to a host. The same value is attached to the manifest request and to every payload download in the manifest, whichever host the payload URL names. If some payloads live on a host that should not see your credential, use pre-signed URLs for those rather than a shared header.
Reporting uses its own credential, the reportingHeader preference, and is never sent to
download hosts. See Preferences.
Both patterns work, with caveats.
Caching is disabled at the client: the URL cache is off and requests are made with
reloadIgnoringLocalAndRemoteCacheData, so BootstrapMate always asks the origin chain for
fresh bytes. This matters because the per-item SHA-256 is the only signal that a payload
changed. If your CDN serves a stale manifest anyway, Macs compare new payloads against old
hashes, decide the files they already have are still valid, and never re-download. Purge the
manifest on the CDN whenever you publish a new one, or serve the manifest from the origin and
only the payloads from the CDN.
If the origin is private and access is granted by a rewritten header or a signed URL at the
edge, remember that BootstrapMate sends only the one Authorization value and follows every
redirect. A CDN rule that swaps an inbound header for an origin credential is compatible with
that; a scheme that needs a second header, or a challenge-response, is not.
Two operational constraints are worth planning around. Each payload is downloaded into memory in full before being written to disk, so very large payloads are resident in RAM during the download. And each download has a 120-second ceiling, with the manifest fetch capped at 60 seconds, so a slow origin fails the item rather than stalling the run.
Run these from a machine on a network like the one your Macs enroll from, not from inside the hosting environment.
Confirm the manifest returns 200 and see what the host claims it is. Content-Type is not used
by BootstrapMate, but a text/html type here usually means you are looking at an error page or
a login redirect.
curl -sS -D - -o /dev/null -L https://example.com/bootstrap/manifest.json
Confirm the body is the manifest and not an error page, and that it parses.
curl -sSL https://example.com/bootstrap/manifest.json | python3 -m json.tool | head -40
If the manifest is behind a credential, confirm it works with the exact header value you will put in the profile.
curl -sS -o /dev/null -w '%{http_code}\n' -L -H "Authorization: Bearer YOUR_AUTH_TOKEN_HERE" https://example.com/bootstrap/manifest.json
Confirm every payload URL is reachable and returns 200, using the same credential.
curl -sS -o /dev/null -w '%{http_code} %{size_download} %{url_effective}\n' -L -H "Authorization: Bearer YOUR_AUTH_TOKEN_HERE" https://example.com/bootstrap/payloads/Example-1.0.pkg
Confirm a payload's digest matches the hash in the manifest. Any mismatch here is the same
mismatch a Mac will hit.
curl -sSL -H "Authorization: Bearer YOUR_AUTH_TOKEN_HERE" -o /tmp/Example-1.0.pkg https://example.com/bootstrap/payloads/Example-1.0.pkg && shasum -a 256 /tmp/Example-1.0.pkg
Then run the whole thing end to end without changing the Mac.
sudo /usr/local/bootstrapmate/managedbootstrapinstall --jsonurl https://example.com/bootstrap/manifest.json --verbose --dry-run --no-dialog
- Manifest URL path ends in
.json,.yamlor.yml. - Manifest and every payload return 200 over HTTPS with no interactive login in the way.
- Every payload's SHA-256 matches the
hashin the manifest. - The manifest is purged from any CDN cache whenever it is republished.
- Packages are signed by the Team ID you configured, or the exceptions are declared per item.
- If a credential is required, it is a single
Authorizationvalue that works for the manifest and for every payload host in the manifest. - The URLs resolve on the network the Macs enroll from, including any split-DNS or filtering that applies before a user has logged in.