> 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-vs-code-copilot.md).

# Nightfall Hooks for VS Code Copilot

Step-by-step instructions for deploying Nightfall's VS Code Copilot hooks to corporate-managed developer devices via your MDM. For the package overview and MDM mapping table, see README.md; this guide walks through the actual setup, end to end.

> **Heads up:** VS Code Copilot hooks are **Preview**. Unlike Claude Code (one drop-in file) or\
> Cursor (one merged file), VS Code needs **two things per device**: the hook file *and* an\
> enterprise policy that tells Copilot to read it. Both steps are covered below.

***

### 1. What gets deployed

Nightfall ships a Copilot hook config (`payloads/nightfall.json`) that registers the `nightfall-hook-relay` binary against four VS Code Copilot events:

| Event              | When it fires                                           | Purpose                                        |
| ------------------ | ------------------------------------------------------- | ---------------------------------------------- |
| `UserPromptSubmit` | When the developer submits a prompt                     | Inspect prompt content                         |
| `PreToolUse`       | Before Copilot runs a tool (file write, terminal, etc.) | Inspect/intercept the action before it happens |
| `PostToolUse`      | After a tool runs                                       | Capture the result                             |
| `Stop`             | When the agent finishes responding                      | Capture the completed turn                     |

Every event runs the same command - `nightfall-hook-relay --source vscode_copilot` - with a **15-second timeout**. The relay binary is resolved by name on the system `PATH`, so the one config file works unchanged on both macOS and Windows.

```
{
  "hooks": {
    "UserPromptSubmit": [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ],
    "PreToolUse":       [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ],
    "PostToolUse":      [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ],
    "Stop":             [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ]
  }
}
```

***

### 2. Before you start

* **Nightfall endpoint agent is installed** on every target device. The agent auto-installs and keeps `nightfall-hook-relay` updated, and adds it to the system `PATH`. The hooks call the binary by name, so without the agent the hooks resolve to nothing.
* **MDM scope selected** - the device group / Blueprint / Smart Group / assignment that will receive the deployment.
* **VS Code + Copilot extension are reasonably current** on managed devices, and ideally **pinned** during the pilot (hooks are Preview).
* You have the pieces from this package for your platform: the **hook payload** (`payloads/nightfall.json`), the matching **policy source** (`payloads/nightfall-vscode-copilot.mobileconfig` on macOS, `payloads/hookFilesLocations.json` on Windows), and the **scripts** in `scripts/macos/` or `scripts/windows/`.

***

### 3. How the deployment works (two steps)

VS Code Copilot won't read the hook file unless `chat.hookFilesLocations` is set as an enterprise policy. So each device needs two things to happen:

1. **Drop the hook file** - the install script copies `nightfall.json` to a fixed file path.
2. **Set the policy** - the policy script registers that file path in `chat.hookFilesLocations` (a Configuration Profile on macOS, a registry policy on Windows).

Both the install scripts and the policy scripts are **idempotent**, so they're safe to wire to a recurring trigger.

#### File paths

| Platform | Staging path                                           | Hook file target (step 1)                                   |
| -------- | ------------------------------------------------------ | ----------------------------------------------------------- |
| macOS    | `/opt/nightfall/hooks/vscode/nightfall.json`           | `/Library/Application Support/Copilot/hooks/nightfall.json` |
| Windows  | <p>`C:\Nightfall\Hooks\vscode</p><p>ightfall.json`</p> | <p>`C:\ProgramData\Copilot\hooks</p><p>ightfall.json`</p>   |

#### Policy values (step 2)

| Platform | Policy mechanism                                         | What it sets                                                                                                        |
| -------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| macOS    | Configuration Profile (`com.microsoft.VSCode`)           | `chat.hookFilesLocations` → `/Library/Application Support/Copilot/hooks/nightfall.json`: `true`                     |
| Windows  | Registry under `HKLM\Software\Policies\Microsoft\VSCode` | <p><code>chat.hookFilesLocations</code> → `C:\ProgramData\Copilot\hooks</p><p>ightfall.json<code>: `true</code></p> |

> Both policy mechanisms are **additive**: macOS profile layering preserves other vendors'\
> Configuration Profiles for the `com.microsoft.VSCode` domain, and the Windows policy script\
> merges Nightfall's entry into any existing `chat.hookFilesLocations`. Nightfall never clobbers\
> another vendor's hook-file registration.

***

### 4. macOS setup

#### Step 1 - Stage the hook file

