> ## 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.

# Jamf

> Deploy Oso to macOS devices via Jamf Pro.

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

* Oso environment ID (find it in **Organization Settings → Environments** in the [Oso dashboard](https://ui.osohq.com/settings/?tab=environments))
* Each computer must have a user assigned in Jamf Pro with an email address in the **User and Location** record. Jamf substitutes `$EMAIL` with that address when deploying `mobileconfig` files.

## 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.

**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</string>
            <key>PayloadUUID</key>
            <string>A1B2C3D4-E5F6-7890-ABCD-EF1234567890</string>
            <key>PayloadDisplayName</key>
            <string>Oso Settings</string>
            <key>PayloadDescription</key>
            <string>Configures Oso</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <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>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</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>F1E2D3C4-B5A6-9870-FEDC-BA0987654321</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>
```

**Upload to Jamf Pro:**

1. Go to **Computers → Configuration Profiles** and click **New**.
2. Under the **General** tab, set:
   * **Name**: `Oso`
   * **Description**: `Configures Oso for AI traffic monitoring`
   * **Distribution Method**: Install Automatically
3. Click **Upload** and attach the edited `oso.mobileconfig`.
4. Under the **Scope** tab, select your target computers or smart group.
5. Click **Save**.

## Step 2: Upload 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.

Copy the script below.

```bash theme={null}
#!/bin/bash
# Oso Jamf Install Script
#
# Downloads and installs Oso non-interactively. Reads OSO_ENVIRONMENT and
# USER_EMAIL from the managed plist written by oso.mobileconfig.

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 computer in Jamf Pro." >&2
    exit 1
fi

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

# Use --claude-mode hooks if your organization manages Claude Code settings
# through claude.ai and wants to avoid conflicts with a local managed-settings.json.
# Otherwise, omit the flag or use --claude-mode managed-settings (the default).
curl -fsSL https://install.osohq.com/install.sh | sh -s -- \
    --env "$OSO_ENVIRONMENT" \
    --email "$USER_EMAIL" \
    --force \
    --claude-mode managed-settings

echo "Oso installation complete."
```

1. Go to **Settings → Computer Management → Scripts** and click **New**.
2. Under the **General** tab, set the **Name** to `Oso Install`.
3. Under the **Script** tab, paste the script above.
4. Click **Save**.

## Step 3: Create a policy to run the install script

1. Go to **Computers → Policies** and click **New**.
2. Under the **General** tab:
   * **Display Name**: `Oso Install`
   * **Triggers**: check **Enrollment Complete** and **Recurring Check-In**
   * **Execution Frequency**: Once per computer
3. Under the **Scripts** tab, click **Configure**, add `Oso Install`, and set **Priority** to **After**.
4. Under the **Scope** tab, select your target computers or smart group.
5. Click **Save**.

Devices that are already enrolled will run the script at their next check-in. To trigger an immediate run on a specific device, run `sudo jamf policy` in its terminal.

## Step 4: (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</string>
            <key>PayloadUUID</key>
            <string>B2C3D4E5-F6A7-8901-BCDE-F12345678901</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</string>
            <key>PayloadUUID</key>
            <string>D4E5F6A7-B8C9-0123-DEFA-234567890123</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 browser 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</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-CDEF-123456789012</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 Jamf 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 Jamf.
  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
```
