ProxonProxon
Open Proxon
Documentation

Managed deployment on macOS

Push the macOS observer to a fleet through your MDM or RMM, with Jamf, Kandji, Intune, JumpCloud, and NinjaOne walkthroughs.

Push the macOS observer to a fleet through your MDM or RMM. You push one .pkg and two configuration profiles, and each Mac joins this organization. Employees do not sign in, and there is no per-machine key to manage. Every Mac needs macOS 15 (Sequoia) or later.

Step 1: Turn on IT-managed distribution

Open Org Settings, then Data Collection, and choose IT-managed distribution. Onboarding asks the same question, so this is already set if you chose it there.

Step 2: Generate an enrollment token

Open Org Settings, then Devices, and choose Generate in the Enrollment tokens block. One token covers the whole fleet.

The token is shown once. Do not close that dialog until you have finished the next step.

Step 3: Download the configuration profile

In the same dialog, choose Download profile and pick your console from the menu. The menu groups the consoles by what each one can do with a per-device variable, so picking your console is the download. You get proxon.mobileconfig, finished, with no placeholder to substitute and nothing to fill in. If you are not sure which group your console is in, see Which path you are on.

Step 4: Download the certificate profile

Open Org Settings, then Devices, and choose Download profile in the Certificate trust block. You get proxon-ca-trust-workspace.mobileconfig. Push it through your MDM scoped to every Mac, alongside proxon.mobileconfig.

The first download also turns on Proxon-signed certificates for your organization. It needs permission to edit organization settings. Until you download it, managed Macs ask each employee for a password to trust Proxon's certificate. See Traffic-inspection certificate trust.

If the download says your organization's signing key is being prepared, Proxon is still creating it. This usually takes a few minutes and can take up to an hour. Try the download again later. If it says Proxon-signed certificates aren't available and to contact Proxon support, retrying will not help, so contact support.

Step 5: Download the installer

Take Proxon-<version>.pkg from the tile below. You can also download from Org Settings, Data Collection.

Which path you are on

One question decides everything that follows: can your MDM substitute a per-device variable into a custom profile?

That is what lets a single profile attribute each Mac to the person using it. Jamf Pro and Kandji expand $EMAIL; Intune expands {{userprincipalname}}. JumpCloud and RMM-first tools like NinjaOne do not expand anything.

Your tool Path What carries the enrollment token
Jamf Pro, Kandji Substituting MDM The profile
Intune Substituting MDM The profile
JumpCloud, NinjaOne, any RMM No substitution A file your script writes

Substituting MDM

The profile you downloaded already carries the token and the right variable. Upload it as-is. Push it with the certificate profile and the .pkg, and you are done.

  1. Upload the .pkg to your distribution point under Settings, Computer Management, Packages, then create a policy with a Packages payload that installs it, scoped to your Mac smart group.
  2. Go to Computers, Configuration Profiles, New, Upload, and select proxon.mobileconfig. Jamf reads every payload from the file, so you do not rebuild them in the Jamf UI.
  3. Jamf expands $EMAIL from the assigned user's record. A Mac with no assigned user in Jamf gets an empty value and falls through to the directory record.

Scope the profile to land before or with the package. The app reads managed configuration at first launch, so a profile that arrives later still works on the next launch, but that first launch will have shown the employee the ordinary onboarding screen.

Deploying to a Mac that is already running Proxon converts it. The Mac notices your configuration the first time it sees it, re-enrolls against the token in it, and is filed under IT from then on. Nobody signs out, and nobody touches the machine. This is the case if you rolled out self-serve first and are adding management later.

The same holds for a correction. Push a profile with a fixed token or a fixed address and the fleet picks it up within minutes, with nothing asked of the people using the Macs.

A Mac that already has an owner keeps that owner when the new profile does not supply a usable one. Proxon changes the owner only when your profile resolves to a person; a profile that supplies nothing usable leaves the existing attribution alone and records what it sent instead, so you can see the mistake without anyone losing their attribution. See Owner attribution.

No substitution

The profile you downloaded for this path carries no enrollment token and no email address, because your tool cannot fill either one in per device. Both instead ride in a file your script writes to every Mac.

