> ## Documentation Index
> Fetch the complete documentation index at: https://www.osohq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Iru

> Deploy Oso to macOS devices via Iru (formerly Kandji).

This page walks through deploying Oso to your organization's macOS devices using Iru.

* Oso environment ID (find it in **Settings → Environments** in the [Oso dashboard](https://ui.osohq.com))
* Admin access to the Iru platform
* macOS devices enrolled in Iru Endpoint
* Each device must have a user assigned in Iru with an email address. Iru substitutes `$EMAIL` with that address when deploying configuration profiles. To assign a user, go to **Devices → select the device → Edit device details → Edit user**.

## Step 1: Deploy the configuration profile

The configuration profile writes your Oso environment settings and the assigned user's email to each device's managed preferences, so the installer can read them without user interaction.

**Prepare the profile:**

Copy the profile below, replace `YOUR_ENVIRONMENT_ID` with your Oso environment ID, and save it as `oso.mobileconfig`.

```xml theme={null}
<?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>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.apple.ManagedClient.preferences</string>
            <key>PayloadIdentifier</key>
            <string>com.osohq.oso.settings.iru</string>
            <key>PayloadUUID</key>
            <string>9A8B7C6D-5E4F-3210-9A8B-7C6D5E4F3210</string>
            <key>PayloadDisplayName</key>
            <string>Oso Settings</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadEnabled</key>
            <true/>
            <key>PayloadContent</key>
            <dict>
                <key>com.osohq.oso</key>
                <dict>
                    <key>Forced</key>
                    <array>
                        <dict>
                            <key>mcx_preference_settings</key>
                            <dict>
                                <key>OSO_ENVIRONMENT</key>
                                <string>YOUR_ENVIRONMENT_ID</string>
                                <key>OSO_PROXY_URL</key>
                                <string>https://agents.osohq.cloud</string>
                                <key>OSO_API_URL</key>
                                <string>https://cloud.osohq.com</string>
                                <key>USER_EMAIL</key>
                                <string>$EMAIL</string>
                            </dict>
                        </dict>
                    </array>
                </dict>
            </dict>
        </dict>
    </array>
    <key>PayloadDescription</key>
    <string>Configures Oso for AI traffic monitoring.</string>
    <key>PayloadDisplayName</key>
    <string>Oso</string>
    <key>PayloadIdentifier</key>
    <string>com.osohq.oso.profile.iru</string>
    <key>PayloadOrganization</key>
    <string>Oso Security, Inc.</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadScope</key>
    <string>System</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>8B9C0D1E-2F3A-4567-8B9C-0D1E2F3A4567</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>
```

**Upload to Iru:**

1. Go to **Library** and click **Add Library Item**.
2. Search for and select **Custom Profile**.
3. Set the **Name** to `Oso`.
4. Click **Upload Profile** and attach the edited `oso.mobileconfig`.
5. Under **Blueprints**, assign the profile to your target blueprint(s).
6. Click **Save**.

## Step 2: Deploy the install script

The install script runs silently on each device and does two things: it configures your coding agents (Claude Code, Cursor, Codex) to route traffic through Oso for session monitoring, and it registers the device and user with Oso for identity correlation. It reads `OSO_ENVIRONMENT` and `USER_EMAIL` directly from the managed plist written in Step 1, with no user interaction required.

1. Go to **Library** and click **Add Library Item**.
2. Search for and select **Custom Script**.
3. Set the **Name** to `Oso Install`.
4. Under **Blueprints**, assign the script to your target blueprint(s).
5. Set **Execution Frequency** to **Install once per device**.
6. Paste the script below into the **Audit Script** field.
7. Click **Save**.

```bash theme={null}
#!/bin/bash
set -euo pipefail

PLIST="/Library/Managed Preferences/com.osohq.oso.plist"

OSO_ENVIRONMENT=$(defaults read "$PLIST" OSO_ENVIRONMENT 2>/dev/null || true)
if [[ -z "$OSO_ENVIRONMENT" ]]; then
    echo "ERROR: OSO_ENVIRONMENT not set. Deploy oso.mobileconfig first." >&2
    exit 1
fi

USER_EMAIL=$(defaults read "$PLIST" USER_EMAIL 2>/dev/null || true)
if [[ -z "$USER_EMAIL" ]]; then
    echo "ERROR: USER_EMAIL not set. Assign a user with an email address to this device in Iru." >&2
    exit 1
fi

echo "Installing Oso for $USER_EMAIL (env: $OSO_ENVIRONMENT)..."

curl -fsSL https://install.osohq.com/install.sh | sh -s -- \
    --env "$OSO_ENVIRONMENT" \
    --email "$USER_EMAIL" \
    --force

echo "Oso installation complete."
```

Iru runs the audit script at each check-in until it exits 0. Once the installation succeeds, the script exits 0 and Iru marks the item as passed, so it will not run again.

## Step 3: (Optional) Deploy the Chrome extension profile

To force-install the Oso Chrome extension, copy the profile below, replace `YOUR_ENVIRONMENT_ID` with your Oso environment ID, and save it as `chrome.mobileconfig`. Then upload and deploy it following the same steps as Step 1.

```xml theme={null}
<?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>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.apple.ManagedClient.preferences</string>
            <key>PayloadIdentifier</key>
            <string>com.osohq.oso.chrome.iru</string>
            <key>PayloadUUID</key>
            <string>A1B2C3D4-E5F6-7890-A1B2-C3D4E5F67890</string>
            <key>PayloadDisplayName</key>
            <string>Oso Chrome Policy</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadEnabled</key>
            <true/>
            <key>PayloadContent</key>
            <dict>
                <key>com.google.Chrome</key>
                <dict>
                    <key>Forced</key>
                    <array>
                        <dict>
                            <key>mcx_preference_settings</key>
                            <dict>
                                <key>ExtensionInstallForcelist</key>
                                <array>
                                    <string>nochaaflecnmeafkagnbiabpgahpledi;https://install.osohq.com/extension/chrome/update_manifest.xml</string>
                                </array>
                            </dict>
                        </dict>
                    </array>
                </dict>
            </dict>
        </dict>
        <dict>
            <key>PayloadType</key>
            <string>com.apple.ManagedClient.preferences</string>
            <key>PayloadIdentifier</key>
            <string>com.osohq.oso.chrome.extension.iru</string>
            <key>PayloadUUID</key>
            <string>B2C3D4E5-F6A7-8901-B2C3-D4E5F6A78901</string>
            <key>PayloadDisplayName</key>
            <string>Oso Chrome Extension Managed Storage</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadEnabled</key>
            <true/>
            <key>PayloadContent</key>
            <dict>
                <key>com.google.Chrome.extensions.nochaaflecnmeafkagnbiabpgahpledi</key>
                <dict>
                    <key>Forced</key>
                    <array>
                        <dict>
                            <key>mcx_preference_settings</key>
                            <dict>
                                <key>environmentId</key>
                                <string>YOUR_ENVIRONMENT_ID</string>
                                <key>userEmail</key>
                                <string>$EMAIL</string>
                            </dict>
                        </dict>
                    </array>
                </dict>
            </dict>
        </dict>
    </array>
    <key>PayloadDescription</key>
    <string>Force-installs the Oso Chrome extension and configures it for AI traffic monitoring.</string>
    <key>PayloadDisplayName</key>
    <string>Oso Chrome Extension</string>
    <key>PayloadIdentifier</key>
    <string>com.osohq.oso.chrome.profile.iru</string>
    <key>PayloadOrganization</key>
    <string>Oso Security, Inc.</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadScope</key>
    <string>System</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>C3D4E5F6-A7B8-9012-C3D4-E5F6A7B89012</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>
```

After the profile lands on a device, open `chrome://policy/` in Chrome and click **Reload policies** to apply immediately.

<Warning>
  **Chrome enterprise management requirement**

  Chrome (v119+) blocks force-installation of extensions not hosted on the Chrome Web Store unless it detects the device as enterprise managed. Devices enrolled in Iru via user-approved MDM (self-enrollment) do not satisfy this requirement. Chrome requires either DEP/ADE supervision through Apple Business Manager or Chrome Browser Cloud Management (CBCM) enrollment.

  If `chrome://policy` shows `[BLOCKED]` next to the extension entry, enroll Chrome in CBCM:

  1. In the [Google Admin Console](https://admin.google.com), go to **Devices → Chrome → Connectors → Browser Cloud Management enrollment tokens**.
  2. Click **Add enrollment token**, give it a name, and copy the generated token.
  3. Add the following key to the `mcx_preference_settings` dict in `chrome.mobileconfig`, alongside `ExtensionInstallForcelist`:

  ```xml theme={null}
  <key>CloudManagementEnrollmentToken</key>
  <string>YOUR_CBCM_TOKEN</string>
  ```

  4. Redeploy the updated profile via Iru.
  5. Fully quit and relaunch Chrome on the device (`⌘Q`, then reopen).

  After enrollment, `chrome://management` will show browser management and `chrome://policy` will show the extension installing without `[BLOCKED]`.
</Warning>

## Verifying deployment

After devices enroll, confirm the installation succeeded:

```bash theme={null}
# Managed preferences written by the configuration profile
defaults read "/Library/Managed Preferences/com.osohq.oso"

# Tool configs written by the installer (system-level)
cat "/Library/Application Support/ClaudeCode/managed-settings.json"
cat "/Library/Application Support/Cursor/hooks.json"
cat "/etc/codex/managed_config.toml"

# Identity registered with Oso
cat "/Library/Application Support/Oso/identity.json"

# Binaries installed
ls -la /usr/local/bin/oso-hook /usr/local/bin/oso-setup
```
