Skip to content

Binary Distribution

Breeze serves agent binaries and viewer installers through its own API. The download source is configurable via BINARY_SOURCE, so downloads work regardless of how you deploy.

Set BINARY_SOURCE to control where downloads come from:

Mode Description When to use
github (default) Agents download directly from GitHub Releases CDN Most deployments
local Serve from disk, with optional S3 offload Distribute binaries from your own infrastructure

No local binaries needed. Download requests redirect to GitHub Releases:

GET /api/v1/agents/download/linux/amd64
→ 302 https://github.com/lanternops/breeze/releases/download/v0.11.3/breeze-agent-linux-amd64

The release version is determined by BINARY_VERSION or BREEZE_VERSION. If neither is set, redirects to the latest release.

The repository itself is configurable: BINARY_GITHUB_REPOSITORY (default lanternops/breeze) controls where downloads redirect and where release sync reads from. Self-hosters who sign their own agent packages point this at their signing repository and set RELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS to their own manifest key.

On startup, the API calls GitHub’s Releases API to register the current version’s checksums in the agent_versions table, so agents know when a new version is available.

In production, GitHub mode requires the RELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS env var. This is the base64 SPKI of the Ed25519 public key that signs our release manifests. The API verifies every fetched manifest against this key before trusting its checksums, so a compromised GitHub release alone can’t deliver tampered binaries.

For the official Breeze releases, use the published trust anchor:

Terminal window
RELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS=yzx8ftmcls6uBetFC5SYnZhBo+cbur3IX50TbBthTso=

This is a public key (also embedded in the agent and CI), so it is safe to commit. Only override it if you build and sign your own binaries. The API refuses to start in production without it. During a signing-key rotation you can trust multiple keys at once by comma-separating them (RELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS=old,new).

Official releases also publish *-unsigned build outputs with manifest entries marked intendedUse: "signing-input" and platformTrust: "none". These exist solely as inputs for self-signing and are never registrable or downloadable through the API.

Manifest entries for the Windows assets that are Authenticode-signed (the Viewer and Helper installers) additionally record which certificate authority signed them, so the provider behind a given build is auditable from the signed manifest itself.

macOS package entries record signingIdentity and signingTeamId. The release workflow adds these fields only after pkgutil reports the exact expected Developer ID Installer leaf identity and Apple Team ID for those package bytes.

Binaries are served from disk. The API reads from these directories:

Variable Default Contents
AGENT_BINARY_DIR ./agent/bin Agent binaries (e.g. breeze-agent-linux-amd64)
VIEWER_BINARY_DIR ./viewer/bin Viewer installers (e.g. breeze-viewer-macos.dmg)
HELPER_BINARY_DIR ./agent/bin Helper binaries (e.g. breeze-helper-windows.msi). The bundled docker-compose.yml overrides this to /data/binaries/helper, alongside the other two directories under the shared binaries volume.

macOS agent packages and Breeze Installer.app.zip are privileged installers. Local mode serves them only when the release’s original release-artifact-manifest.json and .ed25519 signature are staged at the parent of AGENT_BINARY_DIR and verify with RELEASE_ARTIFACT_MANIFEST_PUBLIC_KEYS. A deployment-generated manifest that merely signs whatever bytes happen to be on the volume is not a source-authenticity substitute.

On startup, the API:

  1. Scans AGENT_BINARY_DIR for agent binaries
  2. Computes SHA-256 checksums and registers each binary in the agent_versions table
  3. Marks them as the latest version
  4. If S3 is configured, syncs both directories to your S3 bucket

The docker-compose.yml includes a binaries init container that bundles agent and viewer binaries into a shared volume:

services:
binaries-init:
image: ${BREEZE_BINARIES_IMAGE_REF:?Set BREEZE_BINARIES_IMAGE_REF to a digest-pinned image ref}
pull_policy: always
volumes:
- binaries:/target
restart: "no"
api:
volumes:
- binaries:/data/binaries:ro
environment:
BINARY_SOURCE: ${BINARY_SOURCE:-github}
AGENT_BINARY_DIR: /data/binaries/agent
VIEWER_BINARY_DIR: /data/binaries/viewer
HELPER_BINARY_DIR: /data/binaries/helper
depends_on:
binaries-init:
condition: service_completed_successfully

The init container:

  1. Runs on every docker compose up (pull_policy: always ensures the registry is re-checked for the image ref you’ve pinned in BREEZE_BINARIES_IMAGE_REF, which must be set — there is no latest fallback)
  2. Copies bundled binaries to the shared binaries volume
  3. Exits (restart: “no”)
  4. The API mounts the volume read-only

