Deploying the CloudZero AI Collector With MDM
This guide is written for an MDM administrator deploying the CloudZero AI Collector to managed Macs. It assumes fluency with configuration profiles, custom .mobileconfig payloads, scoping, UAMDM enrollment, and the macOS approval model. It explains only the CloudZero-specific values and behaviors, not MDM itself.
What to expect
At a glance, CloudZero deploys to managed Macs as a set of configuration profiles plus a signed installer package, with updates handled either in-app or by your MDM.
For the admin. A deployment is three things pushed to the target group:
- The approval profiles (system extension, transparent proxy, login items).
- The managed-preferences profile (API key; optionally identity and update settings).
- The installer package.
The profiles are delivered before the installer. Once they are in place, the system extension, transparent proxy, and background agent are configured without user approval prompts, identity values are pre-filled, and the API key is pre-provisioned at first launch. Verify with the commands in Install.
For the end user. On first launch the user goes through a short one-time flow:
- A macOS keychain prompt to trust the CloudZero CA (login password or Touch ID).
- The CloudZero setup wizard: sign in to Claude.ai, select organization, review identity (pre-filled and locked where managed), and the API key (shown as managed and already provisioned, not entered by the user when managed).
After that, the menu-bar app runs and telemetry flows.
The first-launch flow is not fully silent. The CA-trust step cannot be suppressed today: the CA is generated per user, so no configuration profile can pre-trust it. CloudZero is working on a solution that allows this to happen completely silently. See Certificate trust for details.
Identifiers
The CloudZero AI Collector is code-signed and distributed under a fixed set of identifiers. These are required to manually build the profiles within your MDM solution's profile editor. They also help you confirm the app and its network extension in your MDM console.
| Item | Value |
|---|---|
| Team ID | SHVGZ9V9KP |
| App bundle ID | com.cloudzero.Proxy |
| Network extension bundle ID | com.cloudzero.Proxy.network-extension |
| LaunchAgent label | com.cloudzero.Proxy.agent |
| Managed-prefs domain | com.cloudzero.Proxy |
Deployment profiles
CloudZero installs a single network extension (a transparent proxy) as a macOS system extension, plus a background LaunchAgent and a per-user CA certificate. Without managed configurations, macOS approves that one extension in two separate steps, each behind its own user prompt: first loading it as a system extension, then activating it as the transparent proxy. That is why one extension needs two profiles: the System Extension Policy profile clears the load step, and the Transparent Proxy profile clears the activation step.
Deploy the following configuration profiles to the target group before the installer package; with these profiles, those approvals happen without user prompts. (Certificate trust is the one step that still prompts; see Certificate trust.)
| Profile | Payload type | Approves / suppresses | Silent install |
|---|---|---|---|
| System Extension Policy | com.apple.system-extension-policy | Loads the network extension without approval | Required |
| Transparent Proxy | com.apple.vpn.managed | Activates the proxy without the filter-approval prompt | Required |
| Managed Login Items | com.apple.servicemanagement | Suppresses "Background Items Added" notifications | Recommended |
Optionally, deploy the managed-preferences profiles as well, to provision your org's values before first launch. These are all optional, but recommended. If you do not deploy these profiles, users will be prompted to enter their identity values (email and department) as well as their ingest API key, which users without access to the CloudZero platform may not be able to obtain unless it is distributed through other means.
| Profile | Payload type | Provides | Deploy |
|---|---|---|---|
| Managed preferences (API key) | com.cloudzero.Proxy | Fleet ingest API key | Recommended |
| Update settings | com.cloudzero.Proxy | In-app updater behavior | Recommended |
| Identity (per-user) | com.cloudzero.Proxy | User name and department for attribution | Recommended |
See Managed preferences for the keys and values.
Profile delivery
You can deliver these profiles in a few ways, and it is your choice which you use, depending on how you would like to organize them:
- Upload a profile template. CloudZero publishes each profile as a
.mobileconfigfile you can upload directly as a custom profile; see Configuration profiles. Replace the placeholder values in the managed-preferences payloads before deploying. - Build it in your MDM from the specs in this guide. Each profile's section lists the settings to enter in your MDM's own profile editor. In Microsoft Intune this is the Settings catalog; in Jamf Pro you create a Configuration Profile, add the payload, then scope it to devices with a Smart Group. Most tables show the literal payload keys (like
VPNType); the System Extension Policy table shows friendlier setting names instead, because that payload's raw keys are nested dictionaries your MDM abstracts into simple fields. If your editor is not allowing you to deploy the profiles as specified, use the .mobileconfig files included in Configuration profiles. Some MDMs, including Jamf, require these profiles to be signed, otherwise, they are mangled by the editor and cannot be deployed properly.
Two things to know before you choose:
- The Transparent Proxy is one profile native editors often model poorly. Uploading its profile template as a custom profile is the reliable path; for example, in Intune it is required. See MDM-specific notes for per-tool detail.
- Keep them separate, or combine them. Deploy the profiles individually for separation of concerns, or use the single combined all-in-one profile if you would rather manage one, but never both at once (see Configuration profiles). The all-in-one includes the update-settings payload, so deploying it as-is locks automatic update checks off and users cannot toggle them; remove that payload if you want users to control updates. The per-user identity profile stays separate either way, because it deploys on a different channel.
Each profile's section below starts with its macOS payload type (for example, com.apple.system-extension-policy). That is the Apple-defined payload the profile carries; the template already sets it, and your MDM profile editors should select it for you when you pick the matching payload (System Extensions, VPN, and so on).
Configuration profiles
CloudZero publishes the deployment profiles as downloadable .mobileconfig files. You may use them as-is, or as a reference when building payloads by hand. If you prefer a single upload, the combined file bundles every org-wide profile. The identity profile is per-user and still must be deployed separately.
Deploy either the combined profile, or individual profiles, not both. The all-in-one and the individual profiles carry the same inner payload identifiers, so installing both delivers every payload twice. macOS then registers duplicate, conflicting configurations (most visibly two transparent-proxy providers and ambiguous managed-preference values), and the deployment does not work reliably.
Replace the placeholder values before deploying. Two profiles carry placeholders you must set to your own. The config profile (
cloudzero-config) holds the ingest API key (CloudZeroIngestApiKey); deployed with the placeholder key, it sends telemetry under an invalid key, and that data does not appear in CloudZero. The identity profile (cloudzero-identity) carries a user-name token placeholder (REPLACE-WITH-YOUR-MDM-USER-NAME-TOKEN) to replace with your MDM's identity token, and optionally a department (CloudZeroDepartment); deployed unchanged, it sets every user's name to the literal placeholder string.
| Profile | File |
|---|---|
| System Extension Policy (steady-state, non-removable) | cloudzero-system-extension-policy.mobileconfig |
| System Extension Policy (removable, pre-uninstall) | cloudzero-system-extension-policy-removable.mobileconfig |
| Transparent Proxy | cloudzero-transparent-proxy.mobileconfig |
| Managed Login Items | cloudzero-login-items.mobileconfig |
| Managed preferences (API key) | cloudzero-config.mobileconfig |
| Update settings (optional) | cloudzero-updates.mobileconfig |
| Identity (per-user, optional) | cloudzero-identity.mobileconfig |
| All profiles combined | cloudzero-all-in-one.mobileconfig |
Signed configuration profiles
| Profile | File |
|---|---|
| Signed System Extension Policy (steady-state, non-removable) | cloudzero-system-extension-policy-signed.mobileconfig |
| Signed System Extension Policy (removable, pre-uninstall) | cloudzero-system-extension-policy-removable-signed.mobileconfig |
| Signed Transparent Proxy | cloudzero-transparent-proxy-signed.mobileconfig |
| Signed Managed Login Items | cloudzero-login-items-signed.mobileconfig |
System Extension Policy
com.apple.system-extension-policy clears the load step for the CloudZero network extension, so it installs and runs without the System Settings approval prompt. In its steady-state form it also locks the extension on, so the user cannot disable or remove it.
The profile comes in two forms that differ only in the removability key:
- Steady-state (non-removable) is what a normal managed deployment should use. It uses
NonRemovableSystemExtensions, which locks both the Network Extension toggle under General > Login Items & Extensions and the transparent-proxy toggle under Network > Filters & Proxies. - Removable (pre-uninstall) uses
RemovableSystemExtensionsand lifts the lock so the extension can be torn down. Push it only immediately before an uninstall, then pull it afterward; see Uninstall.
The settings below are the steady-state (non-removable) variant. The removable variant is identical except that the extension is listed under Removable system extensions instead:
| Setting | Value |
|---|---|
| Team identifier | SHVGZ9V9KP |
| Allowed system extension | com.cloudzero.Proxy.network-extension |
| Allowed system extension type | NetworkExtension |
| Non-removable system extension | com.cloudzero.Proxy.network-extension |
The lock requires macOS 15 or later. On macOS 14 the
NonRemovableSystemExtensionskey is ignored: the extension still installs and loads silently, but the user can disable or remove it from System Settings. Everything else the profile does works on macOS 14. A Mac that had the profile installed on macOS 14 does not begin enforcing the lock when it upgrades to macOS 15; re-push the profile after the upgrade, or the lock stays off silently.
Without it: the user is prompted to approve the network extension, and it stays in [activated waiting for user] until they do. The approval is under General > Login Items & Extensions on macOS 15 and later, and under System Settings > Privacy & Security on macOS 14.
Verify: systemextensionsctl list reports the extension as [activated enabled].
Transparent Proxy
com.apple.vpn.managed activates the network extension as a transparent proxy, suppressing the proxy/filter-approval prompt.
Most MDM VPN editors do not expose the
ProviderDesignatedRequirementfield this payload needs (Intune has no field for it at all), so building it natively usually fails. Uploading the transparent proxy as a custom profile is the reliable path. Some MDM solutions such as Jamf also require a signed profile. See Configuration profiles and MDM solution-specific notes.
The payload has two top-level keys plus a TransparentProxy dictionary that holds the provider settings:
| Key | Where | Value |
|---|---|---|
VPNType | top level | TransparentProxy |
VPNSubType | top level | com.cloudzero.Proxy |
ProviderBundleIdentifier | inside TransparentProxy | com.cloudzero.Proxy.network-extension |
ProviderDesignatedRequirement | inside TransparentProxy | the code-signing requirement that follows |
AuthenticationMethod | inside TransparentProxy | Password |
The com.apple.vpn.managed payload looks like this:
VPNType = TransparentProxy
VPNSubType = com.cloudzero.Proxy
TransparentProxy = {
ProviderBundleIdentifier = com.cloudzero.Proxy.network-extension
ProviderDesignatedRequirement = <the requirement string that follows>
AuthenticationMethod = Password
}
ProviderDesignatedRequirementis a code-signing requirement string that binds the proxy to CloudZero's signed extension (bundlecom.cloudzero.Proxy.network-extension, Team IDSHVGZ9V9KP). If you upload the profile template you do not enter this by hand; it is already included. Enter it only when you build the payload manually:
identifier "com.cloudzero.Proxy.network-extension" and anchor apple generic
and certificate 1[field.1.2.840.113635.100.6.2.6]
and certificate leaf[field.1.2.840.113635.100.6.1.13]
and certificate leaf[subject.OU] = "SHVGZ9V9KP"
VPNType = TransparentProxytells macOS this payload sets up a transparent proxy, not a VPN. While it uses the VPN payload type, no VPN tunnel is created.AuthenticationMethod = Passwordis required for the profile to install. Without it inside theTransparentProxydictionary, macOS refuses the profile with-319 "The VPN service could not be created", even over a managed MDM channel, so the payload installs nowhere.
Without it: the extension may be approved, but only manually by the user, and it will not adhere to the managed configuration, so a user could disable the proxy in system settings.
Managed Login Items
com.apple.servicemanagement approves the background agent so the application will run in the background, including on startup/login.
Each entry in the Rules array uses these keys:
RuleType | RuleValue | TeamIdentifier |
|---|---|---|
BundleIdentifier | com.cloudzero.Proxy | SHVGZ9V9KP |
Label | com.cloudzero.Proxy.agent | — |
Without it: users receive recurring login-item notifications. The agent still runs.
Certificate trust
This step is not silent, and no configuration profile can pre-approve it. Trusting the per-user CA raises a one-time macOS keychain authorization prompt (login password or Touch ID) that the user must accept.
The local monitor terminates TLS for AI-provider domains, so its CA must be trusted in each user's login keychain. The CA is generated per user, created at install. From version 0.2.7 of the collector and onward, if the user is not present to approve the certificate trust record at install time, they will be prompted in the menu-bar app to complete this step. Its private key and trust settings live in that user's login keychain, so local admin privileges are not needed for the user to complete this prompt.
Managed preferences
Like the deployment profiles, managed preferences are delivered as a configuration profile and must be present before the installer so the values are available at first launch. You may want to deploy them as a separate profile from the approval profiles: the approval profiles are fixed and deployed as-is, while these carry your org's own values. The identity fields (CloudZeroUserName and CloudZeroDepartment) are per-user and should only be distributed in the same profile as org-wide values if they can be filled in by variables provided by your MDM solution.
All keys live under the com.cloudzero.Proxy preference domain (the app bundle ID).
Push these keys via your MDM's custom App & Custom Settings payload on the com.cloudzero.Proxy domain, using variable substitution for per-user values (for example, Jamf $EMAIL).
| Key | Type | Purpose |
|---|---|---|
CloudZeroUserName | String | User identity for cost attribution (work email or display name) |
CloudZeroDepartment | String | Department or team for attribution |
CloudZeroIngestApiKey | String | CloudZero ingest API key (generated in the CloudZero platform) |
Each key is independent and optional. You can push only CloudZeroIngestApiKey, or add CloudZeroUserName and CloudZeroDepartment in any combination; any key you omit is left for the user to set in the app.
Per-user identity values. Fill CloudZeroUserName per user with your MDM's own identity token (Intune {USERPRINCIPALNAME}, Jamf $EMAIL). Only the MDM that owns the token resolves it to a real value; the cloudzero-identity template includes a generic placeholder (REPLACE-WITH-YOUR-MDM-USER-NAME-TOKEN) rather than any one MDM's token, so substitute your own before deploying. Installing the template verbatim, or on an MDM whose token you have not substituted, delivers the literal placeholder string as every user's name. See MDM solution-specific notes for the per-tool tokens.
Update behavior. Updates can be MDM-driven (see Upgrade); these keys control the in-app updater if you choose to use it.
| Key | Type | Purpose |
|---|---|---|
SUEnableAutomaticChecks | Bool | Enable or disable in-app update checks (default false) |
SUScheduledCheckInterval | Integer | Seconds between update checks (default 86400, once per day) |
The Updates pane is visible to users by default. If you do not manage SUEnableAutomaticChecks, each user can turn automatic checks on or off in Settings. Including the cloudzero-updates profile (or the all-in-one, which contains it) locks the setting: the in-app toggle is fixed to your value and users cannot change it. This controls the automatic background checks only; users can still check for updates manually.
MDM solution-specific notes
The profiles and keys in this guide are MDM-agnostic. The following notes cover some of the differences that matter in specific tools. They are not full walkthroughs, and CloudZero will expand these over time.
Jamf Pro
- Building profiles: for profiles that can be created in the editor, create a Configuration Profile, add the relevant payload, then scope it to devices with a Smart Group.
- Transparent Proxy and System Extension profiles: upload the signed versions, and do not open it in the VPN editor. The transparent proxy cannot be built or edited in the Jamf GUI at all, so the only way to deploy it is to upload the signed profile as a custom profile:
- Create a new configuration profile and choose Upload (not "configure manually").
- Upload the signed profiles.
- When Jamf prompts you to remove or keep the signature, keep it.
- Do not open the VPN payload. Set scope through targets and limitations only, then save.
- Managed preferences: deliver these through Application & Custom Settings; use Jamf variable substitution for per-user values, for example
$EMAILforCloudZeroUserName.
Microsoft Intune
- Building profiles: use the Settings catalog, Microsoft's recommended approach for new macOS policies. (A few payloads also have dedicated Templates, such as Extensions for the system extension, but the Settings catalog covers the rest.)
- Transparent Proxy: upload as a Custom configuration profile (Devices > Manage devices > Configuration > Create > New policy, then choose macOS and Templates > Custom). Intune's built-in VPN template does not model the provider dictionary or designated requirement, so there is no native path. You choose a deployment channel on a custom profile and cannot change it after saving; use the Device channel for this profile.
- User identity: set
CloudZeroUserNameto the{USERPRINCIPALNAME}token, and assign that profile to a user group so it deploys on the User channel and the token resolves per person. - Department: Intune has no built-in token for department, so there is no automatic per-user fill. Set
CloudZeroDepartmentas a static value on a per-group profile, or leave it for users to set in the app. If you need it populated per user, you would generate per-group profiles yourself.
Proxy ordering and coexistence
The collector intercepts AI-provider HTTPS via a transparent network extension that relays matched flows to a local monitor on 127.0.0.1:9090. Non-AI traffic passes through untouched.
Fail-open: if the local monitor is unhealthy, the extension stops claiming flows and all traffic passes through normally: no telemetry, no blocking.
Ordering ahead of another transparent proxy
macOS allows multiple transparent proxies on one device, but only one handles each network flow, and they are offered flows in installation order; the first-installed proxy wins. On a Mac that also runs an enterprise transparent proxy (Zscaler, Netskope, and similar), whichever was installed first claims AI-provider traffic. If that's the other proxy, CloudZero never sees those flows and captures no telemetry, while still appearing healthy.
The only lever to change this is the MDM Order key, and it works only when the MDM installs both proxies:
- Where you control provisioning, install CloudZero before the other proxy; first-installed wins and no ordering key is needed.
- Where the other proxy is already MDM-provisioned, use the following
Orderkey to put CloudZero first.
Both proxies must be MDM-installed.
Orderreorders transparent proxies only when the MDM installs both of them. If either extension was activated locally (outside MDM),Orderhas no reliable effect. macOS also refuses a manually installedcom.apple.vpn.managedtransparent-proxy payload ("The VPN service could not be created"), so the proxies and theirOrdermust come from the MDM, not a hand-dropped profile.
Add an Order key to the TransparentProxy dictionary of the Transparent Proxy payload (it is not a separate profile):
| Key | Where | Value |
|---|---|---|
Order | inside TransparentProxy | positive integer; set lower than the competing proxy (see the following guidance) |
Order is Apple's key, not CloudZero's; see Apple's com.apple.vpn.managed payload schema. It is available in macOS 14 and later, below the collector's supported floor.
Set low, then verify
Apple documents Order only as "a positive integer." It does not state whether a lower or higher value is evaluated first, and there is no command to read back the effective order. So:
- Set CloudZero's
Orderto1, lower than the competing proxy. (0is likely rejected; the schema requires a positive integer.) - Deploy both proxies via MDM, then verify with the following cert-probe.
- If CloudZero is still pre-empted, flip the direction (raise CloudZero's value higher than the other proxy's) and re-test.
Order is relative, so the outcome depends on the competing proxy's value too; that value lives in its MDM profile, which you configure separately. If the other tool sets no Order, or one that conflicts, set the Order key in that tool's payload as well so the two values are unambiguous (for example, CloudZero 1, the other proxy 2).
Verifying it took effect
Apple provides no command for this, so confirm by inspecting who signed the TLS leaf. From the managed Mac, after the profiles deploy:
echo | openssl s_client -connect api.anthropic.com:443 -servername api.anthropic.com 2>/dev/null \
| openssl x509 -noout -issuerissuer= /O=CloudZero/CN=CloudZero Proxy CA→ CloudZero is first. Ordering worked.- The other proxy's CA → CloudZero is still pre-empted. Flip the
Orderdirection and re-test. - A public CA → neither proxy is handling that domain (for example, TLS inspection is bypassed for it).
Effect on your security posture
Ordering CloudZero first does not let AI traffic bypass the enterprise proxy. CloudZero claims the AI flow, and the local monitor re-originates the request upstream; that upstream hop still traverses your proxy, which inspects egress exactly as before. The monitor trusts your proxy's CA automatically (it validates against the system trust store, where your MDM already installs that CA), so no extra trust setup is needed.
One caveat: source-app attribution. Because the monitor re-originates the request, your proxy sees these AI flows as coming from CloudZero's monitor (signed cz-monitor) rather than from the calling application. The traffic inspected is the same, but if your egress policy makes decisions by source application (per-app allow/block or logging), those rules will evaluate AI traffic as CloudZero, not the original app. Review any such policy before ordering CloudZero first.
Install
CloudZero ships as a signed, notarized .pkg (Developer ID, Team ID SHVGZ9V9KP).
Download (stable channel): https://desktop.cloudzero.com/latest/desktop-agent/macos/CloudZero.pkg
Verify the signature before deploying, and confirm the Team ID:
pkgutil --check-signature CloudZero.pkg # expect Developer ID, Team ID SHVGZ9V9KPInstall (any MDM, or manually):
sudo installer -pkg CloudZero.pkg -target /The postinstall runs as root and delegates user-context steps to the console user via launchctl asuser. It:
- installs the LaunchAgent at
/Library/LaunchAgents/com.cloudzero.Proxy.agent.plist - generates and trusts the per-user CA (
--register-certificate); see Certificate trust - activates the network extension (
--activate-ne) - bootstraps the agent for the console user
It is fail-open; it exits 0 even if a step fails, and the app retries on first launch. Log: /var/log/cloudzero-postinstall.log.
Verify the deployment:
systemextensionsctl list # extension shows [activated enabled]
pgrep -x CloudZero # app running
pgrep -f cz-monitor # local monitor runningFor the end-user first-launch flow, see What to expect.
Uninstall
Uninstalling removes the app, the LaunchAgent, the per-user CA and its keychain items, and the local app data. How you drive it depends on whether you are clearing a single machine or a managed fleet.
Single machine
Run the built-in uninstall wizard:
open -n /Applications/CloudZero.app --args --uninstallIt walks the user through the teardown with GUI prompts for the steps that need them.
Silent uninstall for managed fleets
For MDM-driven removal, call the uninstaller binary directly:
/Applications/CloudZero.app/Contents/MacOS/CloudZero --uninstall --silent [--force]Run it as root. The binary re-execs its own per-user phase and does not need to be launched as the user.
The uninstaller runs in two phases:
- Per-user phase (runs first): clears the login-keychain items,
~/Librarydata, and~/.claude. These are reachable only as the logged-in user. - Root phase: removes the app itself, the LaunchAgent, and the system-level artifacts.
If the per-user phase cannot run or fails, the root phase is held back by default, so per-user data is not orphaned with no app left to clean it up. --force overrides that hold-back and lets the root phase run regardless.
Exit codes
You can branch your MDM script on the exit code indicating the result of the attempted uninstall:
| Code | Meaning |
|---|---|
0 | Everything was removed. |
1 | A step failed, or the run stopped safely before doing anything destructive. |
2 | No user was logged in and nothing was removed; retry at next login. |
Exit code 1 covers multiple conditions such as "a step failed" or "stopped safely before touching anything." To distinguish them, read the stderr lines: each step emits exactly one, either [ok], [skipped: …], or [FAILED: …]. Do not have scripts treat 1 as "broken, force it."
Choosing the invocation. Both forms are safe to run; they differ in what happens when no user is logged in:
- Plain
--uninstall --silentnever leaves a machine half-removed. With a user logged in it removes everything (exit0); with no user it removes nothing and exits2, so it can be retried at next login. --forcelets removal proceed with no user logged in. The root phase runs and deletes the app, but the per-user artifacts are left behind, and once the app is gone the uninstaller cannot be re-run to clean them up. The app may be reinstalled to remove this data.
There is one item that a silent uninstall does leave behind: after a fully successful logged-in run, the residue is the login-keychain trust designation. Clearing it needs a GUI authorization prompt that cannot run headless, so it stays behind, pointing at a certificate that no longer exists. The certificates themselves are removed, the only thing that remains is the trust record, this should be inert.
With no user logged in and --force, all eleven per-user steps are skipped, so everything per-user is orphaned. Use caution if using the --force option.
Uninstall ordering
The steady-state System Extension Policy profile uses NonRemovableSystemExtensions, which forbids removing the extension, and forbids it persistently across reboot, so the uninstaller cannot tear the extension down while that profile is in force. Swap in the removable variant first:
- Push the removable System Extension Policy profile.
- Run the silent uninstall and branch on its exit code.
- Once the uninstall reports a clean exit
0, pull the remaining CloudZero profiles to finish cleanup.
Never run the uninstall until the swap has landed, so the extension can be torn down. You can pull the profiles at any time; sequencing them after a clean exit 0 just confirms the removal finished first. If you used --force and the app was removed before the per-user cleanup completed, you can still pull the profiles, but the app is no longer present to finish that cleanup; reinstall and uninstall again with a user logged in to complete it.
An MDM-managed transparent-proxy configuration is preserved by design. The uninstaller removes only a proxy configuration the app created for itself; a configuration delivered by the Transparent Proxy profile survives every uninstall and only is deactivated and removed when you pull that profile. A leftover managed proxy entry after uninstall is expected, not a failed removal.
Upgrade
The in-app automatic update checks default to disabled (SUEnableAutomaticChecks=false), so the fleet updates on your schedule. If you enable automatic checks (for example, with the cloudzero-updates managed-preferences profile), each user is prompted to install when a new version is released; leave it disabled to update the fleet by pushing the .pkg yourself.
-
Upgrade = push the newer
.pkgthe same way as the initial install. For version detection, the distribution service publishes a one-linehttps://desktop.cloudzero.com/latest/desktop-agent/macos/version.txt(the app version, matchingCFBundleShortVersionString) next to the constant stable-pkg URL, intended for Installomator and MDM fleet tooling. -
Rolling your own update flow? Whether you use Installomator, another patch tool, or a custom script, point it at the constant package URL and read the current version from
version.txt. Compareversion.txtagainst the installedCFBundleShortVersionStringto decide when to push. The two stable URLs arehttps://desktop.cloudzero.com/latest/desktop-agent/macos/CloudZero.pkgandhttps://desktop.cloudzero.com/latest/desktop-agent/macos/version.txt. -
Downgrade or rollback: macOS will not install an older
.pkgover a newer installed app. To roll back, remove/Applications/CloudZero.appfirst, then install the older.pkg. -
Sample Installomator label, a custom label that always tracks the latest stable build (constant download URL; version from
version.txt):cloudzero) name="CloudZero" type="pkg" downloadURL="https://desktop.cloudzero.com/latest/desktop-agent/macos/CloudZero.pkg" appNewVersion=$(curl -fsL "https://desktop.cloudzero.com/latest/desktop-agent/macos/version.txt") expectedTeamID="SHVGZ9V9KP" blockingProcesses=( CloudZero ) ;;
Have questions or feedback? Reach out to your account manager.
Updated about 12 hours ago

