Span Coding Hooks: IT Admin User Guide for Microsoft Intune
Last updated: July 6, 2026
This guide covers deploying Span Coding Hooks with Microsoft Intune to both macOS and Windows devices. Span ships a native package for each. Step 1 is shared; Steps 2–4 note the macOS and Windows specifics inline.
What This Package Does
Span Coding Hooks captures AI coding activity (prompts, file edits, tool use) from supported IDEs (currently Cursor, Claude Code, Codex CLI, Copilot CLI, and VSCode chat) and sends telemetry to Span's analytics backend. This data appears in your Span dashboard under AI Effectiveness.
Prerequisites
Before deploying, you need:
A Span account with access to integration settings.
A Microsoft Intune tenant with target devices enrolled and assigned to Entra groups.
The release artifact(s) from your Span account team:
coding-hooks-{version}.pkg(macOS) and/orcoding-hooks-{version}.msi(Windows).Each engineer's work email populated in Entra (the
mailattribute / UPN) — used to identify the individual on their device.macOS: devices on macOS 12.0+ with the Intune management agent installed.
Windows: Entra-joined Windows 10/11 devices with the Intune Management Extension present.
Windows — unsigned installer. The .msi is currently unsigned in all releases, so Windows may show a SmartScreen/Defender prompt and policies that require signed installers will block it. This is temporary and will be resolved shortly (Azure Trusted Signing). Pilot on an allowlisted group, or wait for the signed release, if your policy requires it.
Deployment Steps
The flow is the same on both platforms: deliver a config file with your token and the employee's email, then deploy the package. The config file uses one schema everywhere:
{ "span_auth_token": "<token>", "work_email": "<employee work email>" }
The token is shared org-wide; the work email is per-device.
Step 1: Enable the Integration and Get Your Token (this needs to be done once)
This step is the same regardless of your MDM.
Head to the AI tool settings dashboard (https://span.app/_/settings/integrations) and under IDE & CLI AI Tool Integrations, enable the tools your engineers use. Here is what each tool supports:
Tool | What's captured |
|---|---|
Claude Code | OTEL metrics + hooks |
Cursor | Hooks |
Codex CLI | OTEL metrics |
Copilot CLI | Hooks |
VSCode chat | Hooks |
Note: The Cursor, Copilot CLI, and VSCode chat integrations do not yet have a toggle in the dashboard. If your engineers use any of these, enable Claude Code or Codex CLI to generate the token — the token is shared across all tools and is required by the package regardless of which IDEs you are deploying for.
Once you enable a tool, you'll be able to access the token that you have to use to authenticate against our Otel backend:
Step 2: Deploy the Span Configuration File via MDM
The token is org-wide; the email is per-device. Deliver both so the config file exists before (or with) the package.
macOS — two parts:
Email: create a custom configuration profile (Devices → macOS → Configuration → Custom) whose
.mobileconfigwriteswork_email = {{mail}}into theapp.span.coding-hooksmanaged-preference domain. Intune substitutes each user's Entra email.Token + write config: add a shell script (Devices → macOS → Scripts), run as root, that writes
/Library/Application Support/app.span.coding-hooks/span-config.json(root:staff 0640) using your token and the email from step 1:
#!/bin/bash
set -euo pipefail
DIR="/Library/Application Support/app.span.coding-hooks"; FILE="$DIR/span-config.json"
TOKEN="__PASTE_SPAN_AUTH_TOKEN__"
EMAIL="$(/usr/bin/defaults read /Library/Managed\ Preferences/app.span.coding-hooks work_email)"
mkdir -p "$DIR"
printf '{\n "span_auth_token": "%s",\n "work_email": "%s"\n}\n' "$TOKEN" "$EMAIL" > "$FILE"
chown root:staff "$FILE"; chmod 0640 "$FILE"
Windows — add a PowerShell platform script (Devices → Scripts and remediations → Platform scripts → Windows), run as SYSTEM (not logged-on user), that writes %ProgramData%\Span\CodingHooks\span-config.json:
$ErrorActionPreference = "Stop"
$Token = "__PASTE_SPAN_AUTH_TOKEN__"
# Resolve the enrolled user's email (UPN). Adjust if your UPN and mail differ.
$Email = (Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Enrollments" -Recurse -EA SilentlyContinue |
Get-ItemProperty -EA SilentlyContinue | Where-Object UPN | Select-Object -First 1).UPN
if (-not $Email) { throw "Could not resolve work email." }
$Dir = Join-Path $env:ProgramData "Span\CodingHooks"; New-Item -ItemType Directory -Force $Dir | Out-Null
[pscustomobject]@{ span_auth_token = $Token; work_email = $Email } |
ConvertTo-Json | Set-Content (Join-Path $Dir "span-config.json") -Encoding utf8
Windows has no {{mail}} substitution for scripts, so the token and email are written in one script. If your UPN ≠ mail, replace the resolution line with your source of truth and confirm on a pilot device.
Step 3: Deploy the Package
Add the artifact as a line-of-business app (Apps → All apps → Create) and assign it Required to the same group as Step 2.
macOS: platform macOS → Line-of-business app, upload the
.pkg, set Minimum OS to macOS 12.0, and add a Logo (LOB apps without one don't appear in Company Portal). The.pkgis Developer ID–signed and notarized, satisfying Intune's requirement.Windows: platform Windows → Line-of-business app, upload the
.msi(no.intunewinwrapping needed). On install its bundledinstall.ps1reads the config and sets up the hooks, theSpanOtelCollectorservice, and theSpanRegistryPollertask. (Reminder: the MSI is unsigned for now — see the Prerequisites note.)
Step 4: Smoke Test (before fleet rollout)
Assign Steps 2–3 to 1–2 pilot devices first. Confirm the config-delivery step and the package both report success in Intune, then verify on-device (see below) before assigning to the fleet.
Verifying the Deployment
The installer runs a full health check at the end of every install.
To verify manually:
macOS
pkgutil --pkg-info app.span.coding-hooks
~/.span/bin/span-health
Windows
Get-Service SpanOtelCollector
& "$env:LOCALAPPDATA\Span\bin\hook-dispatcher.exe" span-health
A healthy check plus the device appearing in your Span dashboard confirms success.
Upgrading
Upload the new artifact to the existing LOB app (the Span app → Properties → App information → Edit → Select file to update). Existing assignments reinstall on the next check-in; user IDE configs are preserved.
Uninstalling
Assign the LOB app with the Uninstall intent on either platform. Removal reverses the service/task and preserves user-defined IDE configurations.
Troubleshooting
Symptom | Remediation |
|---|---|
Config holds a placeholder token | Re-run Step 2; confirm the real token is pasted into the script |
Missing / wrong work email | Populate the Entra |
macOS script never runs | Confirm the Intune agent at |
Windows MSI install fails | Signed-installer policy is blocking it — allowlist for the pilot, or wait for the signed release |
No data in dashboard | Check the collector service and run |
Support
For anything not covered here, contact your Span account team with the device OS, the failing step, and the output of span-health.
# Health check
~/.span/bin/span-health
# Installer log
cat /var/log/span-coding-hooks-install.log
# Config file — redact the token value before sharing
cat '/Library/Application Support/app.span.coding-hooks/span-config.json'