Skip to content

Deploy via MDM (IT guide)

This guide is for IT admins deploying the InPolicy Mac app to a managed fleet. The end-user experience is zero-touch: no sign-in screen, no Accessibility prompt, no manual configuration. The user installs the app (or you install it for them), and detection is running.

For individual (unmanaged) install, see Install for an individual.

Three things:

  1. The appInPolicy.pkg, signed and notarized.
  2. A PPPC (Privacy Preferences Policy Control) configuration profile — silently grants Accessibility permission so the user never sees a prompt.
  3. A Managed Preferences configuration profile — injects the organization-wide device token and the per-user email so the app authenticates automatically on first launch.

All three are standard MDM artifacts. They work in Jamf Pro, Kandji, Mosyle, JumpCloud, Intune, Addigy, and any other MDM that supports macOS configuration profiles.

  • Minimum: macOS 13 (Ventura).
  • Tested on 13, 14 (Sonoma), and 15 (Sequoia).
  • Earlier versions are not supported.

Download InPolicy.pkg from the release your InPolicy account manager pointed you to. The PKG is:

  • Signed with the InPolicy Developer ID Application certificate.
  • Notarized by Apple (stapled to the bundle).
  • Gatekeeper-safe — no right-click-to-open workaround needed.

Before shipping to your fleet, verify:

Terminal window
pkgutil --check-signature InPolicy.pkg
spctl --assess --type install InPolicy.pkg

Both should succeed with no warnings.

2. Extract the code requirement for the PPPC profile

Section titled “2. Extract the code requirement for the PPPC profile”

You’ll need the code requirement string to scope the Accessibility permission to the real InPolicy binary. Install the PKG on a staging Mac, then:

Terminal window
codesign -d -r- /Applications/InPolicy.app

Copy the line that starts with designated =>. You’ll paste it into the PPPC profile.

Create a configuration profile that grants Accessibility to InPolicy. The key fields:

  • Identifier: ai.inpolicy.desktop
  • Code Requirement: the string from step 2
  • Service: AccessibilityAllowed
  • Comment: “InPolicy requires Accessibility to observe text in focused fields for policy enforcement.”

In Jamf, this is a Payload → Privacy Preferences Policy Control → add InPolicy. In Kandji and others, the pattern is similar. Sign the profile with your MDM’s signing certificate before deploying.

Create a second profile that writes to the ai.inpolicy.desktop preference domain. Required keys:

KeyTypeValue
deviceTokenStringYour organization’s device token from the InPolicy admin dashboard (Settings → Device Provisioning)
userEmailStringThe user’s email — use your MDM’s variable: $EMAIL (Jamf), {{user.email}} (Kandji), {{UserPrincipalName}} (Intune), %EMAIL% (Mosyle), $email$ (Addigy)

Optional keys are documented in Managed preferences reference.

The order matters:

  1. Deploy the PPPC profile first. If it lands before the app is installed, macOS will apply it as soon as the app arrives.
  2. Deploy the Managed Preferences profile second (or in parallel — but before app install is fine).
  3. Deploy the PKG last. When it installs, both profiles are already in place, and the app can read its config and authenticate on first launch.

Missing this order is the single most common deployment issue — if the PKG lands before the PPPC profile, the user sees an Accessibility prompt on first launch.

If everything was deployed correctly:

  • App installs silently (via your MDM).
  • On first launch, the menu bar icon appears.
  • No Accessibility prompt. No sign-in screen.
  • Within a few seconds, the shield icon shows a green checkmark: the app has authenticated to your tenant using the device token and the user’s email.

If the user sees a slashed shield in the menu bar, one of these is off:

  • Accessibility not granted (PPPC profile missing or mis-scoped).
  • deviceToken or userEmail not set in Managed Preferences.
  • The device token has been revoked.
  • The user was removed from the tenant.

Clicking the shield shows an error state with a short diagnostic string.

The app registers itself as a Login Item via Apple’s SMAppService API on first successful authentication. No launchd plist to deploy. If you prefer to block the login item registration, set autoStartAtLogin to false in the Managed Preferences profile.

By default, the app checks for Sparkle updates every 24 hours and installs them silently. To gate updates through your change-management process:

  • Set autoUpdateEnabled to false in Managed Preferences.
  • Deploy new PKGs via your MDM on your own schedule.

To remove the app from a device:

  1. Remove the Managed Preferences profile from scope — the app will see missing config on next launch and stop detecting.
  2. Remove the PPPC profile from scope.
  3. Push a removal script (or let the app sit dormant):
    Terminal window
    /usr/bin/pkgutil --forget ai.inpolicy.desktop
    /bin/rm -rf /Applications/InPolicy.app
    /bin/rm -rf ~/Library/Application\ Support/InPolicy
    /usr/bin/security delete-generic-password -s "ai.inpolicy.desktop" 2>/dev/null

The Mac app needs outbound HTTPS to:

  • api.inpolicy.ai:443 (default; configurable via apiBaseURL)
  • inpolicyai.github.io or updates.inpolicy.ai (for Sparkle updates)
  • sentry.io (error reporting, unless disabled)

No inbound connections. No listening ports. No peer-to-peer traffic.

  • Obtain signed + notarized InPolicy.pkg.
  • Verify PKG signature and notarization.
  • Extract code requirement from the installed app.
  • Build and sign PPPC profile.
  • Build and sign Managed Preferences profile with deviceToken + MDM-substituted userEmail.
  • Deploy PPPC profile first.
  • Deploy Managed Preferences profile.
  • Deploy PKG.
  • Verify on a staging device: menu bar shield shows green checkmark, TextEdit shows policy overlay on a test phrase.
  • Confirm InPolicy appears under System Settings → Privacy & Security → Accessibility as granted.