How can we help?

Rolling out LLM token tracking via MDM (overview)

Uri Nativ
Uri Nativ
  • Updated
Torii AI

The MDM path is the right rollout strategy for any fleet bigger than a small pilot. You upload the Torii install script to your MDM once, set one parameter (the ingest token), and target it at the right device group. From there your MDM handles delivery, retries, and inventory the same way it does every other script.

This article covers the workflow that's the same regardless of which MDM you use. For per-vendor field names (Jamf Parameter 4, Kandji script variables, Intune environment variables, etc.) see MDM vendor reference.

What you'll deploy

One script per (tool, OS) combination. From the AI Telemetry page in Torii, navigate to the tool you want to roll out, pick MDM rollout as the deployment method, and copy the script body. The script bytes shown in the UI are fetched live from https://assets.toriihq.com/otel/latest/<script-name> - they are always the latest, validated, published version.

Tool macOS Linux Windows
Claude Code install-claude-code-telemetry-macos.sh install-claude-code-telemetry-linux.sh install-claude-code-telemetry.ps1
Gemini CLI install-gemini-cli-telemetry-macos.sh install-gemini-cli-telemetry-linux.sh install-gemini-cli-telemetry.ps1
Codex CLI install-codex-cli-telemetry-macos.sh install-codex-cli-telemetry-linux.sh install-codex-cli-telemetry.ps1

You will deploy one script per CLI per OS that you support. If your fleet has all three CLIs across all three OSes, that's nine MDM policies. Most environments are smaller - Claude Code on macOS only, for example.

The one parameter every MDM needs

Each MDM has its own way of passing values to scripts. Torii's install scripts accept the ingest token in three flexible ways - your MDM only needs to support one of them. (The OTLP endpoint https://ai-events.toriihq.com is baked into every script body - there is no endpoint parameter to configure.)

  1. Command-line flag - --token <token> on the script invocation. Works everywhere; the most explicit form.
  2. Environment variable - TORII_TOKEN (the legacy un-prefixed TOKEN still works, but prefer the namespaced name - it can’t collide with an unrelated TOKEN already in the environment). Used by Workspace ONE, which exposes script variables as real shell env vars (the Windows .ps1 installers also read $env:TORII_TOKEN). Note that JumpCloud is not in this group: its Command Variables are {{name}} placeholders substituted into the command body, not env vars - use the dedicated -jumpcloud script variants, which ship with the TORII_TOKEN variable reference already baked in (see the MDM vendor reference). For Kandji, Mosyle, and Intune on macOS - which have neither mechanism - Torii ships per-MDM install scripts with the values pre-baked. See the MDM vendor reference.
  3. Jamf positional parameter - $4 = token. Jamf Pro convention only; inert on every other MDM. (Legacy policies that set $4 = endpoint and $5 = token keep working - the script treats a URL in $4 as an endpoint override.)

The script auto-detects which form your MDM used.

Value to pass

  • TOKEN = the ingest token from your AI Telemetry page. Copy the unmasked value from the Credentials card.

Configure it as a parameter of the MDM policy, not as a value baked into the script body. This matters for token rotation later - when you rotate the token, you'll update one parameter in your MDM rather than re-uploading scripts to every policy. (The Kandji/Mosyle/Intune-macOS pre-filled variants are the exception - those embed the token in the script body, so rotation means re-downloading the file.)

The standard 3-step MDM flow

Step 1 - Upload the script

Create a new script in your MDM. Paste the script body from the AI Telemetry page. Set the script language (bash or PowerShell), the run-as identity (root on macOS/Linux, SYSTEM or user on Windows depending on MDM convention), and the run frequency.

Step 2 - Configure the token parameter

Set TOKEN using your MDM's script-parameter mechanism. The exact field name varies per vendor - Article 6 has them.

Step 3 - Target and deploy

Point the policy at the right device group and pick a trigger:

  • For user-scope installs (Linux and Windows for all three tools; macOS for Gemini and Codex) - run on login + recurring check-in. The script writes to the signed-in user's home directory, so it runs once per user per computer.
  • For system-scope installs (macOS Claude Code only) - run on enrollment + recurring check-in. The script writes a system-wide file (/Library/Application Support/ClaudeCode/managed-settings.d/10-torii-otel.json) that applies to every user on the Mac, so it runs once per Mac.

The install script is idempotent - re-running it produces the same end state. You don't need to worry about "did this run already on this machine?"; running again is safe.

What the script does on each machine