You can put both in that one file, and you can also split them. Proxon resolves each value on its own: the token comes from the profile when the profile carries one, because that is the copy macOS itself vouches for; the address comes from whichever source is closest to the individual Mac, which means enrollment.json wins over a profile.

That split is the useful shape on this path. Keep the token in the profile, where it is delivered and attested by your MDM once for the whole fleet, and let your script write only the per-device address into the file.

On this path the address is required, not optional. Proxon's only other source is the local directory record, and tools that manage plain local accounts never populate it, JumpCloud included. Omitting the address there does not fall back to anything: every Mac enrolls unattributed, silently. Check one Mac with dscl . -read /Users/$(stat -f%Su /dev/console) EMailAddress before you rely on that fallback anywhere.

Push both profiles and the .pkg as usual, then have your tool run a script that writes /Library/Application Support/Proxon/enrollment.json as root:wheel, mode 0644:

bash
#!/bin/bash
set -euo pipefail

install -d -o root -g wheel -m 755 "/Library/Application Support/Proxon"

# Write a temporary file next to the real one, then move it into place.
tmp="$(mktemp "/Library/Application Support/Proxon/.enrollment.json.XXXXXX")"
# If anything below fails, do not leave the temporary copy (it holds the token) behind.
trap 'rm -f "$tmp"' EXIT
cat > "$tmp" <<'JSON'
{
  "enrollment_token": "prx_ent_ab12_REPLACEME",
  "user_email": "ada@acme.example"
}
JSON

chown root:wheel "$tmp"
chmod 644        "$tmp"
mv -f "$tmp" "/Library/Application Support/Proxon/enrollment.json"

Write the file this way, to a temporary file and then mv, rather than straight into enrollment.json. A running Proxon app re-reads the file, and a file it reads halfway through being written looks damaged. A damaged enrollment.json does not fall back to the employee connecting by hand: Proxon stays managed and holds enrollment until the file is fixed.

The token is the same for every Mac. The address is not, so pull it from whatever per-device source your tool has, and keep the token itself in a secret variable rather than in the script body.

Run the script before Proxon first launches. A Mac that has already enrolled will not redo it.

Upload the profile unsigned. JumpCloud signs custom profiles itself and rewrites their identifiers on the way through, and it does no per-device templating either way, signed or not.

JumpCloud does not write an email address into the local directory record, so Proxon cannot fall back to reading one. Your script has to supply it.

Each Mac's JumpCloud agent keeps a systemKey in /opt/jc/jcagent.conf that identifies the device. Read it locally, ask the JumpCloud API which user is bound to that device, and use that user's email field. Matching on the JumpCloud username rather than the local account name means non-standard usernames still resolve correctly.

Gate the Proxon deployment on a device group that only contains Macs where the file is already in place, rather than deploying on a schedule.

If your Macs have no Apple MDM at all, each employee also approves the system extension and the privacy permissions once. Proxon's inspection certificate also arrives as a profile, so without an MDM an administrator has to install it on each Mac by hand. See Traffic-inspection certificate trust. Enrollment and attribution are the parts a script can still automate.

What the profile pre-approves

Each payload removes one approval dialog the employee would otherwise face:

  • System extension. Allow-lists Proxon's network-capture extension by Team ID (4JDW2S2CK4) and bundle id, so it loads without the System Extension Blocked prompt.
  • Privacy permissions. Pre-grants Accessibility, to read the foreground window's title, and Calendar, to count meetings in progress. Counts only, never titles or attendees.
  • Browser extension. Force-installs the Proxon extension on managed Chrome, Edge, and Firefox. Safari is separate, and is covered under Browsers.
  • Managed settings. The enrollment token and the per-device address, on the substituting path only. This is also the payload that carries the optional release-channel key, covered under Release channels.
Why a profile rather than a preference file

macOS marks values delivered by a configuration profile as forced, and Proxon checks that flag key by key, ignoring anything unforced.

Without it, any process running as the employee could write a user_email into the same preference domain and quietly attribute the Mac to a colleague.

Why the enrollment file is world-readable