Deliver `payloads/nightfall.json` to `/opt/nightfall/hooks/vscode/nightfall.json` using your MDM's file-distribution or app-deployment feature (e.g. wrap the JSON in a `.pkg`, or use Workspace ONE's Files feature).

#### Step 2 - Drop the file into place

Wire `scripts/macos/install.sh` into your MDM as a **System-context** script. It:

1. Verifies it's running as root (exits early if not - deploy at System scope).
2. Confirms the staged payload exists.
3. Creates `/Library/Application Support/Copilot/hooks/` if needed.
4. Copies `nightfall.json` into place.

```
sudo ./scripts/macos/install.sh
```

#### Step 3 - Install the policy

Wire `scripts/macos/install-policy.sh` into your MDM (also System-context). It installs `payloads/nightfall-vscode-copilot.mobileconfig` via `sudo profiles install`, which sets `chat.hookFilesLocations` so Copilot reads the file dropped in Step 2. The profile uses a stable `PayloadIdentifier` (`ai.nightfall.hooks.vscode`), so re-installs update in place. Alternatively, on profile-aware MDMs (Jamf, Kandji, Workspace ONE), upload the `.mobileconfig` directly as a Configuration / Custom Settings Profile instead of running the script.

#### Drift checking (optional, recommended for Iru-style audit/remediation MDMs)

`scripts/macos/audit.sh` compares the deployed hook file against the staged payload **byte-for-byte** (`cmp -s`):

* Exit `0` > in sync, no action.
* Exit `1` > drift detected, run `install.sh` to remediate.

