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-relayupdated, and adds it to the systemPATH. 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.mobileconfigon macOS,payloads/hookFilesLocations.jsonon Windows), and the scripts inscripts/macos/orscripts/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:
Drop the hook file - the install script copies
nightfall.jsonto a fixed file path.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
`C:\Nightfall\Hooks\vscode
ightfall.json`
`C:\ProgramData\Copilot\hooks
ightfall.json`
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
chat.hookFilesLocations → `C:\ProgramData\Copilot\hooks
ightfall.json: `true
Both policy mechanisms are additive: macOS profile layering preserves other vendors' Configuration Profiles for the
com.microsoft.VSCodedomain, and the Windows policy script merges Nightfall's entry into any existingchat.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:
Verifies it's running as root (exits early if not - deploy at System scope).
Confirms the staged payload exists.
Creates
/Library/Application Support/Copilot/hooks/if needed.Copies
nightfall.jsoninto place.
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, runinstall.shto 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:
Verifies it's running as administrator (exits early if not).
Confirms the staged payload exists.
Creates
C:\ProgramData\Copilot\hooksif needed.Copies
nightfall.jsoninto place.
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, exit0> in sync.Prints
staging-missing, exit0> staging not deployed yet (no remediation loop).Exit
1→ drift, runinstall.ps1as 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.hookFilesLocationsincludes that path - check the installed Configuration Profile (macOS) or the registry key underHKLM\Software\Policies\Microsoft\VSCode(Windows).nightfall-hook-relayresolves onPATH(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):
Delete the hook file:
macOS:
/Library/Application Support/Copilot/hooks/nightfall.jsonWindows:
C:\ProgramData\Copilot\hooks\nightfall.json
Remove the policy entry for Nightfall's path from
chat.hookFilesLocations:macOS: remove the
ai.nightfall.hooks.vscodeConfiguration Profile.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.hookFilesLocationsdoes 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": falseto the policy.
Last updated
Was this helpful?