Root writes enrollment.json, but the Proxon app that reads it runs as the employee, so a root-owned 0600 file would be unreadable by the only process that needs it.

The token inside is a shared organization-wide secret, bounded by use count, rate-limited, and revocable from the Enrollment tokens block. It is not a per-user credential. The per-device credential it mints lives in the macOS Keychain, not in this file.

Traffic-inspection certificate trust

Proxon inspects AI-provider traffic locally, which needs a certificate the Mac trusts. Your organization has one inspection certificate, and it reaches every Mac through your MDM. Once you have pushed its profile, no employee is asked for a password.

Download its profile from Org Settings, Devices, in the Certificate trust block, and push it through your MDM scoped to every Mac. The Profile ID shown next to the button is the identifier to look for in your MDM. JumpCloud and other MDMs that rewrite identifiers show a different one, so look for the profile by its name there. The first download also turns this certificate on for your organization.

The certificate is signed by a key that belongs to your organization alone. The key is kept in AWS Key Management Service (KMS), so its private part never leaves AWS's hardware and nobody at Proxon can read or copy it.

If you download the profile again, you get the certificate Proxon is using now. Downloading it again is also how you repair a certificate that has stopped working. When Devices shows Macs waiting for a signed certificate for longer than an hour, download the profile again and push the new one through your MDM.

Proxon then gives each Mac a short-lived certificate, valid for one hour and only for the AI providers Proxon inspects. The Mac replaces it halfway through its life, so at least every 30 minutes. On a Mac with a Secure Enclave, its private key is created inside the Enclave and never leaves it.

Until the profile reaches a Mac, Proxon does not inspect that Mac's AI traffic, and Devices shows it as Waiting for your MDM. Traffic is never blocked. A Mac that cannot reach Proxon for an hour also stops inspecting until it reconnects, and Devices shows it as Waiting for a signed certificate.

The Members page in Org Settings shows the same thing for each person. A Mac that is enrolled and sending data, but cannot inspect encrypted traffic because its certificate is not trusted, shows its Network Observer badge in orange with the words Encrypted content not inspected. Hover the badge to see why. The reason is one of these:

  • The certificate is not trusted yet, and the Mac is waiting on the employee or on your MDM profile.
  • macOS refused to trust the certificate. The error number macOS returned is shown with it.
  • The certificate changed, and the Mac is waiting for your MDM profile to replace it.
  • A certificate Proxon did not create is trusted in place of this Mac's own.
  • The Mac is waiting for a signed certificate from Proxon.

Hovering the Certificate trust badge in Org Settings, Devices shows the same reason. The orange badge clears on its own once the Mac reports a trusted certificate. If the Mac stops reporting for two hours, the badge goes back to the Mac's ordinary state.

Signing

You do not need a signed profile, and on the substituting path you should not want one. A profile delivered over MDM is trusted because the MDM channel is trusted, and some tools sign it themselves on upload.

A signature freezes the contents. Anything meant to be filled in per device has to be concrete before signing, so a signed profile and a per-device variable are mutually exclusive: sign one containing $EMAIL and every Mac receives that literal string.

Proxon refuses an address that is still an unexpanded variable rather than attributing anyone to it, and each affected Mac says so on its row in Org Settings, Devices. So the mistake is visible and correctable centrally instead of silent — but those Macs are unattributed until you push a profile that carries a real address, or set each one's owner by hand (see Owner attribution).

Signing earns its place in two cases. If you install the profile by hand on each Mac rather than through an MDM, macOS flags an unsigned one as Unverified. And your change control may require a signed artifact for its records.

If either applies, email support@proxon.ai. We sign after your token is in place, so there is no generic pre-signed profile we can publish, and the file we return carries no per-device variable.

Owner attribution

Proxon resolves the owner of each Mac in this order, stopping at the first hit:

  1. The address from managed configuration, whether that came from the profile or from enrollment.json. This always wins.
  2. The console user's directory record, meaning the logged-in user's email from Open Directory, including the local node and any directory the Mac is bound to, such as Platform SSO.
  3. Unattributed, if neither produces a plausible email address.

