> For the complete documentation index, see [llms.txt](https://docs.threatdefence.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.threatdefence.com/endpoint-agent/installation-guides/mac-os-mdm.md).

# Mac OS MDM

## TD Endpoint Agent for macOS — MDM Deployment

Deploy the TD Endpoint Agent to macOS devices via any MDM using two configuration profiles and one install script.

### Artifacts

<table><thead><tr><th width="401.99609375">Artifact</th><th>Delivered via</th><th>Purpose</th></tr></thead><tbody><tr><td><p><code>TDAgent-FDA-PPPC.mobileconfig</code></p><div data-gb-custom-block data-tag="file" data-src="https://4191868192-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOlFHF8fl339QOw3Og8L7%2Fuploads%2Fgit-blob-fcc8becb817270b567ba0d01d98fc27b142e991e%2FTDAgent-FDA-PPPC.mobileconfig?alt=media"></div></td><td>MDM custom profile</td><td>Full Disk Access for the agent</td></tr><tr><td><p><code>TDAgent-ActivationCode.mobileconfig</code></p><div data-gb-custom-block data-tag="file" data-src="https://4191868192-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOlFHF8fl339QOw3Og8L7%2Fuploads%2Fgit-blob-5eebba3e367e8bc2f961eb26a4828d367072e5b7%2FTDAgent-ActivationCode.mobileconfig?alt=media"></div></td><td>MDM custom profile</td><td>Activation code as a managed preference</td></tr><tr><td><code>TD_Endpoint_MacOS_Silicon.dmg</code></td><td>Script / command</td><td>Installer app</td></tr></tbody></table>

### Order

1. Push the FDA profile.
2. Push the activation-code profile. **Important:** before uploading, open `TDAgent-ActivationCode.mobileconfig` in a text editor and replace `REPLACE_WITH_ACTIVATION_CODE` with the tenant's activation code.
3. Run the install script.

Confirm both profiles landed (`sudo profiles show`) before installing. No profile

* no code passed to the script = installer exits `2`.

### Install script

MDM stages the DMG on the device; script mounts, installs, copies the app to `/Applications`, cleans up. Set `DMG` to the staged path.

```bash
#!/bin/bash
# Run as root.
set -uo pipefail

DMG="/tmp/TD_Endpoint_MacOS_Silicon.dmg"   # match the MDM's file destination
ACTIVATION_CODE=""   # empty -> uses the managed-preference profile
AUTO_UPDATE=""       # "no" to disable auto-update; empty = enabled

if [ -x /opt/TDAgent/tdcli/tdcli.bin ]; then
    /opt/TDAgent/tdcli/tdcli.bin version 2>/dev/null || true
    exit 0
fi

[ -s "$DMG" ] || { echo "ERROR: DMG not found at $DMG" >&2; exit 20; }

MP=$(hdiutil attach -nobrowse -noverify -readonly "$DMG" \
       | awk -F'\t' '/\/Volumes\//{print $NF}' | tail -1)
[ -z "$MP" ] && { echo "ERROR: failed to mount DMG" >&2; exit 21; }
trap 'hdiutil detach "$MP" -quiet 2>/dev/null || true' EXIT

APP=$(find "$MP" -maxdepth 1 -name "*.app" -print -quit)
BIN="$APP/Contents/MacOS/TDAgentInstaller"
[ -x "$BIN" ] || { echo "ERROR: TDAgentInstaller not found at $BIN" >&2; exit 22; }

ARGS=(--headless)
[ -n "$ACTIVATION_CODE" ] && ARGS+=(--activation-code "$ACTIVATION_CODE")
[ -n "$AUTO_UPDATE" ]     && ARGS+=(--auto-update "$AUTO_UPDATE")
"$BIN" "${ARGS[@]}"
RC=$?
echo "TDAgentInstaller exit code: $RC"

if [ "$RC" -eq 0 ]; then
    DEST="/Applications/$(basename "$APP")"
    rm -rf "$DEST"
    ditto "$APP" "$DEST"
fi
exit $RC
```

### Exit codes

| Code  | Meaning                                          |
| ----- | ------------------------------------------------ |
| 0     | Installed (or already installed)                 |
| 1     | Not root                                         |
| 2     | No activation code found                         |
| 3     | Installer payload missing from bundle            |
| 4     | Install reported success but agent binary absent |
| 20    | (script) DMG not found                           |
| 21    | (script) DMG failed to mount                     |
| 22    | (script) installer binary not found              |
| other | From the underlying installer                    |

### Verify

```bash
sudo /opt/TDAgent/tdcli/tdcli.bin version
sudo launchctl list | grep -E 'com.tdagent|com.threatdefence|com.velocidex'

# Logs should start populating here. If not, check that the Full Disk Access profile has been added.
tail -f /var/log/tdagent/tdagent_events.json
```

### Notes

* Idempotent: re-run exits 0 without reinstalling.
* Auto-update: default on. Disable at install with `--auto-update no`, or later with `tdcli.bin disable-autoupgrade`.
* Uninstall: `sudo /opt/TDAgent/tdcli/tdcli.bin uninstall`.
* Logs: `/var/log/tdagent/`.
* Test on one Mac before scoping to the fleet.


---

# 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://docs.threatdefence.com/endpoint-agent/installation-guides/mac-os-mdm.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.
