# Jamf Pro Distribution (macOS)

Deploy Capsule Security hooks for AI coding assistants across your macOS fleet using Jamf Pro. Capsule supports two paths:

- **Automated (recommended)** - Connect Jamf Pro as a Capsule integration. Capsule creates and reconciles script policies in your Jamf Pro instance on your behalf, scoped to the computer groups you choose.
- **Manual** - Download the configuration files from the Capsule portal and create the Jamf packages or script policies yourself, following the per-product steps later in this guide.


Both paths deploy the same configuration to the same locations on macOS devices. Use the automated path when you want changes to flow continuously (new hooks, rotated tokens, scope changes) without manual touch-ups in the Jamf Pro console.

## Prerequisites

- **Jamf Pro** console with administrative access
- A **Capsule Security** account with admin access
- Target devices running macOS
- For the manual package path: **[Jamf Composer](https://app.jamfnow.com/account/composer)** installed on your Mac


## Automated: Connect Jamf Pro as a Capsule integration

The Jamf Pro integration lets Capsule create, update, and remove **scripts and policies** directly through the Jamf Pro API, scoped to the computer groups you select. Once connected, you create one **Distribution** per target product (Cursor, Claude Code, GitHub Copilot, Devin (Windsurf), or Codex), pick the scope, and Capsule keeps the deployed script content in sync with the corresponding integration.

### Step 1: Create an API role and client in Jamf Pro

Capsule authenticates with an **API client** you create in your Jamf Pro instance (OAuth client-credentials; see [Jamf Pro API Roles and Clients](https://learn.jamf.com/en-US/bundle/jamf-pro-documentation-current/page/API_Roles_and_Clients.html)).

1. In Jamf Pro, go to **Settings > System > API Roles and Clients**.
2. Create an **API role** with these privileges:
  - Create / Read / Update / Delete **Scripts**
  - Create / Read / Update / Delete **Policies**
  - Read **Smart Computer Groups** and **Static Computer Groups**
3. Create an **API client** assigned to that role, enable it, and copy the **client ID** and **client secret** (the secret is shown once).


### Step 2: Connect in the Capsule portal

1. In the Capsule portal, navigate to **Integrations** and locate **Jamf Pro**.
2. Click **Install** and enter your Jamf Pro URL (for example `https://acme.jamfcloud.com`), the client ID, and the client secret. Capsule validates the credentials against your instance before saving.


### Step 3: Create distributions

1. On the Jamf Pro integration page, open the **Distributions** tab and click **New distribution**.
2. Pick the target integration (Cursor, Claude Code, GitHub Copilot, Devin (Windsurf), or Codex).
3. Scope it to **all computers** or select one or more **computer groups**.
4. Create the distribution. Capsule creates a script and a policy in Jamf Pro; devices apply them at their next check-in (typically within 15 to 30 minutes).


The policy runs at **recurring check-in** with **Ongoing** frequency. The deployed script is idempotent: it rewrites the hook file only when the content drifts, so re-runs are free, configuration updates converge automatically, and locally deleted hook files self-heal.

### Updating, uninstalling, and deleting

- **Edit / Reapply** - Capsule rewrites the Jamf Pro script and policy; devices converge at the next check-in.
- **Uninstall** - Capsule delivers a cleanup policy that removes Capsule-owned hook files from devices (files are only deleted when they carry Capsule's content marker), then removes the install script and policy. The cleanup objects stay in Jamf Pro until you delete the distribution, so devices that were offline still clean up when they return.
- **Delete** - Removes the Jamf Pro objects and the distribution record. Hook files already on devices stay in place; uninstall first if you want them removed.


## Manual distribution

The remaining sections cover the manual path: building packages with Jamf Composer for Cursor, GitHub Copilot, Claude Code, and Devin (Windsurf), and a script policy or configuration profile for Codex.

## Cursor

Deploy the Cursor hooks configuration using a Jamf Composer package.

### Step 1: Download the Configuration

1. Log in to the **Capsule Security** portal
2. Navigate to **Settings > Integrations**
3. Locate the **Cursor** integration
4. Download the `hooks.json` file


### Step 2: Create the Package

1. Open **[Jamf Composer](https://app.jamfnow.com/account/composer)** on your Mac
2. Create a new package source:
  - Open Finder and create the directory structure locally: `/Library/Application Support/Cursor/`
  - Place the `hooks.json` file inside this directory
  - **Important**: Composer captures the exact file structure, so the `hooks.json` file must already be in `/Library/Application Support/Cursor/` before dragging into Composer
  - Drag only the `Cursor` folder directly into Composer's **Sources** panel on the left sidebar
3. Configure the package destination:
  - In the left sidebar, right-click on the newly created package source
  - Select **Edit Package** or **Package Settings**
  - Confirm the destination is set to `/` (root) so files install to `/Library/Application Support/Cursor/`
4. Add a **Preinstall Script**:
  - Expand the Package under **Sources**
  - Right-click on **Scripts** and select **Add Shell Script > preinstall**
  - Paste the following script:

```bash
#!/bin/bash
mkdir -p "/Library/Application Support/Cursor"
chmod 755 "/Library/Application Support/Cursor"
exit 0
```
5. Build the package:
  - Click **Build as PKG**
  - Save as `CapsuleCursorHooks.pkg`


### Step 3: Upload and Deploy

1. Log in to your **Jamf Pro** console
2. Navigate to **Settings > Computer Management > Packages**
3. Click **New** and upload the `.pkg` file
4. Create a **Policy**:
  - Navigate to **Computers > Policies** and click **New**
  - **Name**: Deploy Capsule Security Cursor Hooks
  - **Trigger**: Recurring Check-in
  - **Execution Frequency**: Once per computer
  - Under **Packages**, click **Configure**, add the package, and set **Action** to **Install**
5. Configure the **Scope**: add target computers, groups, or departments
6. Save and deploy


### Verification

After deployment, restart Cursor on target devices, then:

1. Open Cursor Settings
2. Navigate to the **Hooks** tab
3. Confirm the hooks are listed and enabled


## GitHub Copilot

Deploy the GitHub Copilot hooks configuration using a Jamf Composer package.

### Step 1: Download the Configuration

1. Log in to the **Capsule Security** portal
2. Navigate to **Settings > Integrations**
3. Locate the **GitHub Copilot** integration
4. Download the `capsule-hooks.json` file


### Step 2: Create the Package

1. Open **[Jamf Composer](https://app.jamfnow.com/account/composer)** on your Mac
2. Create a new package source:
  - Open Finder and create the directory structure locally: `/Library/Application Support/Code/User/hooks/`
  - Place the `capsule-hooks.json` file inside this directory
  - Drag only the `hooks` folder directly into Composer's **Sources** panel on the left sidebar
3. Configure the package destination:
  - In the left sidebar, right-click on the newly created package source
  - Select **Edit Package** or **Package Settings**
  - Confirm the destination is set to `/` (root) so files install to `/Library/Application Support/Code/User/hooks/`
4. Add a **Preinstall Script**:
  - Expand the Package under **Sources**
  - Right-click on **Scripts** and select **Add Shell Script > preinstall**
  - Paste the following script:

```bash
#!/bin/bash
mkdir -p "/Library/Application Support/Code/User/hooks"
chmod 755 "/Library/Application Support/Code/User/hooks"
exit 0
```
5. Build the package:
  - Click **Build as PKG**
  - Save as `CapsuleCopilotHooks.pkg`


### Step 3: Upload and Deploy

1. Log in to your **Jamf Pro** console
2. Navigate to **Settings > Computer Management > Packages**
3. Click **New** and upload the `.pkg` file
4. Create a **Policy**:
  - Navigate to **Computers > Policies** and click **New**
  - **Name**: Deploy Capsule Security GitHub Copilot Hooks
  - **Trigger**: Recurring Check-in
  - **Execution Frequency**: Once per computer
  - Under **Packages**, click **Configure**, add the package, and set **Action** to **Install**
5. Configure the **Scope**: add target computers, groups, or departments
6. Save and deploy


### Verification

After deployment, restart VS Code on target devices, then:

1. Right-click in the **Chat** view and select **Diagnostics**
2. Confirm the hooks are loaded and enabled


## Claude Code

Deploy the Claude Code managed settings configuration using a Jamf Composer package.

### Step 1: Download the Configuration

1. Log in to the **Capsule Security** portal
2. Navigate to **Settings > Integrations**
3. Locate the **Claude Code** integration
4. Click **Install** and select **macOS** as the target platform
5. Download the `managed-settings.json` file


### Step 2: Create the Package

1. Open **[Jamf Composer](https://app.jamfnow.com/account/composer)** on your Mac
2. Create a new package source:
  - Open Finder and create the directory structure locally: `/Library/Application Support/ClaudeCode/`
  - Place the `managed-settings.json` file inside this directory
  - Drag only the `ClaudeCode` folder directly into Composer's **Sources** panel on the left sidebar
3. Configure the package destination:
  - In the left sidebar, right-click on the newly created package source
  - Select **Edit Package** or **Package Settings**
  - Confirm the destination is set to `/` (root) so files install to `/Library/Application Support/ClaudeCode/`
4. Add a **Preinstall Script**:
  - Expand the Package under **Sources**
  - Right-click on **Scripts** and select **Add Shell Script > preinstall**
  - Paste the following script:

```bash
#!/bin/bash
mkdir -p "/Library/Application Support/ClaudeCode"
chmod 755 "/Library/Application Support/ClaudeCode"
exit 0
```
5. Build the package:
  - Click **Build as PKG**
  - Save as `CapsuleClaudeCodeHooks.pkg`


### Step 3: Upload and Deploy

1. Log in to your **Jamf Pro** console
2. Navigate to **Settings > Computer Management > Packages**
3. Click **New** and upload the `.pkg` file
4. Create a **Policy**:
  - Navigate to **Computers > Policies** and click **New**
  - **Name**: Deploy Capsule Security Claude Code Hooks
  - **Trigger**: Recurring Check-in
  - **Execution Frequency**: Once per computer
  - Under **Packages**, click **Configure**, add the package, and set **Action** to **Install**
5. Configure the **Scope**: add target computers, groups, or departments
6. Save and deploy


### Verification

After deployment, restart Claude Code on target devices, then:

1. Run `/hooks` in Claude Code to confirm all hooks are listed
2. Start a session and verify events appear in the Capsule Security portal


## Devin (Windsurf)

Deploy the Devin (Windsurf) hooks configuration using a Jamf Composer package. Cascade merges hook configurations from the system, user, and workspace levels ([Cascade hooks documentation](https://docs.devin.ai/desktop/cascade/hooks)), so deploying to the system-level path applies the Capsule hooks to every user on the device, and they cannot be disabled by end users.

### Step 1: Download the Configuration

1. Log in to the **Capsule Security** portal
2. Navigate to **Settings > Integrations**
3. Locate the **Devin (Windsurf)** integration
4. Choose **MDM** as the deployment method
5. Select **Mac** as the target platform and download the `hooks.json` file


### Step 2: Create the Package

1. Open **[Jamf Composer](https://app.jamfnow.com/account/composer)** on your Mac
2. Create a new package source:
  - Open Finder and create the directory structure locally: `/Library/Application Support/Windsurf/`
  - Place the `hooks.json` file inside this directory
  - Drag only the `Windsurf` folder directly into Composer's **Sources** panel on the left sidebar
3. Configure the package destination:
  - In the left sidebar, right-click on the newly created package source
  - Select **Edit Package** or **Package Settings**
  - Confirm the destination is set to `/` (root) so files install to `/Library/Application Support/Windsurf/`
4. Add a **Preinstall Script**:
  - Expand the Package under **Sources**
  - Right-click on **Scripts** and select **Add Shell Script > preinstall**
  - Paste the following script:

```bash
#!/bin/bash
mkdir -p "/Library/Application Support/Windsurf"
chmod 755 "/Library/Application Support/Windsurf"
exit 0
```
5. Build the package:
  - Click **Build as PKG**
  - Save as `CapsuleWindsurfHooks.pkg`


### Step 3: Upload and Deploy

1. Log in to your **Jamf Pro** console
2. Navigate to **Settings > Computer Management > Packages**
3. Click **New** and upload the `.pkg` file
4. Create a **Policy**:
  - Navigate to **Computers > Policies** and click **New**
  - **Name**: Deploy Capsule Security Devin (Windsurf) Hooks
  - **Trigger**: Recurring Check-in
  - **Execution Frequency**: Once per computer
  - Under **Packages**, click **Configure**, add the package, and set **Action** to **Install**
5. Configure the **Scope**: add target computers, groups, or departments
6. Save and deploy


### Verification

Hooks are loaded at application start, so after deployment, close Devin Desktop completely on target devices and reopen it, then:

1. Start a **Cascade** session and run a simple task to generate activity
2. In the Capsule portal, navigate to **Inventory > Agents** and confirm the agent appears


## Codex

Deploy the Codex [managed configuration](https://developers.openai.com/codex/enterprise/managed-configuration) using a Jamf script policy. Codex reads a managed `requirements.toml` from the system-wide path `/etc/codex/requirements.toml`; because the configuration is managed, the Capsule hooks are trusted by policy, apply to every user on the device (including users created later), and cannot be overridden or removed by users. No per-user trust approval is required.

Alternatively, Jamf Pro can deliver the same configuration as a **Configuration Profile** in the `com.openai.codex` preference domain, with the downloaded file's content base64-encoded into the `requirements_toml_base64` key.

### Step 1: Download the Configuration

1. Log in to the **Capsule Security** portal
2. Navigate to **Settings > Integrations**
3. Locate the **Codex** integration
4. Choose **MDM** as the deployment method
5. Select **Mac** as the target platform and download the `requirements.toml` file


### Step 2: Create the Script

1. Log in to your **Jamf Pro** console
2. Navigate to **Settings > Computer Management > Scripts** and click **New**
3. **Display Name**: Deploy Capsule Security Codex Managed Configuration
4. Paste the following script, replacing the placeholder line with the contents of the downloaded `requirements.toml` (keep the `CAPSULE_REQUIREMENTS_EOF` marker lines unchanged and unindented):

```bash
#!/bin/bash
CODEX_DIR="/etc/codex"
mkdir -p "$CODEX_DIR"
chmod 755 "$CODEX_DIR"
cat > "$CODEX_DIR/requirements.toml" << 'CAPSULE_REQUIREMENTS_EOF'
<PASTE YOUR REQUIREMENTS.TOML CONTENT HERE>
CAPSULE_REQUIREMENTS_EOF
chmod 644 "$CODEX_DIR/requirements.toml"
exit 0
```


### Step 3: Create the Policy

1. Navigate to **Computers > Policies** and click **New**
2. **Name**: Deploy Capsule Security Codex Managed Configuration
3. **Trigger**: Recurring Check-in
4. **Execution Frequency**: Once per computer
5. Under **Scripts**, click **Configure** and add the script
6. Configure the **Scope**: add target computers, groups, or departments
7. Save and deploy


### Verification

After deployment, close any running Codex CLI sessions on target devices, then:

1. Start a new Codex CLI session so the managed configuration is loaded
2. In the Capsule portal, navigate to **Inventory > Agents** and confirm the Codex agent appears with session, prompt, response, and tool-invocation events


## Key Considerations

- Preinstall scripts ensure target directories exist with proper permissions before file deployment
- Packages must be in `.pkg` format to support preinstall scripts
- To update configurations, create a new package version and update the policy
- Use Jamf Smart Groups for dynamic targeting and staged rollouts
- All five integrations can be deployed as separate packages and policies, assigned independently
- **Codex** uses a managed configuration (`/etc/codex/requirements.toml`) enforced by policy - it applies to all users on the device (including users created later) and cannot be overridden by user-level configuration
- **Devin (Windsurf)** merges system, user, and workspace hook configurations, so the system-level deployment coexists with any per-user hooks and cannot be disabled by end users
- Restart each application on target devices after deployment for hooks to take effect


## Support

For help with deployment:

- **Email**: support@capsule.security
- **Include**: Your organization ID, Jamf Pro environment details, and any error messages


## References

- [Jamf Composer User Guide - Creating Package Sources](https://docs.jamf.com/composer/10.25.0/user-guide/Creating_Package_Sources.html)
- [Jamf Composer User Guide - Building Packages](https://docs.jamf.com/composer/10.25.0/user-guide/Building_Packages_from_Package_Sources.html)
- [Codex Hooks](https://developers.openai.com/codex/hooks)
- [Codex Managed Configuration](https://developers.openai.com/codex/enterprise/managed-configuration)