A bare short username like ada is never promoted to an address, since attributing a Mac to the wrong person is worse than leaving it unassigned. To give an unattributed Mac an owner, or to correct one, push the right address in the profile or enrollment.json. The Mac re-enrolls under it within minutes, with nothing to re-install (see Substituting MDM).

An organisation owner or admin can also set the owner by hand. In Org Settings, open Devices, find the Mac under Enrolled devices, open the menu on its row, and choose Set owner; Remove owner, on the same menu, clears one. This is one device at a time, and it does not correct the profile: the next enrollment that finds an address puts that address's person back as the owner. For more than a few Macs, fix the address in the profile instead.

Each macOS account on a Mac enrolls it at that account's first login, because Proxon keeps its credential per account. All of them land on the same device, and the account that enrolled most recently owns it, as long as Proxon found an address for it. An enrollment that finds no address leaves the existing owner in place. So when your configuration supplies the address, that person owns the Mac whoever logs in.

Not every management tool populates the local directory record. JumpCloud does not, so the second step produces nothing on a JumpCloud-managed Mac and every device lands unattributed unless your script supplies the address. Check with dscl . -read /Users/$(stat -f%Su /dev/console) EMailAddress on one Mac before relying on that fallback.

Macs nobody logs into

A managed Mac enrolls when someone logs into it. Installing the .pkg and the profiles is not enough on its own, unless someone is already logged in when it installs. Proxon starts when a person logs into a macOS account, and enrollment happens at that first start. A Mac that sits at the login window and that nobody ever logs into does not enroll, apart from the Setup Assistant case below. It captures nothing, sends nothing, and does not show up in Org Settings, Devices. Nothing warns you about it, because the Mac never contacts Proxon.

Proxon also captures and sends only while someone is logged in. Nothing is captured at the login window or after everyone logs out. With fast user switching, each logged-in account runs its own copy of Proxon, but only the account that enrolled most recently keeps sending. When another account on the same Mac enrolls, the first account's copy stops sending until it next starts.

This is how Proxon works on a Mac. These Macs are affected:

  • Kiosks, lab machines, and other Macs that sit at the login window with nobody logged in.
  • Macs you set up ahead of time, through Automated Device Enrollment or by hand, and leave until their owner arrives.
  • Shared or VDI-style images. Do not log into the image, or let it enroll, before you capture it: a copy of an enrolled image carries that enrollment with it. Copies that share one hardware identifier (IOPlatformUUID) also count as a single device in Proxon.

What to do:

  • For a Mac that will have an owner, nothing, as long as the enrollment token in your profile or enrollment.json still works when they arrive. Only a Mac's first enrollment counts against the token's use limit, so keep enough uses for every Mac you staged. Keep the token unexpired and unrevoked for as long as Macs may still enroll or enroll again: a new account logging in, an owner you correct by pushing an address, or a Mac you re-image all need it. Until the owner's first login the Mac is usually missing from Org Settings, Devices. If the package installed during Setup Assistant, it may instead be listed without an owner, unless your profile or enrollment.json supplies the address. Both are expected, and the owner's first login attributes it.
  • For a Mac nobody will log into, it is covered only while an account is logged in. On a kiosk or lab Mac, set macOS to log into its account automatically when it starts. macOS turns automatic login off while FileVault is on.
  • Check who it was attributed to. If your profile or enrollment.json supplies an address, that person owns the Mac, whoever logs in. If not, the account that enrolled most recently with a findable address owns it, which can be a technician's account until the real owner logs in. To correct an owner, push the right address. See Owner attribution.

A Windows PC nobody logs into still enrolls, under the computer's own name, after a 30-minute wait. The Enrollment\UserBindGraceMinutes setting only changes how long that wait is. The Mac has no equivalent setting, because a Mac nobody logs into does not enroll, apart from the Setup Assistant case above.

Browsers

The extension is the same on every browser. Only the way it gets switched on differs. If you push the profile, Chrome, Edge, and Firefox are done. Without a profile, the .pkg sets up Firefox only, because Chrome and Edge treat an extension policy as binding only when it arrives from a configuration profile, and no privileged script gets around that.

Safari

