Skip to main content
If your MDM has a dedicated guide (Jamf Pro, SimpleMDM, Mosyle, Iru/Kandji, Workspace ONE), use that for provider-specific UI paths.
Migrating from the legacy script-based Detect rollout? Run Legacy macOS Detect Cleanup before rolling out the .pkg so the old runlayer-scan artifacts don’t conflict with com.runlayer.aiwatch.

Overview

A signed, notarized aiwatch binary installs once per device via .pkg. Tenant config — host, a single organization API key, Mode, legacy Enforcement, the Sessions capability flag, and the AutoUpdate gate — is pushed via an MDM Configuration Profile.

Capabilities

All behaviors ship in the same .pkg and shared PPPC / Login Items profiles. The mode and flags in the tenant-config profile decide what runs — update the configuration and re-push the profile, no .pkg reinstall. If you need multiple configurations, deploy one tenant-config profile per group. The .pkg, PPPC profile, and Login Items profile are universal and can be reused unchanged across all configurations. Project and client-config detection is always enabled after AI Watch is installed. Endpoint behavior is selected with Mode; Sessions and optional runtime discovery are controlled independently. One organization API key authenticates AI Watch scans, hooks, session events, and macOS updates; no enrollment keys are required.
  • Running-process and container discovery are disabled by default. Set their macOS/Linux keys to true or Windows properties to 1 to opt in.
  • Monitor is the default mode.
  • Sessions is enabled by default. Set Sessions=false (macOS) or AIWATCH_SESSIONS=0 (Windows) to skip the full event/session hook set.
Mode overrides the legacy Enforcement boolean when it contains a valid value. If Mode is absent or invalid, Enforcement=true maps to Enforce and Enforcement=false or absent maps to Monitor. Generated deployment artifacts still include Enforcement for older AI Watch versions: Monitor writes false, while Protect and Enforce write true. Mode-aware clients apply the exact selected mode; an older client receiving Protect falls back to Enforce rather than silently monitoring, but does not have Protect’s exact direct-MCP scanner path. Hook installation follows the combined capability state: AI Watch installs hook configs when Mode is Protect/Enforce or Sessions is enabled. Detect-only uses Monitor with Sessions disabled; omitting Sessions uses the default enabled state and installs hooks for Monitor telemetry. On current macOS and Windows packages, admins can change Mode, Sessions, process/container discovery, project depth, and project timeout from Settings → MDM configuration → Manage settings. Devices fetch the complete settings snapshot during the privileged hook reconcile, typically within an hour, without an MDM policy update. The tenant host, organization API key, AutoUpdate, CPU/memory limits, and browser-extension settings remain MDM-owned. Advanced scan tuning (optional). Detect scans walk each user’s home directory to a bounded depth within a per-scan time budget, and a cooperative in-process governor keeps CPU and memory use within soft caps. The defaults fit most fleets — override them only if scans miss deeply-nested project configs (raise depth), run out of time on very large home directories (raise timeout), or you want to constrain the scan’s footprint on constrained hosts (lower the CPU / memory caps). All are integers — macOS <integer> in the tenant-config profile, Windows REG_DWORD via the matching MSI AIWATCH_* property. Omit the keys to keep the defaults. Values outside the range are clamped into it; non-integer or non-positive values are ignored and the default applies. The CPU / memory caps are best-effort: the governor throttles the scan to hold the CPU duty cycle (max(0.05, min(cpu_cores, MaxCpuPercent% × logical_cores)) cores) and aborts the scan if its Python-heap high-water mark exceeds the memory ceiling. The MDM Configuration setup wizard bakes the selected Monitor / Protect / Enforce mode and Collect session data value into the downloaded profile, plus any Advanced scan settings overrides. When hand-editing a macOS profile, set Mode to monitor, protect, or enforce; pair legacy Enforcement=false with Monitor and Enforcement=true with Protect or Enforce; set other boolean flags explicitly and each scan-tuning key to an <integer>.

