> 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

Deploy Nightfall hooks for VS Code and GitHub Copilot by copying a hook file into each user's Copilot hooks folder.

Deploy Nightfall's GitHub Copilot hooks to corporate-managed devices with your MDM. Download the VS Code / Copilot bundle from **AI Agent Security** setup in the Nightfall console. The `README.md` in that zip matches this page.

This page is VS Code and GitHub Copilot only. Claude Code and Cursor each have their own guide under Setup & Installation.

{% hint style="info" %}
VS Code Copilot hooks are **Preview**. Pin VS Code and the Copilot extension during a pilot.

Copilot reads hook files from each user's `~/.copilot/hooks` folder. This deployment copies `nightfall.json` into that folder. It does not set a VS Code policy, a configuration profile, or a Windows registry value.
{% endhint %}

### What this covers

One `nightfall.json` in `~/.copilot/hooks/` covers:

* **VS Code Copilot**, including the built-in agent and Copilot CLI mode
* **JetBrains IDEs** (GoLand, IntelliJ, and others) when the developer is in **Copilot CLI mode**
* **The standalone GitHub Copilot CLI**

JetBrains in Local (native) agent mode reads hooks only from a per-repository `.github/hooks/` directory, so an MDM file drop cannot cover it. The Copilot cloud coding agent runs on GitHub's servers, and local hooks do not apply there.

### What gets deployed

The bundle registers `nightfall-hook-relay` on four Copilot events. Each event uses a 15-second timeout.

| Event              | When it fires                                                 | What Nightfall does                                                          |
| ------------------ | ------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `UserPromptSubmit` | The developer submits a prompt                                | Inspect the prompt                                                           |
| `PreToolUse`       | Before Copilot runs a tool (file write, terminal, and others) | Inspect the action before it runs                                            |
| `PostToolUse`      | After a tool runs                                             | Record the result. Monitor only. VS Code Copilot cannot replace tool output. |
| `Stop`             | The agent finishes responding                                 | Record the completed turn                                                    |

The payload includes `"version": 1`. VS Code ignores that field. The Copilot CLI requires it, so the same file works on every surface this bundle covers.

Hooks are on by default in VS Code. This deployment does not change a VS Code setting to turn them on.

{% hint style="warning" %}
On Windows, stage `payloads/nightfall.windows.json` and save it on the device as `nightfall.json`. The macOS file uses shell syntax that Windows PowerShell 5.1 cannot run. `install.ps1` refuses that file. If the macOS file is what lands on a Windows device, the relay never starts, and the Devices page shows no Copilot hook activity.
{% endhint %}

On Windows the hook command is a single executable and its arguments:

```
nightfall-hook-relay --source vscode_copilot
```

That form runs under both Git Bash and Windows PowerShell. Deploy the Nightfall agent and this payload to the same devices. Until the agent is installed, Windows reports a non-blocking error on each event. It does not block the developer.

### Before you start

1. **Nightfall endpoint agent** installed and running. The agent installs `nightfall-hook-relay`, keeps it updated, and adds it to PATH. The hooks call that binary by name. The agent installer does not write `nightfall.json`.
2. **An MDM scope**: the device group, Blueprint, Smart Group, or assignment that will receive this deployment.
3. **A current VS Code and Copilot extension** on managed devices. Pin both during the pilot.
4. **This package**, including `payloads/nightfall.json` (macOS), `payloads/nightfall.windows.json` (Windows), and the scripts for the platform you are deploying.

### How deployment works

Two steps, in order. The install script only reads a fixed staging path. Your MDM has to place the payload there first.

|                        | macOS                                                                           | Windows                                                                                                       |
| ---------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| File in the zip        | `payloads/nightfall.json`                                                       | `payloads/nightfall.windows.json`                                                                             |
| Stage it as            | `/opt/nightfall/hooks/vscode/nightfall.json`                                    | `C:\Nightfall\Hooks\vscode\nightfall.json`                                                                    |
| Install script         | `scripts/macos/install.sh`, as root                                             | `scripts/windows/install.ps1`, as SYSTEM                                                                      |
| Where Copilot reads it | `~/.copilot/hooks/nightfall.json`                                               | `%USERPROFILE%\.copilot\hooks\nightfall.json`                                                                 |
| New user accounts      | Covered on the next run of `install.sh`. Schedule it (daily is a good default). | Also written to `C:\Users\Default\.copilot\hooks\nightfall.json`, so a new profile inherits it at first logon |