Safari extensions cannot be managed by a configuration profile at all. Apple handles them only through declarative device management, which needs macOS 15 or later, a supervised Mac, and an MDM that supports declarations.

Supervised means the Mac was enrolled through Apple Business Manager. Declaration support is the condition fleets most often fail, and it depends on your console rather than on the Mac. Jamf Pro delivers declarations through Blueprints on macOS 15 or later. Jamf Now and JumpCloud cannot deliver them at all, so a declaration uploaded to either one never reaches the Mac.

If your fleet meets all three, push this declaration after the .pkg, since the extension only becomes manageable once Proxon.app is on the Mac. Most MDMs present it as a form, and the values are what matter.

json
{
  "Type": "com.apple.configuration.safari.extensions.settings",
  "Identifier": "generate-a-uuid-here",
  "Payload": {
    "ManagedExtensions": {
      "com.proxon.observer.SafariWebExtension (4JDW2S2CK4)": {
        "State": "AlwaysOn"
      }
    }
  }
}

That identifier is the extension's bundle id followed by Proxon's Team ID, and Apple requires that exact spelling. AlwaysOn stops the employee turning it off; use Allowed to leave that to them.

If the fleet does not meet all three conditions, the employee ticks Proxon under Safari, Settings, Extensions, and the app links them straight to that pane.

Verify

On a target Mac, once the install and the profiles have both landed, run these in order.

Step 1: Profiles installed

Needs sudo. The profiles are device-scoped, so without it profiles lists only your own user's profiles and finds nothing.

bash
sudo profiles list -type configuration | grep -i proxon

Expect: a line with com.proxon.mdm.capture-stack and a line with com.proxon.ca-trust.workspace. If your MDM rewrites profile identifiers, as JumpCloud does, this can print nothing. Check System Settings, General, Device Management instead. Look for Proxon Capture Stack and Proxon Certificate Trust.

Step 2: Managed settings arrived

Needs sudo. This reads the forced copy of the settings, the only one Proxon honours. defaults read com.proxon.observer would show your own unforced values instead.

bash
sudo defaults read "/Library/Managed Preferences/com.proxon.observer"

Expect: your enrollment keys printed back.

Or, if you used an enrollment file instead of a profile:

bash
ls -l "/Library/Application Support/Proxon/enrollment.json"

Expect: -rw-r--r-- owned by root wheel.

Step 3: Certificate and helper in place

bash
security find-certificate -c "Proxon Inspection Root" /Library/Keychains/System.keychain
bash
launchctl print system/com.proxon.update-helper 2>&1 | head -5

Expect: a certificate whose name starts with Proxon Inspection Root and ends with your organization's name as it was when Proxon created your signing key (renaming the organization later does not change it), and a service block for the update helper rather than "Could not find service".

Step 4: Device enrolled

In Proxon. Launch the app once on the Mac, because enrollment happens at first launch, not during the install. Then open Org Settings, Devices, and find the Mac in the Enrolled devices list.

Expect: the owner is the person you expect, not Unattributed.

If the Mac shows no Connect option and never enrolls, run status as the employee who is logged in at the Mac, not as root. Proxon keeps the failure in that person's account, so a run as root does not show it. Someone must be logged in at the Mac; at the login window the script stops with "no one is logged in" rather than running as root. From an MDM script, which runs as root:

bash
user="$(stat -f%Su /dev/console)"
[ "$user" != root ] || { echo "no one is logged in" >&2; exit 1; }
launchctl asuser "$(id -u "$user")" sudo -H -u "$user" "/Applications/Proxon.app/Contents/MacOS/Proxon" status

In the JSON it prints, check enrollment.managed_enrollment.error_code. config_file_unusable means Proxon cannot use enrollment.json: the file is not valid JSON, it is not readable by the employee (it must be mode 0644), or it has no enrollment token and no Proxon configuration profile supplies one. If you keep the token in the profile, check the Proxon profile is installed on the Mac; the file is meant to have no token then. The message next to the code names the problem without showing the file's contents. Fix it and Proxon picks up the change within a minute, with no relaunch.

Updates