Prerequisites

  • Devices enrolled via UAMDM (User-Approved MDM) or DEP/ADE. TCC payloads are ignored on manually-enrolled MDM.
  • A single organization API key with the Shadow AI Scan role minted in Settings → Organization API keys in the Runlayer dashboard. Record the secret value (rl_org_...). The same key authenticates scanning, enforcement, sessions, and the narrow update-target/download endpoints.
  • Your Runlayer tenant host URL (e.g. https://your-instance.runlayer.com).
Apple Silicon only for now. The current release ships an arm64 .pkg.

Artifacts

The package is a .zip named aiwatch-<version>-macos-arm64.zip. Contents: Contact your Runlayer account team if you don’t have the .zip yet. The tenant profile enables AutoUpdate by default. Set it to <false/> before deployment to opt a group out; an absent key is also treated as enabled.
Deploy the three Configuration Profiles before the .pkg. Profiles must land in /Library/Managed Preferences/ and TCC before the bundled LaunchAgent’s first scan tick — otherwise aiwatch logs host not configured and TCC denies project-config reads until the next MDM sync.

Deployment

1

Edit the tenant-config profile

Open com.runlayer.aiwatch.config.mobileconfig in a text editor, replace the tenant placeholders, and choose a mode:Pair the legacy <key>Enforcement</key> boolean with Mode: <false/> for Monitor; <true/> for Protect or Enforce.
2

Upload the three Configuration Profiles

Tenant config (edited above), PPPC (as-is), Login Items (as-is). Use your MDM’s Custom Configuration Profile workflow. Assign to your target device group.PPPC + Login Items profiles are pre-pinned to Developer ID team AF2M8HC7A2 — no edits required.
3

Upload the .pkg via Custom App / LOB App / Package payload

Match the install command to your MDM’s vocabulary. The .pkg is self-contained (no install-time arguments needed) and signed/notarized so Gatekeeper accepts it. Assign to the same device group.
After deployment, change Mode, Sessions, optional process/container discovery, project depth, or project timeout from SettingsMDM configurationManage settings; connected devices refresh them during the hourly hook reconcile. To rotate the API key or change AutoUpdate, resource limits, identity overrides, or browser-extension settings, edit and re-deploy com.runlayer.aiwatch.config.mobileconfig. When hand-editing Mode, also pair legacy Enforcement=false with Monitor and Enforcement=true with Protect or Enforce. No .pkg reinstall. Keep each Apple PayloadVersion at 1.

Verification

On a test Mac after MDM sync:
In the Runlayer dashboard, navigate to Shadow and confirm scan data is arriving from the test device.

Common post-deploy issues

Confirm com.runlayer.aiwatch.loginitems.mobileconfig is scoped to the same device group as the .pkg, then force an MDM sync and check:
On macOS 13+, expect the Runlayer item to show enabled allowed visible. macOS 12 and older ignore the Login Items payload; the notification control only exists on macOS 13+.
Verify you are deploying the official signed and notarized release artifact:
Expected: a Developer ID Installer signature for Anysource Inc. and source=Notarized Developer ID.
The PPPC profile pins Full Disk Access to identifier com.runlayer.aiwatch and Developer ID team AF2M8HC7A2. Confirm the installed binary matches:
Expected: Authority=Developer ID Application: Anysource Inc. (AF2M8HC7A2) and Identifier=com.runlayer.aiwatch. Custom or ad-hoc signed builds will not satisfy the PPPC CodeRequirement.

Customize scan schedule (optional)

The bundled LaunchAgent ships with a 15-minute StartInterval. Most tenants don’t need to change it. To override, push the script below via your MDM’s recurring-script mechanism (Jamf Policy, Kandji Custom Script, SimpleMDM Script, etc.):
The next .pkg upgrade resets StartInterval to the bundled default — the override script must run on a recurring schedule, or be re-applied after each upgrade.

Upgrade

By default, the root com.runlayer.aiwatch.update LaunchDaemon checks hourly and installs the backend-selected signed + notarized .pkg. An MDM Custom App push remains a manual fallback, but the next hourly tick will restore the backend-selected target. To hold a manually pushed version, set AutoUpdate=false or align the backend rollout policy first. The pkgbuild receipt (com.runlayer.aiwatch) tracks every file in the install layout; installer removes any files in the old receipt not present in the new payload and atomically lays down the new tree per file. Mid-scan upgrades are safe — macOS lets you unlink an open file, the running aiwatch keeps its mapped .dylib pages until the next LaunchAgent tick picks up the new version. Postinstall intentionally leaves an already-loaded updater running so it cannot terminate its own installer transaction; the hourly cadence remains stable. The three Configuration Profiles (tenant config, PPPC, Login Items) are unchanged across version upgrades.
If you’ve overridden StartInterval via Custom Script, the upgrade resets it to the bundled default. Re-apply the override script on a recurring schedule.

Uninstall

For full package and hook cleanup guidance, see Remove AI Watch.

Troubleshooting

For deployment diagnostics and common macOS package issues, see Troubleshooting.