For each tool, the install script:

  1. Validates that a token was provided (the endpoint is baked into the script).
  2. Resolves the target user (when running as root) or uses the calling user.
  3. Renders the desired config and compares it with what’s on disk - only the Torii-owned telemetry keys are written, and only when something actually changed; unrelated settings in the file are preserved.
  4. If the run will change the file, first creates a timestamped backup: <file>.ai-otel-backup-YYYYMMDD-HHMMSS. A re-run that changes nothing skips both the write and the backup.
  5. Writes the telemetry config block.
  6. Prints a one-line summary to stdout.

For the full deep dive on what each install script writes, including the exact env vars, see What the install scripts do.

Backups

Any run that changes the target file first creates a backup next to it:

  • Claude Code: ~/.claude/settings.json.ai-otel-backup-YYYYMMDD-HHMMSS
  • Gemini CLI: ~/.gemini/settings.json.ai-otel-backup-YYYYMMDD-HHMMSS
  • Codex CLI: ~/.codex/config.toml.ai-otel-backup-YYYYMMDD-HHMMSS

(The Claude Code system-scope target on macOS is /Library/Application Support/ClaudeCode/managed-settings.d/10-torii-otel.json and gets a backup at the same path.)

The path of each backup file is printed to stderr (backup: <path>) immediately after it's created - useful when collecting script output through MDM agent logs.

Re-runs that change nothing - the steady state for a recurring MDM policy - skip both the write and the backup, so the policy itself doesn't accumulate backups. You'll see one backup per actual change: the first install, a token rotation, a script update. The install script never deletes existing backups (every change stays recoverable); sweep older ones via a separate MDM script if you'd like.

Token rotation does not require a script redeploy

When you rotate the ingest token in Torii (see Rotating your LLM token tracking ingest token), update the TOKEN parameter on each MDM policy and the next time the script runs, the new token is written. You do not need to re-upload the script.

The previous token stays valid for 24 hours after rotation, which gives every MDM policy time to fire on its normal schedule.

Air-gapped Linux fleets

The Linux installers for Claude Code and Gemini CLI fetch a small Go helper (ai-otel-helper, ~1 MB) from assets.toriihq.com at install time. (This is because stock Linux doesn't ship a built-in JSON parser; the helper is statically linked, has no external dependencies, and is SHA256-verified against a sidecar file before use.) The macOS and Windows installers do not download anything at install time.

If your Linux fleet can't reach assets.toriihq.com directly:

  1. Download the helper artifacts to a machine that has internet access:
    • https://assets.toriihq.com/otel/latest/helper/linux-amd64.gz
    • https://assets.toriihq.com/otel/latest/helper/linux-amd64.gz.sha256
    • https://assets.toriihq.com/otel/latest/helper/linux-arm64.gz
    • https://assets.toriihq.com/otel/latest/helper/linux-arm64.gz.sha256
  2. Host the files on an internal HTTPS mirror at a stable path, e.g. https://your-mirror.example.com/torii-otel/helper/linux-amd64.gz (and the corresponding sha256 file).
  3. Pass HELPER_BASE_URL as a second parameter to your MDM policy, with value https://your-mirror.example.com/torii-otel (the script appends /helper/linux-<arch>.gz).

Refresh your mirror when Torii ships a new helper version (quarterly cadence at most). The script will detect a checksum mismatch and refuse to run, so a stale mirror is loud, not silent.

Codex CLI vs the rest - one less moving part

Codex CLI's config is TOML, and the Codex installer uses pure awk on a marker-delimited block - no helper download is needed on any OS. The block is delimited by # BEGIN AI_OTEL_MANAGED / # END AI_OTEL_MANAGED comments, which the uninstall script later uses to surgically remove just the Torii-managed portion without touching anything else in your config.toml.

Detect / compliance scripts

For MDMs that support a separate "detect" or "compliance" check (Intune is the main one - exit 0 with non-empty stdout = compliant, exit 1 = not compliant), Torii ships matching detect scripts:

  • detect-claude-code-telemetry-linux.sh / -macos.sh / .ps1
  • detect-gemini-cli-telemetry-linux.sh / -macos.sh / .ps1
  • detect-codex-cli-telemetry-linux.sh / -macos.sh / .ps1

All three validate against the production endpoint https://ai-events.toriihq.com by default; pass --endpoint <url> only if your fleet points at a relay or staging endpoint. Pair them with the matching install script to create a self-healing compliance policy.

Next steps

Was this article helpful?

0 out of 0 found this helpful

Have more questions? Submit a request