Proxon updates itself. The app checks hourly and installs each new signed release in the background, with nothing for the employee to click and nothing for you to repackage. To have employees choose when to install, or to pause updates for a maintenance window, see Controlling when updates install.

That holds for a managed rollout too. A Mac the .pkg landed on with nobody logged in updates exactly like one installed by hand, and so does a Mac whose owner is a standard user with no administrator rights. Nobody is asked for a password, and you do not push a new .pkg for each release.

What installs the update

The .pkg installs a background service that runs as root, com.proxon.update-helper. When the person using the Mac cannot write to /Applications, which is the ordinary case on a managed fleet, the app hands the install to that service rather than asking for an administrator password. Root performs the write, so it stops mattering who owns the app bundle or what rights the employee has.

The service does one thing, which is install the current signed Proxon release. It takes no other instruction, and it carries no enrollment token, no organization identifier, and no credential of yours. Before it installs anything, it checks the package three independent ways:

  • Proxon's own release signature over the bytes it downloaded. The key it checks against is built into the service rather than read from disk, so nothing on the Mac can swap in another one.
  • Gatekeeper's assessment of the package, the same check macOS runs on an installer someone opens by hand. It requires a Developer ID signature and Apple notarization.
  • Proxon's Apple Team ID (4JDW2S2CK4) in the package's signing chain. Gatekeeper on its own would accept a notarized package from any Apple developer, and this check is what narrows it to ours.

A package that fails any one of the three is discarded, and nothing is installed.

Updates are installed by the app while it runs, so a Mac has to be switched on and logged into to pick one up. The service installs updates. It does not wake a Mac nobody is using.

If a Mac can see a new release and cannot install it, Proxon says so against that device in the console, with the reason.

Release channels

Every Mac follows the production channel, where released versions are published, and you do not have to configure anything to get that. Set a channel only if you want a pilot group on pre-release builds.

The key is update_channel, in the com.proxon.observer domain, in the same com.apple.ManagedClient.preferences payload that already carries user_email. It takes exactly two values, both lowercase. production is the released channel, and develop is the pre-release one.

xml
<key>update_channel</key>
<string>develop</string>

The profile you download does not set the key, so an unedited profile leaves the whole fleet on production. Add it yourself for the group you want on pre-release builds, and leave it out everywhere else.

Proxon reads the key only when it arrives forced from a configuration profile. An employee can pick a channel for their own Mac in the app's Diagnostics window, and a forced value outranks that choice, which is the reason to set it centrally. Any other spelling is ignored and the Mac keeps the channel it already had, so a typo cannot move a fleet onto a channel nobody chose. Diagnostics shows the channel in effect and whether it came from your profile.

update_channel decides which releases a Mac receives. It is not a switch for updates themselves, and setting it never stops a Mac updating.

On the no-substitution path the profile you download carries no Proxon managed-settings payload. Put the key in a separate profile instead, as described in Update settings without a Proxon payload.

Controlling when updates install

Four more optional keys decide when a Mac installs an update. They go in the same com.proxon.observer domain and payload as update_channel, and they match the Windows Updates policies of the same names. The profile you download sets none of them, so an unedited profile keeps the default of installing each release as soon as it is found. If your downloaded profile has no such payload, which is the case on the no-substitution path, see Update settings without a Proxon payload.

Let employees choose when to install. Set ProxonUpdatesAutoApply to false. The Mac still checks for updates every hour and shows that one is available, but it never installs one by itself. The employee installs it by choosing Update Proxon in the Proxon menu. On a Mac installed from the .pkg, that install runs through the update service described above, so it works for a standard user with no administrator password.

xml
<key>ProxonUpdatesAutoApply</key>
<false/>

Pause updates for a maintenance window. Set ProxonUpdatesDeferralWindowStart and ProxonUpdatesDeferralWindowEnd. Inside the window the Mac does not check for updates and installs nothing, even when the employee chooses Update Proxon. When the window ends, updates resume on the next hourly check. Both keys take one of two forms, and both must use the same one:

  • A date and time in ISO 8601, such as 2026-12-18T17:00:00Z, for a one-off freeze. A time with no Z or offset is read as UTC.
  • A time of day in 24-hour form, such as 22:00, for a window that repeats every day in the Mac's own time zone. A start later than the end crosses midnight, so 22:00 to 06:00 covers the night. A 12-hour value such as 9:00PM is not read on a Mac, even though Windows accepts it.

