Advanced Install Methods
The Quick Install page covers the happy path — a pre-configured MSI or PKG built by the dashboard. This page documents the alternate paths used for silent deployment, MDM, scripted rollouts, air-gapped installs, and environments where Breeze’s MSI signing service is not configured.
If you just want to install on a single machine, use the dashboard installer instead. For end-to-end GPO, Intune, JAMF, and Ansible rollout recipes built on these methods, see the Mass Deployment guide.
Picking a Method
Section titled “Picking a Method”| Method | When to use |
|---|---|
| ZIP bundle | Default fallback when no remote MSI signing service is wired up. Self-contained: signed MSI + credentials + script. |
| MSI with properties | Available when the signing service is configured. Single signed file, properties embedded at sign time or passed at msiexec. |
Direct binary + enroll |
Custom packaging, MDM, Ansible/Chef/Puppet, or container images. Most flexible. |
| Public installer link | Hand off install to an on-site contact via a token-authenticated URL. |
ZIP Bundle (MSI + enrollment.json + install.bat)
Section titled “ZIP Bundle (MSI + enrollment.json + install.bat)”When the API does not have an MSI signing service configured, the dashboard generates a zip bundle instead of a property-injected MSI. The same fallback exists for macOS (PKG + install.sh).
This is also the format you get if you call the underlying buildWindowsInstallerZip / buildMacosInstallerZip paths directly — for example from your own automation calling the enrollment-key download endpoint.
Windows zip contents
Section titled “Windows zip contents”Directorybreeze-agent-windows.zip
- breeze-agent.msi The unmodified, signed agent MSI
- enrollment.json Server URL + enrollment key + secret + site ID
- install.bat Calls msiexec, then
breeze-agent enroll
macOS zip contents
Section titled “macOS zip contents”Directorybreeze-agent-macos.zip
- enrollment.json Server URL + enrollment key + secret + site ID
- install.sh Downloads the arch-matched, notarized PKG, verifies it with Gatekeeper, then calls
installer -pkgandbreeze-agent enroll
The PKG itself is no longer bundled in the zip — install.sh downloads the architecture-matched package (Intel or Apple Silicon) at install time, so one zip works on both.
Running the bundle
Section titled “Running the bundle”Extract the zip to any directory, then run install.bat as Administrator:
Expand-Archive breeze-agent-windows.zip -DestinationPath C:\breeze-installcd C:\breeze-installStart-Process -FilePath .\install.bat -Verb RunAs -WaitThe script will:
- Run
msiexec /i breeze-agent.msi /quiet /norestart - Wait 5 seconds for install to settle
- Read
enrollment.jsonand invoke"%ProgramFiles%\Breeze\breeze-agent.exe" enroll <key> --server <url> [--enrollment-secret <secret>] - Delete
enrollment.jsonso credentials do not persist on disk
unzip breeze-agent-macos.zip -d ~/breeze-installcd ~/breeze-installsudo ./install.shThe script will:
- Detect the Mac’s CPU architecture (Intel or Apple Silicon) and download the matching, notarized
breeze-agent.pkgfrom the server - Verify the download passes Gatekeeper’s notarization assessment (
spctl --assess) before installing it as root sudo installer -pkg breeze-agent.pkg -target /- Read
enrollment.jsonviaplutil -extract - Invoke
sudo <agent> enroll <key> --server <url> [--enrollment-secret <secret>], where<agent>is the binary the package installed:/Library/Breeze/bin/breeze-agentwhen the package put it there, otherwise/usr/local/bin/breeze-agent(the site comes from the enrollment key; the installer no longer passes the deprecated--site-id) - Delete
enrollment.jsonand the downloaded pkg
enrollment.json schema
Section titled “enrollment.json schema”{ "serverUrl": "https://breeze.yourdomain.com", "enrollmentKey": "64-char-lowercase-hex", "enrollmentSecret": "shared-AGENT_ENROLLMENT_SECRET", "siteId": "uuid-of-target-site"}| Field | Required | Notes |
|---|---|---|
serverUrl |
yes | Passed as --server to the agent. Validated server-side at zip generation. |
enrollmentKey |
yes | 64 lowercase hex chars. Server-side regex: ^[a-f0-9]{64}$. |
enrollmentSecret |
optional | Only set when AGENT_ENROLLMENT_SECRET is required by the server. Maps to --enrollment-secret. |
siteId |
yes | Site UUID, for reference only. The device always lands in the site the enrollment key resolves to. The installers no longer pass it as --site-id (deprecated and ignored by the agent). |
If you write your own wrapper, you can ignore the bundled install.bat / install.sh and just feed the JSON values straight into breeze-agent enroll — see Direct binary + manual enroll.
MSI with Properties (Silent Install)
Section titled “MSI with Properties (Silent Install)”When the API does have an MSI signing service configured, the dashboard returns a single signed MSI with credentials baked into the WiX properties at sign time. You can also pass these properties yourself via msiexec:
msiexec /i breeze-agent.msi /qn ` SERVER_URL=https://breeze.yourdomain.com ` ENROLLMENT_KEY=<64-hex-enrollment-key> ` ENROLLMENT_SECRET=<shared-enrollment-secret>| Property | Purpose |
|---|---|
SERVER_URL |
Breeze API base URL. |
ENROLLMENT_KEY |
64-hex enrollment key. Marked Hidden="yes" so it does not appear in MSI logs. |
ENROLLMENT_SECRET |
Optional AGENT_ENROLLMENT_SECRET. Marked Hidden="yes". |
The MSI’s EnrollAgent custom action runs breeze-agent.exe enroll "[ENROLLMENT_KEY]" --server "[SERVER_URL]" --enrollment-secret "[ENROLLMENT_SECRET]" --quiet directly during install — there is no PowerShell wrapper. A WiX Launch Condition enforces that SERVER_URL and ENROLLMENT_KEY are provided together (both or neither).
If neither property is set, the MSI installs the binaries but skips enrollment. You can then enroll later by running breeze-agent.exe enroll … manually, which is useful when staging an image for cloning.
Direct Binary + Manual Enroll
Section titled “Direct Binary + Manual Enroll”For MDM, configuration management (Ansible, Chef, Puppet, Salt), golden images, or container/VM templates, install the agent binary yourself and call enroll once the host is provisioned.
curl -fsSL -o /usr/local/bin/breeze-agent \ https://breeze.yourdomain.com/api/v1/agents/download/linux/amd64chmod +x /usr/local/bin/breeze-agent
sudo /usr/local/bin/breeze-agent enroll <ENROLLMENT_KEY> \ --server https://breeze.yourdomain.com \ --enrollment-secret <ENROLLMENT_SECRET> \ --quiet
sudo /usr/local/bin/breeze-agent service installcurl -fsSL -o /usr/local/bin/breeze-agent \ https://breeze.yourdomain.com/api/v1/agents/download/darwin/arm64chmod +x /usr/local/bin/breeze-agent
sudo /usr/local/bin/breeze-agent enroll <ENROLLMENT_KEY> \ --server https://breeze.yourdomain.com \ --enrollment-secret <ENROLLMENT_SECRET> \ --quiet
sudo /usr/local/bin/breeze-agent service install# Older PowerShell/.NET defaults (e.g. Windows Server 2016) can omit# TLS 1.2, which makes Invoke-WebRequest fail outright.[Net.ServicePointManager]::SecurityProtocol = ` [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest ` -Uri "https://breeze.yourdomain.com/api/v1/agents/download/windows/amd64" ` -OutFile "C:\Program Files\Breeze\breeze-agent.exe"
& "C:\Program Files\Breeze\breeze-agent.exe" enroll <ENROLLMENT_KEY> ` --server https://breeze.yourdomain.com ` --enrollment-secret <ENROLLMENT_SECRET> ` --quiet
& "C:\Program Files\Breeze\breeze-agent.exe" service installOn macOS, this manual service install path (unlike the .pkg installer) always copies the binary to /Library/Breeze/bin/breeze-agent and the service runs from there, regardless of whether /usr/local/bin would otherwise be safe to run from. The copy you downloaded to /usr/local/bin is only used to enroll and install. See macOS Permissions for when the .pkg installer instead leaves the agent in /usr/local/bin, and grant Full Disk Access at whichever path applies.
breeze-agent enroll — flag reference
Section titled “breeze-agent enroll — flag reference”| Flag | Required | Notes |
|---|---|---|
<enrollment-key> (positional) |
yes | Single positional argument. 64-char enrollment key. |
--server <url> |
yes | API base URL. May also be set in the config file. |
--enrollment-secret <secret> |
optional | The server’s AGENT_ENROLLMENT_SECRET. Required when configured server-side. |
--site-id <uuid> |
deprecated | Ignored: the site comes from the enrollment key. Passing it prints a deprecation warning; the flag will be removed in a future release. |
--device-role <role> |
optional | Override the inferred device role (e.g. workstation, server). |
--force |
optional | Re-enroll a host that already has a config. Replaces agent_id and auth_token only on success — a failed re-enroll leaves the existing config untouched. |
--quiet |
optional | Suppress stdout progress output. Errors still go to stderr. Use for unattended installs. |
--config <path> |
optional (persistent) | Override the default config path (/etc/breeze/agent.yaml, /Library/Application Support/Breeze/agent.yaml, or C:\ProgramData\Breeze\agent.yaml). |
The agent refuses to enroll with an empty hostname — if your provisioning pipeline runs enroll before hostnamectl / scutil --set ComputerName, set the hostname first.
breeze-agent service install — flag reference
Section titled “breeze-agent service install — flag reference”| Flag | Platform | Notes |
|---|---|---|
--no-watchdog |
all | Skip auto-fetching and registering the watchdog, and remember the choice: it writes the watchdog.disabled marker in the agent’s config directory, so later plain service install runs and the running agent’s automatic repair also leave the watchdog alone. Use for air-gapped hosts where the agent cannot reach GitHub releases or the Breeze server’s watchdog download. |
--watchdog |
all | Undo --no-watchdog: remove the marker, reset the watchdog install retry state, and install the watchdog. Cannot be combined with --no-watchdog. |
--strict-watchdog |
all | Exit with code 78 instead of 0 when the agent installed but the watchdog could not be. See exit codes. |
--with-user-helper |
Linux, macOS | Also install the per-user desktop helper unit (systemd user unit / LaunchAgent). Not needed on Windows — the helper is spawned per-session by the service. |
service install is safe to re-run — it overwrites the binary at the install path, records whether the agent service was running beforehand, and rewrites and re-enables the unit. It starts the service again if it was running before the install or the host is already enrolled; a fresh, unenrolled host is left stopped until you enroll it. If the service was stopped for the install and can’t be started again, the command now fails with recovery instructions rather than exiting successfully. It also registers any missing watchdog, which is always restarted so a newly staged binary takes over. Use this to add the watchdog to a previously agent-only install. To install only the watchdog without touching the agent, run breeze-watchdog service install directly.
service install exit codes
Section titled “service install exit codes”| Exit code | Meaning |
|---|---|
0 |
The agent service is installed (and started when it was running before or the host is enrolled). The watchdog either installed, was skipped by --no-watchdog or a standing opt-out, or could not be installed and was deferred to the running agent. |
78 |
Only with --strict-watchdog: the agent installed, but the watchdog did not. Any watchdog failure counts, whether or not the agent could repair it later. |
1 |
The agent itself could not be installed, or its service was stopped for the install and could not be started again. This wins over the watchdog outcome: an agent failure is never reported as 0 or 78. |
When the watchdog is deferred, service install prints the usual warning to stderr and one machine-readable line to stdout:
BREEZE_WATCHDOG_INSTALL=deferred reason=<class><class> is one of network, server, policy, signature, checksum, dev_build, unsupported_os, install_cmd, locked or unknown. It never contains the error text. A failure while verifying the release download during the first install (before enrollment) often reports unknown; the warning on stderr has the detail. Nothing is printed when the watchdog installed or was skipped.
The default is 0 on purpose. The agent did install, and once the host is enrolled the running agent installs the missing watchdog by itself (see Automatic repair of a missing watchdog), so reporting failure would break scripted installs that work today. Use --strict-watchdog in lanes that must not finish without a watchdog, for example golden-image builds. If the running agent is installing the watchdog at that moment, service install leaves the install to it and exits 0 without the marker line, even with --strict-watchdog.
On Linux and macOS, service uninstall stops and removes both the agent and watchdog services (and the installed agent binary), but does not remove agent.yaml or secrets.yaml — wipe /etc/breeze or /Library/Application Support/Breeze manually if you want a clean uninstall. On Windows, service uninstall only deletes the agent’s own SCM service registration — it does not touch the watchdog service, the installed binaries, or C:\ProgramData\Breeze. Run breeze-watchdog service uninstall separately for the watchdog, and remove the binaries/config directory by hand.
Pre-Staging Without Enrollment
Section titled “Pre-Staging Without Enrollment”You can install the agent binary and service on an image without enrolling, then enroll on first boot. This is the standard pattern for VM templates and golden images.
- Install the agent binary (or run the MSI/PKG with no
ENROLLMENT_KEY). - Install the service:
breeze-agent service install. Because the host isn’t enrolled yet, the installer enables the unit but leaves it stopped rather than starting it — there is nothing to talk to a server about until enrollment happens. It comes up automatically the next time the machine reboots (since the unit is enabled), or you can start it manually. - On first boot of a cloned VM, run
breeze-agent enroll <key> --server <url>from a startup script. Once the agent process is actually running and unenrolled, it polls foragent.yaml/secrets.yamlon an interval and connects automatically as soon asenrollwrites them — no restart needed.
If you skip step 2 and run enroll after service install, the service picks up the new credentials within a few seconds without needing a restart.
Programmatic Bundle Generation
Section titled “Programmatic Bundle Generation”If you are building your own provisioning system, the same zip bundles the dashboard produces are available via the enrollment-key API:
POST /api/v1/enrollment-keys/:id/installer-linkThis issues a token-authenticated download URL that returns either:
- A signed MSI / PKG with properties baked in (when the signing service is configured)
- A zip bundle (
breeze-agent-windows.zip/ the equivalent macOS zip) when not
Both responses set Cache-Control: no-store and Content-Disposition: attachment. The download is single-use by default and decrements the parent enrollment key’s maxUsage atomically. See Enrollment Keys for the full API.