> For the complete documentation index, see [llms.txt](https://help.nightfall.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.nightfall.ai/data-exfiltration-prevention/ai-agent-security/ai-governance/auditability-and-control/setup-and-installation/nightfall-hooks-for-cursor.md).

# Nightfall Hooks for Cursor

This guide walks an MDM administrator through deploying Nightfall's Cursor hooks to corporate-managed developer devices, end to end. It covers all five supported MDMs in detail. The deployment package ships as a zip (`Hooks Setup/cursor/`) containing this payload, the install scripts, and a `README.md` quick reference. This guide is the long-form companion to that README.

***

### When to use this guide

Nightfall installs hooks on most AI coding agents **automatically** - when you activate an AI Agent Security policy, the Nightfall endpoint agent writes the hook configuration to `~/.claude/settings.json` on each endpoint, with nothing for IT to deploy by hand. That path is documented in setup.md. This guide is the exception for **Cursor**, which requires a **manual MDM deployment** of a system-level `hooks.json`.

{% hint style="info" %}
**Why Cursor needs a manual path (Cursor enterprise hooks bug, Feb 2026):** Hooks configured in Cursor's admin dashboard sometimes don't materialize at the endpoint path Cursor reads from. Until Cursor resolves this, deploying `hooks.json` directly through your MDM is the reliable way to enforce Nightfall hooks in Cursor.
{% endhint %}

Use the automatic path for Claude Code and VS Code. Use **this guide** to add reliable hook coverage for Cursor on managed devices.

***

### How it works

Cursor reads its hook configuration from a single file at a fixed path and a fixed name (`hooks.json`). Deployment is a **two-step model**:

1. **Stage the payload.** Your MDM's file-distribution (or app-deployment) feature drops Nightfall's `hooks.json` at a staging path on each device.
2. **Run the merge script.** A script provided in the package splices Nightfall's entries into Cursor's `hooks.json` at the path Cursor actually reads.

#### Why merge instead of overwrite

The file Cursor reads (`hooks.json`) is **shared** - another security vendor or your own org policy may already own entries in it. And because the filename and path are dictated by Cursor, you can't rename or relocate it without Cursor ceasing to read it.

So the install scripts **merge**: they drop any existing Nightfall-marked entries, then append the staged Nightfall entries, leaving every other vendor's entries untouched. This makes re-runs **idempotent** - periodic re-execution never accumulates duplicates.

***

### Prerequisites

Before deploying the Cursor hooks payload:

1. **The Nightfall endpoint agent is already installed** and running on the managed devices. The agent owns the `nightfall-hook-relay` binary the hooks invoke.
2. **You've selected the MDM scope** (device group / smart group) that will receive the deployment.
3. **`jq` is present on macOS devices where a `hooks.json` may already exist.** The macOS install script refuses to run — rather than clobber another vendor's entries - if a target `hooks.json` exists and `jq` is not installed. (Greenfield devices with no existing `hooks.json` do not need `jq`.)

***

### Package contents

```
payloads/hooks.json                    # Nightfall's Cursor hook entries
scripts/macos/install.sh               # MDM-agnostic merge (idempotent on re-run)
scripts/macos/audit.sh                 # presence check (grep)
scripts/windows/install.ps1            # MDM-agnostic merge (idempotent on re-run)
scripts/windows/detect.ps1             # presence check (regex match)
README.md

```

The scripts are **MDM-agnostic** - the same `install.sh` works whether your MDM is Rippling, Jamf Pro, Kandji, or Workspace ONE. The per-MDM sections below show which MDM feature to wire each script into.

***

### Hooks installed

Nightfall registers four Cursor events. The two pre-action events carry `failClosed: true`, which blocks the action if the hook crashes, times out, or returns invalid JSON.

| Event                | When it fires                             | `failClosed` |
| -------------------- | ----------------------------------------- | ------------ |
| `beforeSubmitPrompt` | Before a prompt is submitted to the model | `true`       |
| `preToolUse`         | Before a tool executes                    | `true`       |
| `postToolUse`        | After a tool finishes executing           | -            |
| `afterAgentResponse` | After the agent returns its response      | -            |

All four invoke the same command: `nightfall-hook-relay --source cursor`.

`failClosed: true` on the pre-action events (`beforeSubmitPrompt`, `preToolUse`) means the action is blocked if the hook can't complete cleanly. The post-action events (`postToolUse`, `afterAgentResponse`) observe content after the action has already happened, so they monitor only  there is nothing left to block.

***

### Paths reference

| <p><br></p>                                   | macOS                                            | Windows                                |
| --------------------------------------------- | ------------------------------------------------ | -------------------------------------- |
| **Staging path** (MDM drops the payload here) | `/opt/nightfall/hooks/cursor/hooks.json`         | `C:\Nightfall\Hooks\cursor\hooks.json` |
| **Target path** (Cursor reads from here)      | `/Library/Application Support/Cursor/hooks.json` | `C:\ProgramData\Cursor\hooks.json`     |

The target path and filename are dictated by Cursor and must not be changed.

On macOS, a **greenfield** device (no existing target `hooks.json`) is handled by a plain `cp` - no `jq` required. If a target already exists, the script requires `jq` to merge and refuses to run without it. On Windows, the merge runs in PowerShell, writes the result as **UTF-8 without a BOM**, then locks the file down with `icacls`.

***

### Per-MDM setup

Every MDM follows the same two-step wiring: **distribute the payload** to the staging path, then **run the install script** to merge it into Cursor's `hooks.json`. The install scripts hard-fail unless run as **root** (macOS) or **SYSTEM / Administrator** (Windows), so always run them in a System / SYSTEM context.

#### Rippling

**macOS**

1. **Distribute the payload** — Use Rippling's file/app distribution to place `payloads/hooks.json` at `/opt/nightfall/hooks/cursor/hooks.json`.
2. **Run the merge** — Create a **Custom Script** that runs `scripts/macos/install.sh` at **System scope**, triggered **on enrollment and daily**.

**Windows**

1. **Distribute the payload** to `C:\Nightfall\Hooks\cursor\hooks.json`.
2. **Run the merge** - Create a **PowerShell Script** that runs `scripts/windows/install.ps1` at SYSTEM scope.

#### Jamf Pro

**macOS**

1. **Distribute the payload** to `/opt/nightfall/hooks/cursor/hooks.json` (e.g. via a package or a Files and Processes distribution).
2. **Run the merge** - Add `scripts/macos/install.sh` as a **Script**, then attach it to a **Policy** scoped to your device group with the triggers **Recurring Check-in** and **Enrollment Complete**.

#### Kandji

**macOS** - Kandji's **Custom Script** library item pairs an audit script with a remediation script, which matches the package's presence-check model exactly:

1. **Distribute the payload** to `/opt/nightfall/hooks/cursor/hooks.json` (Custom App or file distribution).
2. **Audit** - Set `scripts/macos/audit.sh` as the **Audit Script**. It exits 0 when Nightfall's command is already present and exits 1 when remediation is needed.
3. **Remediation** - Set `scripts/macos/install.sh` as the **Remediation Script**. Kandji runs it only when the audit reports drift.

#### Microsoft Intune

**Windows** - Wire into a **Win32 / Proactive Remediation** (Detection + Remediation):

1. **Distribute the payload** to `C:\Nightfall\Hooks\cursor\hooks.json` (e.g. a Win32 app).
2. **Detection** - Use `scripts/windows/detect.ps1` as the **Detection script**. It exits 0 (present) when Nightfall's command is already in `hooks.json` and exits 1 to trigger remediation. Run it in the **SYSTEM** context (64-bit PowerShell).
3. **Remediation** - Use `scripts/windows/install.ps1` as the **Remediation script**, also in the SYSTEM context.

#### Workspace ONE

Workspace ONE covers **both platforms** via its Scripts feature, run in the System / SYSTEM context with **Periodic and Enrollment** triggers.

**macOS**

1. **Distribute the payload** to `/opt/nightfall/hooks/cursor/hooks.json`.
2. **Run the merge** - Add `scripts/macos/install.sh` as a **Script** in the **System** context, scheduled **Periodic + on Enrollment**.

**Windows**

1. **Distribute the payload** to `C:\Nightfall\Hooks\cursor\hooks.json`.
2. **Run the merge** - Add `scripts/windows/install.ps1` as a **Script** in the **SYSTEM** context, scheduled **Periodic + on Enrollment**.

***

### Validation

Open the **Devices** page in the Nightfall console. Each device shows a **per-client hook status indicator** - a healthy status for Cursor means the deployment is working on that device. A healthy Cursor hook status on the Devices page confirms the payload was staged, the merge script ran, and Cursor is reading Nightfall's entries.

***

### Drift & re-run behavior

The audit/detection scripts (`audit.sh` / `detect.ps1`) check for the **presence** of Nightfall's command in `hooks.json` (a `grep` / regex match), not byte equality. Byte equality with the staged payload isn't meaningful because `hooks.json` is shared with other vendors.

The install scripts are **idempotent**: each run drops any existing Nightfall-marked entries and re-appends the staged ones, so periodic re-execution never accumulates duplicates and never disturbs other vendors' entries.

If the staging payload hasn't been deployed yet, the audit/detection scripts report **present / exit 0** rather than failing. Remediation couldn't succeed without the staged file, so this stops the MDM from looping on a state it can't fix from the device.

***

### Rollback

To remove Nightfall's Cursor hooks, hand-edit `hooks.json` on the device (or push an edited copy via your MDM) and remove every entry whose `command` is `nightfall-hook-relay --source cursor`. Leave all other vendors' entries - and your own org policy's entries - untouched.

The `nightfall-hook-relay` binary stays installed; the Nightfall endpoint agent owns its lifecycle.

A scripted rollback may be added in a future release. For now, removal is a manual entry edit.

***

### Troubleshooting

| Symptom                                                            | Likely cause                                                                      | Resolution                                                                                   |
| ------------------------------------------------------------------ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| macOS install exits with "jq is not installed"                     | A `hooks.json` already exists and `jq` is missing, so the script refuses to merge | Install `jq` on the device and re-run the install script                                     |
| Install exits with "must run as root" / "administrator privileges" | Script ran in a user context                                                      | Re-run in the System (macOS) or SYSTEM (Windows) context via your MDM                        |
| Install exits with "payload not found"                             | The payload wasn't staged before the script ran                                   | Deploy `hooks.json` to the staging path first, then re-run                                   |
| Windows `hooks.json` fails to parse on re-run                      | A UTF-8 BOM was written by an older PowerShell 5.1 run                            | Re-run the current `install.ps1` — it strips the BOM on read and writes UTF-8 without a BOM  |
| Cursor hook status not showing in console                          | Hooks not yet merged, or agent not connected                                      | Confirm the install script ran successfully and the Nightfall agent is running on the device |

***

### Known issues / notes

* **Cursor enterprise hooks bug (Feb 2026):** Hooks configured in Cursor's admin dashboard sometimes don't materialize at the expected endpoint path. MDM-deployed `hooks.json` is the reliable path until Cursor resolves this.
* **Cursor cloud agents** don't yet honor team/enterprise-managed hooks — only a project-committed `.cursor/hooks.json` runs in cloud sessions. The MDM deployment in this guide covers local Cursor sessions on managed devices.

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.nightfall.ai/data-exfiltration-prevention/ai-agent-security/ai-governance/auditability-and-control/setup-and-installation/nightfall-hooks-for-cursor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