A daily window must leave at least 61 minutes outside it each day. The Mac checks for updates once an hour, sometimes a few seconds late, and the employee's own check is paused inside the window too, so a shorter gap could fall between two checks every day and the Mac would never update. A daily window that leaves less than 61 minutes outside it, one longer than 22 hours 59 minutes, is treated as set up wrong and pauses nothing. Windows does not have this rule and would honor such a window as written.

xml
<key>ProxonUpdatesDeferralWindowStart</key>
<string>22:00</string>
<key>ProxonUpdatesDeferralWindowEnd</key>
<string>06:00</string>

A one-off window cannot pause updates for more than 90 days from its start, however late its end. ProxonUpdatesMaxDeferralDays, a whole number, shortens that limit. It applies only to a date-and-time window and does nothing on its own.

xml
<key>ProxonUpdatesMaxDeferralDays</key>
<integer>14</integer>

A window that is set up wrong never stops updates. If only one of the two keys is set, a value cannot be read, the two use different forms, the start is not before the end, or a daily window leaves less than 61 minutes outside it, the Mac updates as normal and writes the reason to its log.

Both settings apply from the moment the profile arrives, with one exception. An update that was already downloading, or already handed to the update service, when the profile or the window arrived can still finish installing, at the latest when Proxon next quits. Later updates wait as described.

Proxon reads these keys only when they arrive forced from a configuration profile, so an employee cannot change them. To see whether a Mac is holding an update and why, run this on it:

bash
"/Applications/Proxon.app/Contents/MacOS/Proxon" status

In the JSON it prints, update.held_reason reads deferral_window while the window is open, and auto_apply_disabled when an update has been found and is waiting for the employee. It is missing when nothing is held, including on a Mac that is already up to date.

ProxonUpdatesAutoApply and the window decide when a Mac installs an update. They do not change which releases it receives, which is update_channel.

Update settings without a Proxon payload

On the no-substitution path the profile you download carries no com.proxon.observer payload, so there is nowhere in it to put update_channel or the keys under Controlling when updates install. Push them in a second, separate configuration profile instead. JumpCloud, NinjaOne and most RMM tools can deploy a custom .mobileconfig.

Proxon reads each key on its own and does not care which profile it came from. Different keys from separate profiles combine. Do not set the same key in two profiles, because which value wins is not defined. Give the extra profile its own identifiers.

A key that does not reach the Mac changes nothing: the Mac stays on its channel and installs updates as normal. We have not yet confirmed this with a live push from an MDM, so check one Mac after the profile arrives. This lists the keys the Mac actually received:

bash
defaults read "/Library/Managed Preferences/com.proxon.observer"

For example, to have employees choose when to install:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
    <key>PayloadScope</key>
    <string>System</string>
    <key>PayloadIdentifier</key>
    <string>com.example.proxon.update-timing</string>
    <key>PayloadUUID</key>
    <string>REPLACE-WITH-A-NEW-UUID</string>
    <key>PayloadDisplayName</key>
    <string>Proxon update timing</string>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.apple.ManagedClient.preferences</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadIdentifier</key>
            <string>com.example.proxon.update-timing.settings</string>
            <key>PayloadUUID</key>
            <string>REPLACE-WITH-ANOTHER-NEW-UUID</string>
            <key>PayloadContent</key>
            <dict>
                <key>com.proxon.observer</key>
                <dict>
                    <key>Forced</key>
                    <array>
                        <dict>
                            <key>mcx_preference_settings</key>
                            <dict>
                                <key>ProxonUpdatesAutoApply</key>
                                <false/>
                            </dict>
                        </dict>
                    </array>
                </dict>
            </dict>
        </dict>
    </array>
</dict>
</plist>

Replace the two UUIDs with new ones, for example from uuidgen. Add update_channel or the window keys beside ProxonUpdatesAutoApply in the same mcx_preference_settings block if you want them.

Uninstall

