> ## Documentation Index
> Fetch the complete documentation index at: https://hilt.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy via MDM

> Zero-click fleet rollout of the Hilt macOS Collector through Jamf, Kandji, Intune, or any MDM that accepts a custom profile: push the signed .pkg, then upload one generated profile (or build the payloads by hand) to auto-approve the System Extension and pre-grant Full Disk Access, with no end-user interaction.

## Overview

The Hilt macOS Collector ships as a notarized macOS app, **Hilt EDR** (`Hilt.app`, bundle id `Hilt.EDRApp`, team **Cybe Corporation / MVMB6LCP2A**), that embeds two Apple System Extensions:

| Extension | Type | Bundle id | Role |
| :- | :- | :- | :- |
| ESensor | Endpoint Security (ES) | `Hilt.EDRApp.ESensor` | Telemetry sensor: process / file / network / persistence events |
| NetFilter | NetworkExtension content filter | `Hilt.EDRApp.NetFilter` | Per-flow network attribution |

There is **no kernel extension**. Both are pure user-space System Extensions on Apple's modern frameworks, and the collector runs with **System Integrity Protection (SIP) enabled** on a normal, hardened Mac. See [Networking and trust model](https://hilt.ai/docs/macos-collector/networking-security.md) for the full signing and entitlement story.