On VS Code 1.126.0, `~/.copilot/hooks` is already one of Copilot's default hook locations, so the copied file is picked up with no settings change. Microsoft's settings reference does not list that folder. Re-check after a major VS Code upgrade.

If the staging file is missing, `install.sh` and `install.ps1` exit 1 and log the path they expected.

### macOS

#### 1. Stage the file

Deliver `payloads/nightfall.json` to `/opt/nightfall/hooks/vscode/nightfall.json`. Wrap it in a `.pkg`, or use your MDM's file distribution (Workspace ONE Files can target that path directly).

```bash
mkdir -p pkgroot/opt/nightfall/hooks/vscode
cp payloads/nightfall.json pkgroot/opt/nightfall/hooks/vscode/

pkgbuild \
  --root pkgroot \
  --identifier ai.nightfall.hooks.vscode \
  --version 1.0 \
  --install-location / \
  Nightfall-Copilot-Hooks.pkg
```

Upload the `.pkg` to Jamf, Kandji, or Workspace ONE, scoped to the same group as `install.sh`. If the package must be signed, add `--sign "Developer ID Installer: Your Org (TEAMID)"` and notarize it.

#### 2. Run the install script

Wire `scripts/macos/install.sh` as a System-context script, on enrollment and on a recurring schedule. It copies the staged file to `~/.copilot/hooks/nightfall.json` for each real user (it skips `Shared` and system accounts), and sets ownership to that user. Running it again replaces the file and picks up new accounts.

#### 3. Drift check (Kandji)

`scripts/macos/audit.sh` compares each user's file to the staged payload.

* Exit 0: in sync, or the staging file is not there yet. Do nothing.
* Exit 1: a user is missing the file, or the file changed. Run `install.sh`.

### Windows

#### 1. Stage the file

Deliver `payloads/nightfall.windows.json` to `C:\Nightfall\Hooks\vscode\nightfall.json`. The staged name is `nightfall.json`. The file you copy from the zip is `nightfall.windows.json`.

#### 2. Run the install script

Wire `scripts/windows/install.ps1` as a SYSTEM-context script, on enrollment and on a recurring schedule. It copies the staged file to `%USERPROFILE%\.copilot\hooks\nightfall.json` for each real user, and to `C:\Users\Default\.copilot\hooks\nightfall.json` for new profiles. Running it again replaces the file.

#### 3. Drift check (Intune)

`scripts/windows/detect.ps1` compares each profile's file to the staged payload by SHA256.

* Exit 0, output `present`: in sync.
* Exit 0, output `staging-missing`: the staging file is not deployed yet. Intune will not loop.
* Exit 0, output `unix-payload-staged`: the macOS file was staged. Replace it with `nightfall.windows.json`, saved as `nightfall.json`, then run `install.ps1`.
* Exit 1: a profile is missing the file, or the file changed. Run `install.ps1`.

### Microsoft Intune

Use two Intune assignments. The first places the staging file. The second copies it into each user profile. There is no configuration profile and no registry policy.

#### Assignment 1: stage the payload (Win32 app)

In a source folder, place `nightfall.windows.json` next to `stage.cmd`:

```bat
md "C:\Nightfall\Hooks\vscode" 2>nul
copy /Y "%~dp0nightfall.windows.json" "C:\Nightfall\Hooks\vscode\nightfall.json"
```

Package that folder with Microsoft's Win32 Content Prep Tool:

```
IntuneWinAppUtil.exe -c <sourceFolder> -s stage.cmd -o <outputFolder>
```

In Intune, go to **Apps → Windows → Add → Windows app (Win32)** and upload the package.

* **Install command:** `stage.cmd`
* **Uninstall command:** `cmd /c if exist "C:\Nightfall\Hooks\vscode\nightfall.json" del /f /q "C:\Nightfall\Hooks\vscode\nightfall.json"`
* **Install behavior:** System
* **Detection rule:** File. Path `C:\Nightfall\Hooks\vscode`, file `nightfall.json`, method File or folder exists.

#### Assignment 2: copy the file to each user (Remediation)

Create a remediation script package from the same zip.

* **Detection script:** `scripts/windows/detect.ps1`
* **Remediation script:** `scripts/windows/install.ps1`
* **Run as:** System

Use the exit codes in the drift check above. Deploy the agent before or with these assignments. Hook files can be present before the agent is, and they start firing once `nightfall-hook-relay` is on PATH.

### Other MDMs