Removing Proxon from a Mac takes root. On a managed Mac, Proxon refuses to uninstall when an ordinary user runs it, so employees cannot remove it themselves. Run the commands below through your MDM, which runs scripts as root.

Step 1: Remove the Proxon profiles

In your MDM, remove every Proxon configuration profile from the Mac. This withdraws the system extension approval, the traffic proxy configuration, the privacy permissions, and the trusted inspection certificate. When the system extension approval is withdrawn, macOS removes the system extension itself.

Do this first. While the profiles are installed, the script leaves the system extension in place and tells you to remove them.

Step 2: Run the uninstall script

Run this as root, for example as an MDM script. Run it while the Mac's employee is logged in at the Mac. The script needs them logged in to finish cleaning up their account.

bash
sudo "/Library/Application Support/Proxon/uninstall.sh"

This stops traffic capture, quits Proxon on every account where it is running, and removes the browser policy entries, the login agent, and Proxon's background services. It leaves Proxon.app in /Applications.

The script also cleans up every account on the Mac that has Proxon data. An account is fully cleaned if that person is logged in while the script runs, and that includes the Mac's device credential and enrollment, which the script reports as removed for that account or, if it could not reach that account's keychain, as not confirmed. Reinstalling Proxon then enrolls the Mac again, silently when your configuration profile is still in place. The Mac keeps nothing like the Windows observer's "already enrolled" marker, so there is no separate deprovision step on a Mac. For a person who is logged out, the script deletes only Proxon's data files. Their account keeps Proxon's certificate trust and device secret in their login keychain, along with that account's device credential, Proxon's background agents, and their Proxon settings. Run the script again while they are logged in to remove those.

The script runs Proxon's cleanup from its own copy of the app, which it checks first. If it cannot make that copy, or the copy fails Proxon's signature check, it cleans no account and says so. Reinstall the .pkg, then run the script again.

The script lists every account it skipped or only partly cleaned. When anything is left, it exits with an error.

Step 3: Delete the app and restart

Check the script's output. If it says the system extension is already removed, delete /Applications/Proxon.app and restart the Mac. The restart finishes removing the system extension.

If the script reports that the system extension was not removed, keep the app for now. This happens when the Proxon profiles are still installed. Remove them in your MDM, run the script again, then delete the app and restart.

Known limits

  • A Mac has one MDM of record. Proxon's profile has to come from whichever MDM already owns your Macs.
  • The .pkg cannot grant the system extension or the privacy permissions on its own. Only an MDM profile can, and without one, each employee approves those once.
  • Proxon's inspection certificate reaches a Mac only as a configuration profile. A Mac without it keeps working, but Proxon does not inspect its AI traffic until the profile arrives. See Traffic-inspection certificate trust.
  • Enrollment happens at the app's first launch, not during the install. A DEP or Setup Assistant install has no person logged in to attribute the Mac to, so the Mac either waits for the owner's first login or enrolls without an owner, unless your profile or enrollment.json supplies the address, until then. A Mac that nobody logs into does not enroll, and Proxon captures only while someone is logged in. See Macs nobody logs into.
  • Converting a Mac that is already running Proxon, and correcting a profile you have already pushed, both work fleet-wide and need nobody to touch a machine. A Mac that has never launched the app picks the change up at its next launch.
  • Apple is retiring the ability to grant Accessibility through a configuration profile. When that lands, this permission stops being pre-grantable and the managed install gains an employee prompt for it. Check Apple's current release notes for the version it affects before planning around it.
  • Attribution falls back to the local directory record, which some tools never populate. See the warning under Owner attribution.
  • Without a configuration profile, only Firefox can be set up automatically.
  • Firefox's policy does not survive a Firefox self-update, because Mozilla keeps it inside the Firefox app bundle. Re-running the .pkg restores it, and the profile avoids the problem entirely.
  • Proxon installs its own updates while the app is running, so a Mac that is switched off, or that nobody has logged into yet, stays on the build it has until somebody uses it. See Updates.
  • MDM consoles differ in how strictly they validate a custom profile. If yours rejects a payload or silently ignores a key, send us the error text and we will turn a fix around quickly.