On an unmanaged Mac, an Endpoint Security product requires two user consents that cannot be click-suppressed without an MDM: approving the System Extension and granting Full Disk Access. The [direct-download path](https://hilt.ai/docs/macos-collector/deploy-standalone.md) walks the user through both. **Under MDM you remove both prompts** by pushing two configuration profiles alongside the app, making enrollment a silent, zero-touch install.

This page covers the three pieces of an MDM rollout:

1. **App delivery.** Deploy the signed `.pkg` to the fleet.
2. **System Extensions payload.** Auto-approve the embedded extensions so no approval prompt appears.
3. **PPPC (Privacy) payload.** Pre-grant Full Disk Access so no FDA prompt appears.

Pieces 2 and 3 can be obtained two ways. The **console generates both as a single profile** for you, already carrying your deployment's ingest endpoint. That is the recommended route, described under *The generated profile* below. If you would rather author the payloads natively in your MDM's own UI, Pieces 2 and 3 below give the exact keys and values.

> [!NOTE]
>
> The macOS collector is **early access**. The notarized `.pkg` plus SIP-on install described here is the target shipping model. On-device quarantine response is not yet available on macOS; the collector itself stays current through its signed, per-deployment update channel once installed.

## Enrollment prerequisites

Both profiles must reach the Mac **through the MDM it is enrolled in**. A profile installed by double-click applies its other payloads, but macOS silently ignores manually installed TCC grants.

| Profile | What it does | Minimum enrollment |
| :- | :- | :- |
| System Extensions (`com.apple.system-extension-policy`) | Pre-approves the extension, so no approval prompt | **User-Approved MDM (UAMDM)** |
| PPPC (`com.apple.TCC.configuration-profile-policy`) | Pre-grants Full Disk Access, so no FDA prompt | **User-Approved MDM (UAMDM)**, device channel. ADE is **not** required — see below. |

* **UAMDM** is any MDM enrollment the user approved — an enrollment URL, your MDM's enrollment app — or an ADE enrollment, where approval is automatic.
* **Supervision**, which Apple's documentation attaches to the PPPC payload, is automatic on **macOS 11 and later** for every Mac enrolled through Device Enrollment, *including ordinary user-initiated enrollment*. Every macOS version this collector supports is past that line, so on any MDM-enrolled fleet the Full Disk Access grant applies silently at check-in. **Automated Device Enrollment (ABM/ADE) is not a prerequisite** — what ADE removes is the enrollment click itself, not an FDA toggle.
* The one enrollment mode that does **not** carry the PPPC payload is account-driven **User Enrollment** (the BYOD mode). Macs enrolled that way need one manual FDA toggle per host.

| Mac state | System Extension approval | Full Disk Access | User actions |
| :- | :- | :- | :- |
| Unmanaged (direct download) | one click | one toggle | \~2 clicks + 1 password |
| MDM-enrolled (user-initiated or ADE) | auto (silent) | auto (silent) | **zero** |

## The generated profile

The Hilt console builds a complete, ready-to-upload `.mobileconfig` for you. In the dashboard go to **Collectors → Add Collector → macOS**, where you will find two things: the signed `.pkg` download (Piece 1) and, beside it, **MDM config**. Opening MDM config lets you pick how much the agent observes, optionally name the device group the profile is for, then generate and download the file as `hilt-<group>.mobileconfig`.

> [!NOTE]
>
> **MDM config** appears in consoles running release **0.22 or later**. On an older console the button is not present — author Pieces 2 and 3 below natively in your MDM instead; they are the same payloads the generator emits.

A generated profile always contains the two payloads this page documents as Pieces 2 and 3, the System Extensions allowlist and the PPPC Full Disk Access grant, so uploading it covers both. Depending on the monitoring level you choose it also carries browser policy for Chrome and Edge, and an Input Monitoring entry for clipboard paste attribution.

It additionally carries a **managed-preference payload** in the `ai.hilt.edr` domain, which the hand-built payloads below cannot give you. This is what ties the profile to your specific deployment: it writes the collector ingest URL and client identifier that this tenant's agents should report to, so a Mac that receives the profile is pointed at your environment rather than falling back to a compiled-in default. If you build payloads natively in your MDM instead, you are responsible for pointing the agent at the right endpoint by other means.

**1. Generate the profile**

**Collectors → Add Collector → macOS → MDM config**. Choose a monitoring level, name the device group if you plan to run more than one policy, then generate and download.

**2. Upload it as a custom profile**

Every MDM has a route for uploading a `.mobileconfig` that its own UI does not model, commonly labelled *custom profile*, *custom settings*, or *upload profile*. Use that route, then scope the profile to the device group you generated it for. MDMs that prefer to author payloads natively can still use Pieces 2 and 3 below instead.

**3. Regenerate freely**

Every generated profile shares one `PayloadIdentifier` (`ai.hilt.edr.deploy`). A Mac that receives a new one sees an **update to the profile it already has**, never a second profile stacked beside the first. Changing your mind about monitoring level is therefore safe: regenerate, re-upload, and the old policy is replaced in place.

> [!NOTE]
>
> The generated profile does not change the delivery requirement above: it must be pushed by your MDM. Delivered to a device-enrolled (UAMDM) fleet, it applies the extension approvals and the Full Disk Access grant silently. The same file double-clicked by a user installs the other payloads but grants no TCC.

> [!WARNING]
>
> If you enable clipboard paste attribution, macOS will ask the user for **Input Monitoring** once. Apple does not allow any MDM to grant Input Monitoring silently. A profile can only pre-authorise a standard (non-admin) user to approve it themselves, which is what the generated profile does. This is the one monitoring choice that is not invisible to the end user. Every other level installs with no prompt beyond the FDA toggle described above.

## Piece 1: Deploy the signed .pkg

The collector is distributed as a notarized, Developer ID-signed `.pkg`. Installing it places `Hilt.app` in `/Applications` and registers the updater LaunchDaemon (`com.hilt.edr.updater`); telemetry ships from the ESensor extension itself over outbound HTTPS. See [Release artifacts](https://hilt.ai/docs/macos-collector/release-artifacts.md) for where to obtain the package and its checksum.

**1. Upload the package to your MDM**

Add the signed `.pkg` to your MDM's package store:

* **Jamf Pro:** upload to a distribution point (Jamf Admin or the web console), then scope a policy with an **Install Package** action.
* **Kandji:** add a **Custom App** of type **Installer Package (.pkg)** and assign it to a Blueprint.
* **Intune:** add it as a **macOS app → Line-of-business app** (`.pkg`), or wrap and deploy via the Intune macOS PKG installer.

**2. Order delivery before first launch**

Deliver the **System Extensions payload before the app first launches** (see Piece 2). If the app starts before its approval profile lands, macOS surfaces a one-time approval prompt that the profile would have suppressed. In Jamf, scope the configuration profile to the same smart group at the same priority or higher than the install policy. In Kandji and Intune, profiles and apps in a Blueprint or assignment converge at check-in, so target the same group.

**3. Verify the install landed**

From a managed host, or via your MDM's remote-command or script runner:

```bash theme={null}
pkgutil --pkg-info-plist <package-identifier>
ls -d /Applications/Hilt.app
systemextensionsctl list
```

`systemextensionsctl list` should show `Hilt.EDRApp.ESensor` and `Hilt.EDRApp.NetFilter` in the `[activated enabled]` state once approval has applied.

The `.pkg` is notarized and Developer ID-signed, so Gatekeeper admits it without any local override. No `csrutil disable`, no `systemextensionsctl developer on`, and no developer mode are involved on managed hosts. Those are dev-only steps that a notarized package removes entirely.

## Piece 2: System Extensions payload (auto-approve the extension)

> [!NOTE]
>
> Already included in the generated profile. Follow this section only if you are authoring payloads natively in your MDM.

To suppress the System Extension approval prompt, push a **System Extensions** configuration profile. The payload type is `com.apple.system-extension-policy`. Whitelist Hilt's Apple Developer Team ID so any extension signed by that team is auto-approved.

**Required values**

| Key | Value | Meaning |
| :- | :- | :- |
| Payload type | `com.apple.system-extension-policy` | System Extensions policy |
| `AllowedTeamIdentifiers` | `MVMB6LCP2A` | Auto-approve any system extension signed by Cybe Corporation |
| `AllowedSystemExtensions` (optional, tighter) | `MVMB6LCP2A` → `Hilt.EDRApp.ESensor`, `Hilt.EDRApp.NetFilter` | Restrict approval to exactly these two extensions |

Whitelisting the Team ID (`MVMB6LCP2A`) is the simplest and recommended form: it auto-approves both ESensor and NetFilter, and survives extension renames or additions within the same team. If your policy prefers an explicit allowlist, pin the two bundle ids under `AllowedSystemExtensions` keyed to the team.

**By MDM:**

* **Jamf Pro:** Configuration Profile → **System Extensions** payload → set **System Extension Types** to *Allowed Team IDs*, add `MVMB6LCP2A`. (Optionally add *Allowed System Extensions* with the two bundle ids.)
* **Kandji:** **System Extensions** library item → add an allowed team identifier `MVMB6LCP2A`.
* **Intune:** **Devices → Configuration → macOS → Templates → Extensions → System Extensions** → allow the team identifier `MVMB6LCP2A`.

A raw payload, for reference or for a custom-profile MDM:

```xml theme={null}
<dict>
  <key>PayloadType</key>
  <string>com.apple.system-extension-policy</string>
  <key>AllowedTeamIdentifiers</key>
  <array>
    <string>MVMB6LCP2A</string>
  </array>
  <key>AllowedSystemExtensions</key>
  <dict>
    <key>MVMB6LCP2A</key>
    <array>
      <string>Hilt.EDRApp.ESensor</string>
      <string>Hilt.EDRApp.NetFilter</string>
    </array>
  </dict>
</dict>
```

This payload only requires **UAMDM**, not supervision. With it in place before first launch, the extension activates without ever surfacing the *"System extension blocked / Open System Settings"* prompt.

## Piece 3: PPPC payload (pre-grant Full Disk Access)

> [!NOTE]
>
> Already included in the generated profile. Follow this section only if you are authoring payloads natively in your MDM.

Full Disk Access is **required** for any Endpoint Security client. This is not optional, and the FDA entry on macOS appears as **ESensor / "Hilt EDR Sensor"**, not "EDRApp". To grant it silently, push a **Privacy Preferences Policy Control (PPPC)** profile.

The payload type is `com.apple.TCC.configuration-profile-policy`. Set the `SystemPolicyAllFiles` service to **Allow**, keyed to ESensor's code requirement so the grant binds to the correct, signed binary.

**Required values**

| Key | Value |
| :- | :- |
| Payload type | `com.apple.TCC.configuration-profile-policy` |
| Identifier | `Hilt.EDRApp.ESensor` |
| Identifier type | `bundleID` |
| Code requirement | `anchor apple generic and identifier "Hilt.EDRApp.ESensor" and (certificate leaf[field.1.2.840.113635.100.6.1.9] or certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = MVMB6LCP2A)` |
| Service | `SystemPolicyAllFiles` |
| Access | `Allow` |

The code requirement is the extension's designated requirement — the same string `codesign -d -r-` prints for the installed ESensor, and the same one Jamf computes if you upload the signed app. Use it verbatim.

**By MDM:**

* **Jamf Pro:** Configuration Profile → **Privacy Preferences Policy Control** payload → add an app with **Identifier** `Hilt.EDRApp.ESensor` (type *Bundle ID*), paste the code requirement, set **App or service** = *SystemPolicyAllFiles*, **Access** = *Allow*. Jamf can auto-compute the code requirement if you upload the signed app.
* **Kandji:** **PPPC** library item → add the ESensor identifier with the code requirement → grant *Full Disk Access (SystemPolicyAllFiles)*.
* **Intune:** macOS PPPC profile → service `SystemPolicyAllFiles` → *Allow*, with the identifier and code requirement above.

A raw payload, for reference:

```xml theme={null}
<dict>
  <key>PayloadType</key>
  <string>com.apple.TCC.configuration-profile-policy</string>
  <key>Services</key>
  <dict>
    <key>SystemPolicyAllFiles</key>
    <array>
      <dict>
        <key>Identifier</key>
        <string>Hilt.EDRApp.ESensor</string>
        <key>IdentifierType</key>
        <string>bundleID</string>
        <key>CodeRequirement</key>
        <string>anchor apple generic and identifier "Hilt.EDRApp.ESensor" and (certificate leaf[field.1.2.840.113635.100.6.1.9] or certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = MVMB6LCP2A)</string>
        <key>Authorization</key>
        <string>Allow</string>
      </dict>
    </array>
  </dict>
</dict>
```

This payload takes effect when it arrives through the MDM the Mac is enrolled in (see [Enrollment prerequisites](#enrollment-prerequisites)) — no ADE needed. On a device-enrolled fleet it grants Full Disk Access with no user interaction, and the install is fully silent end to end. A sensor already running without the grant picks it up on its own within minutes of the profile landing — current collector builds retry automatically, with no reboot or reinstall.

> [!NOTE]
>
> PPPC can pre-grant **Full Disk Access** (and Accessibility), but it can **never** pre-grant **Camera, Microphone, or Screen Recording**. Apple always requires a manual user grant for those three. The Hilt ES sensor only needs Full Disk Access, so an MDM install is fully silent. You do not need, and should not request, any of the camera / mic / screen services.
>
> **Input Monitoring** is a fourth service MDM cannot grant silently. It is not part of this payload and is only involved if you turn on clipboard paste attribution in the generated profile, where the most a profile can do is let a standard user approve it without an admin password.

## Result and verification

With all three pieces in place against an MDM-enrolled Mac:

1. The MDM installs the `.pkg`, so `Hilt.app` lands in `/Applications` and the updater LaunchDaemon registers.
2. The System Extensions profile auto-approves ESensor and NetFilter, so no approval prompt.
3. The PPPC profile pre-grants Full Disk Access to ESensor, so no FDA prompt.

The user sees nothing and telemetry begins flowing. To confirm from a managed host:

```bash theme={null}
# Extensions activated and enabled
systemextensionsctl list

# ESensor process running
pgrep -fl ESensor

# Updater LaunchDaemon loaded
launchctl print system/com.hilt.edr.updater
```

`systemextensionsctl list` should report `Hilt.EDRApp.ESensor` and `Hilt.EDRApp.NetFilter` as `[activated enabled]`. Within a minute the host appears in the dashboard **Collectors** fleet with a **macOS host-type badge**, and its events flow into the **Investigate**, **Networks**, **Files**, and **Users** views. See [Data flow](https://hilt.ai/docs/macos-collector/data-flow.md) for the end-to-end pipeline (ESensor → edr-collector → Kafka → enrichment → ClickHouse `endpoint_events`).

## Updates and macOS upgrades

* **App / extension update** (same Team ID, signed): no re-approval. The existing System Extension approval and FDA grant carry over, and `launchd` relaunches the new extension build automatically. Push the new `.pkg` through the same MDM mechanism, or let the collector's built-in updater deliver it from your deployment's release channel — the approvals carry over either way.
* **Monitoring policy change:** regenerate the profile in the console with the new choices and re-upload it. Because every generated profile shares the `ai.hilt.edr.deploy` identifier, the new one replaces the old on each Mac at next check-in rather than stacking beside it, and no re-approval of the extension is involved.
* **macOS major upgrade:** Full Disk Access grants can occasionally reset across major OS upgrades, a known TCC behavior. The MDM PPPC profile re-applies the grant automatically at the next check-in, so managed fleets self-heal. Direct-download (non-MDM) users may need to re-toggle FDA once.

## What this deployment does not do

* **No inbound exposure.** The collector opens no listening sockets and never phones home. The only network path is outbound HTTPS from the collector to the configured ingest endpoint. See [Networking and trust model](https://hilt.ai/docs/macos-collector/networking-security.md).
* **No kernel extension.** Nothing loads into the kernel, so there is no kext approval and no SIP change. The Mac stays hardened with SIP enabled.
* **No camera / mic / screen capture.** The sensor requests only Full Disk Access. It cannot, and does not, request Camera, Microphone, or Screen Recording, and PPPC could not pre-grant them anyway.
* **No on-device response (yet).** Quarantine-style response is not available on macOS. (Updates are covered: the collector self-updates from its signed release channel, and you can also push a newer `.pkg` through MDM.)
* **No manual-install path for privacy grants.** The PPPC payload is honored only when it arrives from the MDM the Mac is enrolled in. A profile a user double-clicks installs the other payloads but silently grants no Full Disk Access.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.