(If the staging file is missing, audit exits `0` to avoid a remediation loop it can't fix.) The policy install is naturally idempotent and can simply be re-run on any trigger.

***

### 5. Windows setup

#### Step 1 - Stage the hook file

Deliver `payloads/nightfall.json` to `C:\Nightfall\Hooks\vscode\nightfall.json` using your MDM's file-distribution feature (e.g. an `.msi` or `.intunewin`).

#### Step 2 - Drop the file into place

Wire `scripts/windows/install.ps1` into your MDM as a **SYSTEM-context** script. It:

1. Verifies it's running as administrator (exits early if not).
2. Confirms the staged payload exists.
3. Creates `C:\ProgramData\Copilot\hooks` if needed.
4. Copies `nightfall.json` into place.

```
powershell -ExecutionPolicy Bypass -File .\scripts\windows\install.ps1
```

#### Step 3 - Set the policy

Wire `scripts/windows/install-policy.ps1` into your MDM (also SYSTEM-context). It merges Nightfall's entry into `chat.hookFilesLocations` under `HKLM\Software\Policies\Microsoft\VSCode`, preserving any entries other vendors have already registered. The merged value mirrors `payloads/hookFilesLocations.json`.

Alternatively, import VS Code's ADMX template and set the policy via the Intune UI, or push the same value via an OMA-URI Custom Configuration Profile.

#### Drift checking (Intune Win32 Remediation pattern)

`scripts/windows/detect.ps1` compares the deployed hook file against the staged payload by **SHA256**:

* Prints `present`, exit `0` > in sync.
* Prints `staging-missing`, exit `0` > staging not deployed yet (no remediation loop).
* Exit `1` → drift, run `install.ps1` as the remediation.

The policy merge script is idempotent and can be re-run on any trigger.

***

### 6. Wiring into your MDM

The scripts are MDM-agnostic - the same scripts work regardless of vendor. Note that VS Code has **two install scripts per platform** (file drop + policy), so most rows below pair them:

| MDM              | Platform | Wire into                                    | Script                                                                                                              |
| ---------------- | -------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Rippling         | macOS    | Custom Script — file drop                    | `scripts/macos/install.sh`                                                                                          |
| Rippling         | macOS    | Custom Script — policy install               | `scripts/macos/install-policy.sh`                                                                                   |
| Rippling         | Windows  | PowerShell Script — file drop                | `scripts/windows/install.ps1`                                                                                       |
| Rippling         | Windows  | PowerShell Script — policy merge             | `scripts/windows/install-policy.ps1`                                                                                |
| Jamf Pro         | macOS    | Script + Policy — file drop                  | `scripts/macos/install.sh`                                                                                          |
| Jamf Pro         | macOS    | Script + Policy — policy install             | `scripts/macos/install-policy.sh` (or upload the `.mobileconfig` directly as a Configuration Profile)               |
| Kandji           | macOS    | Custom Script — Audit (file)                 | `scripts/macos/audit.sh`                                                                                            |
| Kandji           | macOS    | Custom Script — Remediation (file)           | `scripts/macos/install.sh`                                                                                          |
| Kandji           | macOS    | Custom Script — Policy install               | `scripts/macos/install-policy.sh` (or upload the `.mobileconfig` as a Kandji Custom Profile)                        |
| Microsoft Intune | Windows  | Win32 Remediation — Detection                | `scripts/windows/detect.ps1`                                                                                        |
| Microsoft Intune | Windows  | Win32 Remediation — Remediation              | `scripts/windows/install.ps1`                                                                                       |
| Microsoft Intune | Windows  | Custom Configuration Profile / ADMX — policy | `scripts/windows/install-policy.ps1` (or import VS Code's ADMX and set the policy via UI)                           |
| Workspace ONE    | macOS    | Script — file drop                           | `scripts/macos/install.sh`                                                                                          |
| Workspace ONE    | macOS    | Script — policy install                      | `scripts/macos/install-policy.sh` (or upload the `.mobileconfig` as a Custom Settings Profile)                      |
| Workspace ONE    | Windows  | Script — file drop                           | `scripts/windows/install.ps1`                                                                                       |
| Workspace ONE    | Windows  | Script — policy merge                        | `scripts/windows/install-policy.ps1` (or set OMA-URI under `HKLM\Software\Policies\Microsoft\VSCode` via a Profile) |

**Two drift strategies for the file drop:**

* **Re-run on a schedule** (Rippling / Jamf / Workspace ONE) - the install script is idempotent, so a periodic trigger simply re-copies the file. Simplest.
* **Audit/detect → remediate** (Kandji / Intune) - pair the audit/detect script with the install script so a re-install only fires when drift is detected.

The **policy scripts** are idempotent regardless of strategy (profile install updates in place via the stable `PayloadIdentifier`; registry merge re-applies the same entry), so wire them to the same trigger as the file drop.

***

### 7. Validation

After deployment, open the **Devices** page in the Nightfall console. Each device shows a per-client hook status indicator. A **healthy** status for VS Code Copilot means the hooks are registered and the relay is responding - the deployment is working.

On a single device you can also confirm:

* The hook file landed at the target path.
* `chat.hookFilesLocations` includes that path - check the installed Configuration Profile (macOS) or the registry key under `HKLM\Software\Policies\Microsoft\VSCode` (Windows).
* `nightfall-hook-relay` resolves on `PATH` (the endpoint agent provides it).

If the file is present but hooks don't fire, the **policy** is almost always the missing piece - Copilot silently ignores hook files at paths not listed in `chat.hookFilesLocations`.

***

### 8. Rollback

Remove **both** pieces; the relay binary stays installed (the Nightfall agent owns its lifecycle):

1. **Delete the hook file:**
   1. macOS: `/Library/Application Support/Copilot/hooks/nightfall.json`
   2. Windows: `C:\ProgramData\Copilot\hooks\nightfall.json`
2. **Remove the policy entry** for Nightfall's path from `chat.hookFilesLocations`:
   1. macOS: remove the `ai.nightfall.hooks.vscode` Configuration Profile.
   2. Windows: remove the Nightfall path entry under `HKLM\Software\Policies\Microsoft\VSCode` (leave other vendors' entries intact).

If you wired the install/policy scripts to a recurring trigger, remove those MDM assignments first — otherwise the next check-in will re-deploy.

***

### 9. Notes & known issues

* **VS Code Copilot hooks are Preview.** The configuration format and behavior may change. Pin to specific VS Code and Copilot extension versions during pilot.
* **Two-step deployment is mandatory.** Dropping the file without setting `chat.hookFilesLocations` does nothing — Copilot won't read an unregistered hook file. This is the most common cause of a "deployed but not working" report.
* **Multi-vendor coexistence.** Both policy mechanisms are additive - macOS profile layering and the Windows registry merge preserve other vendors' hook-file registrations. Nightfall adds a single path entry and never overwrites others.
* **Copilot CLI and Copilot coding agent (cloud) are out of scope** - hook coverage doesn't apply there.
* **Claude Code spillover into VS Code.** By default VS Code Copilot may also read `~/.claude/settings.json`. If you observe Claude's user-level hooks firing inside VS Code and want to suppress that, add `"~/.claude/settings.json": false` to the policy.


---

# 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-vs-code-copilot.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.
