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/or coding-hooks-{version}.msi (Windows).

  • Each engineer's work email populated in Entra (the mail attribute / 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:

  1. Email: create a custom configuration profile (Devices → macOS → Configuration → Custom) whose .mobileconfig writes work_email = {{mail}} into the app.span.coding-hooks managed-preference domain. Intune substitutes each user's Entra email.

  2. 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 .pkg is Developer ID–signed and notarized, satisfying Intune's requirement.

  • Windows: platform Windows → Line-of-business app, upload the .msi (no .intunewin wrapping needed). On install its bundled install.ps1 reads the config and sets up the hooks, the SpanOtelCollector service, and the SpanRegistryPoller task. (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 mail attribute; on Windows adjust the UPN→mail resolution

macOS script never runs

Confirm the Intune agent at /Library/Intune/Microsoft Intune Agent.app; user opens Company Portal → Check settings

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 span-health


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'