| MDM           | Platform | Wire into                                            | Script                        |
| ------------- | -------- | ---------------------------------------------------- | ----------------------------- |
| Rippling      | macOS    | Custom script, enrollment and daily                  | `scripts/macos/install.sh`    |
| Rippling      | Windows  | PowerShell script, enrollment and recurring          | `scripts/windows/install.ps1` |
| Jamf Pro      | macOS    | Policy and script, enrollment and recurring check-in | `scripts/macos/install.sh`    |
| Kandji        | macOS    | Custom script, audit                                 | `scripts/macos/audit.sh`      |
| Kandji        | macOS    | Custom script, remediation                           | `scripts/macos/install.sh`    |
| Workspace ONE | macOS    | Script, enrollment and periodic                      | `scripts/macos/install.sh`    |
| Workspace ONE | Windows  | Script, enrollment and periodic                      | `scripts/windows/install.ps1` |

Rippling, Jamf, and Workspace ONE should re-run the install script. It is safe to run repeatedly: it replaces each user's file and covers accounts added since the last run. Kandji and Intune should run the install script only when the audit or detect script exits 1.

{% hint style="warning" %}
`audit.sh` and `detect.ps1` exit 0 when nothing should change. A Rippling pre-install check does the opposite: it installs when the check exits 0. Do not put `audit.sh` or `detect.ps1` in front of a Rippling, Jamf, or Workspace ONE install. Point those MDMs at `install.sh` or `install.ps1` directly.
{% endhint %}

If your MDM cannot write the staging path above, change `STAGING` at the top of `install.sh` and `audit.sh`, or `$staging` at the top of `install.ps1` and `detect.ps1`, so all four scripts use the same path.

### Confirm the install

On a device:

* macOS: `ls -l ~/.copilot/hooks/nightfall.json`
* Windows: `dir %USERPROFILE%\.copilot\hooks\nightfall.json`

On the **Devices** page, a healthy VS Code Copilot status means a hook event arrived in the last 72 hours. A device can show **Not configured** after a correct install until someone uses Copilot on it. Confirm the file on disk first. Then have a developer start a Copilot agent turn, and confirm the Last-event time moves.

The same conditions below can leave the file in place while no events arrive. Check them before treating a quiet device as a failed install.

### When the file is installed and hooks still do not run

| Condition                                                         | What happens                                          | Where to look                                                                                                                                                                                   |
| ----------------------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ChatHooks` is set to false                                       | VS Code ignores every hook file                       | macOS: `ChatHooks` in `/Library/Managed Preferences/com.microsoft.VSCode.plist`. Windows: the VS Code policy in Group Policy or the registry. `install.sh` prints a warning when it finds this. |
| Copilot preview features are disabled for the GitHub organization | Forces hooks off, even with no MDM policy of your own | GitHub organization Copilot policies                                                                                                                                                            |
| The workspace is not trusted                                      | Hooks are skipped in that folder                      | The workspace-trust banner in VS Code. Trust the folder.                                                                                                                                        |

A `ChatHooks` value of false is an existing policy. Remove it or set it to true. This bundle does not set it.

### Copilot CLI on a machine-wide path (optional)

VS Code does not read this location. Use it only when the standalone Copilot CLI, or JetBrains in Copilot CLI mode, is the main surface and you want one machine-wide file in addition to the per-user copy.

| Platform | Directory                                                                                      |
| -------- | ---------------------------------------------------------------------------------------------- |
| macOS    | `/etc/github-copilot/policy.d/nightfall.json` from `payloads/nightfall.json`                   |
| Windows  | `C:\ProgramData\GitHub\Copilot\policy.d\nightfall.json` from `payloads/nightfall.windows.json` |

Policy hooks load before other sources, stay on when a user disables hooks, and run whether or not the folder is trusted. On Windows, put the Windows payload in that directory. The macOS file will not run there.

### Remove the hooks

Remove the MDM assignment first when the install script is on a schedule. The next check-in would copy the file back. The relay binary stays installed. The Nightfall agent owns it.

Delete `nightfall.json` from:

* macOS: `/Users/*/.copilot/hooks/`
* Windows: `C:\Users\*\.copilot\hooks\` and `C:\Users\Default\.copilot\hooks\`

If you also deployed the optional CLI policy file, delete that copy too.

### Notes

* Events from VS Code, JetBrains CLI mode, and the standalone Copilot CLI are reported as VS Code Copilot.
* VS Code can also read `~/.claude/settings.json`, but that behavior is off unless `chat.useClaudeHooks` is enabled. Leave it off unless you intend Claude Code user hooks to run inside Copilot.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
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>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