When BINARY_SOURCE=github (default), the API ignores the local volume and syncs versions from GitHub Releases instead. The volume is only used when BINARY_SOURCE=local.

When BINARY_SOURCE=local and S3 credentials are configured, Breeze:

  1. On startup: syncs local binaries to your S3 bucket
  2. On download: returns a 302 redirect to a presigned S3 URL for ordinary artifacts (falls back to disk if the object is absent). Privileged macOS packages are the exception: the API reads them with a signed-size bound, verifies the signed release-manifest digest, and proxies the exact verified bytes instead of redirecting the client.

This offloads download bandwidth from your API server to S3/R2/MinIO.

Variable Default Description
S3_ENDPOINT S3-compatible endpoint
S3_ACCESS_KEY Access key
S3_SECRET_KEY Secret key
S3_BUCKET Bucket name
S3_REGION us-east-1 Bucket region
S3_PRESIGN_TTL 900 Presigned URL expiration in seconds (15 min)

S3 is activated when S3_BUCKET, S3_ACCESS_KEY, and S3_SECRET_KEY are all set. Files are uploaded to:

  • s3://{bucket}/agent/ — agent binaries
  • s3://{bucket}/viewer/ — viewer installers

Helper and user-helper binaries are not synced to S3 — downloads for those fall through to disk even when S3 is configured.

GET /api/v1/agents/download/:os/:arch
Parameter Values
os linux, darwin, windows
arch amd64, arm64
GET /api/v1/agents/download/windows/amd64/msi

Serves the staged breeze-agent.msi verbatim, with no per-download bootstrap token embedded — unlike the enrollment-installer routes, so the file has a stable checksum. The automatic edition-migration flow pins its own download to a sha256 computed from this same file and verifies before touching an installed agent. Disk-only: unlike the routes above, it does not redirect to GitHub or S3, so a BINARY_SOURCE=github deployment gets a 404 here.

GET /api/v1/agents/download/:os/:arch/pkg

os must be darwin. Serves the notarized .pkg used by install.sh’s macOS path, which verifies the download via Apple notarization (spctl --assess) rather than a checksum comparison against /agent-versions/latest.

GET /api/v1/viewers/download/:platform
Parameter Values File
platform macos breeze-viewer-macos.dmg
windows breeze-viewer-windows.msi
linux breeze-viewer-linux.AppImage
GET /api/v1/agents/download/helper/:os/:arch
Parameter Values
os linux, darwin, windows
arch amd64, arm64

Helper binaries are companion processes used for remote desktop in headless/service contexts (Session 0 on Windows, LaunchDaemon on macOS, systemd on Linux).

GET /api/v1/agents/download/watchdog/:os/:arch
Parameter Values
os linux, darwin, windows
arch amd64, arm64

breeze-watchdog runs as its own service (BreezeWatchdog on Windows) alongside the agent and restarts it if it stops responding. The agent’s own self-update and failover logic fetch replacement watchdog builds through this same route.

GET /api/v1/agents/download/user-helper/:os/:arch
Parameter Values
os linux, darwin, windows
arch amd64, arm64

breeze-user-helper is a distinct binary from the Helper installers above (/viewers/download and the Helper Binaries section) — it’s the GUI-subsystem sibling of the agent that the agent’s session broker spawns into the interactive user session (prompts and remote-desktop UI in headless/service contexts), not the standalone Helper app.

The breeze-backup binary handles enterprise backup operations (Hyper-V, MSSQL, system image, cloud-to-cloud). It is bundled in installers and served through the download API:

  • Windows MSI: installed to the same directory as breeze-agent.exe
  • macOS .pkg: installed to /usr/local/bin/breeze-backup
  • Linux: fetched by the generated install script alongside the agent binary
GET /api/v1/agents/download/backup/:os/:arch

The backup binary communicates with the main agent over HMAC-signed IPC. As of v0.105.0 its version is slaved to the agent’s: the agent downloads and atomically swaps breeze-backup as part of its own auto-update, so the helper no longer stays frozen at whatever version the installer shipped. A periodic reconcile also re-fetches the helper if it is missing or stale.

GET /api/v1/agents/install.sh

One-line agent installer that auto-detects OS/arch, downloads the binary, enrolls, and installs as a system service.

GET /api/v1/agents/uninstall.sh

Companion to the install script, for Linux and macOS. Stops and removes the agent, watchdog, and backup services and binaries. Windows agents are removed through the MSI’s own uninstall (Apps & Features / msiexec /x), not this endpoint.

Agents download directly from GitHub. No configuration needed:

.env
# BINARY_SOURCE=github (default, no change needed)