> For the complete documentation index, see [llms.txt](https://docs.harmony.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.harmony.io/getting-started/installing-harmony-app-on-mdm.md).

# Installing the Harmony App on MDM

Deploy the Harmony app to managed Windows, macOS and iOS devices automatically using Intune, Jamf Pro, JumpCloud, Workspace ONE, Ivanti or Kandji.

Harmony is available as an installable app, so your employees can open it from the Start menu or the Dock instead of finding a browser tab. If your organization manages devices with an MDM, you can install it on every device automatically, with no installer to package, no administrator rights, and nothing for your users to do.

This guide explains how the deployment works, what to check before you start, and the exact steps for the most common MDM platforms.

{% hint style="info" %}
This guide is about deploying the Harmony app **to** your devices. It is not about connecting your MDM as an integration so that Harmony can read your device inventory. For that, see [Unified MDM Device Management](https://github.com/harmonyso/public-docs/tree/main/guides/unified-mdm-device-management/README.md).
{% endhint %}

### How it works

Your MDM does not install the app itself. It delivers a single browser policy called `WebAppInstallForceList` to the device, and Chrome or Edge installs the Harmony app the next time it starts. Because the browser is already running in the user's session, nothing needs elevation and nothing interrupts them.

Two things follow from this. The policy value is identical on every platform, so the only real difference between MDM platforms is how you deliver it. And because the browser performs the install, your Harmony address must be reachable from the device at that moment.

### Supported Platforms

| Platform          | How the app is delivered                        | Silent install       |
| ----------------- | ----------------------------------------------- | -------------------- |
| Windows 10 and 11 | Browser policy, through Chrome or Edge          | Yes                  |
| macOS             | Browser policy, through a configuration profile | Yes                  |
| iPhone and iPad   | Managed Web Clip                                | Icon only, see below |
| Linux             | Browser policy, through a managed policy file   | Yes                  |

### Choose your platform

Read the two short sections below, then jump straight to your own MDM.

| Your MDM               | Go to                                                                     |
| ---------------------- | ------------------------------------------------------------------------- |
| Microsoft Intune       | [Configuring Microsoft Intune](#configuring-microsoft-intune)             |
| Jamf Pro               | [Configuring Jamf Pro](#configuring-jamf-pro)                             |
| JumpCloud              | [Configuring JumpCloud](#configuring-jumpcloud)                           |
| Workspace ONE UEM      | [Configuring Workspace ONE UEM](#configuring-workspace-one-uem)           |
| Ivanti Neurons for UEM | [Configuring Ivanti Neurons for UEM](#configuring-ivanti-neurons-for-uem) |
| Kandji                 | [Configuring Kandji](#configuring-kandji)                                 |
| Something else         | [Configuring any other MDM](#configuring-any-other-mdm)                   |
| iPhone or iPad         | [Setting up iPhone and iPad](#setting-up-iphone-and-ipad)                 |

### What you need before you start

1. **Find your Harmony address.** In Harmony, go to **Settings** and open **General**. The **Domain** field shows your address, in the form `yourcompany.harmony.io`. Every example below uses `yourcompany`, so replace it with your own.
2. **Confirm the app is installable.** Open `https://yourcompany.harmony.io/` in Microsoft Edge on a test machine and check that the **Install** icon appears in the address bar. If you cannot install it by hand, no policy will install it either.
3. **Allow Harmony through your proxy and SSL inspection.** Allowing `*.harmony.io` covers the application, its API and its realtime endpoint.
4. **Check that your target users have Harmony accounts.** The app opens to your organization's sign-in on first launch. Pushing it to a group without Harmony access gives those users an icon that leads to a login wall.

{% hint style="warning" %}
If `https://yourcompany.harmony.io/` does not load at all, the DNS record for your address may not be provisioned yet. Contact Harmony support before you build any policy.
{% endhint %}

{% hint style="info" %}
If your network policy requires exact hostnames rather than a wildcard, or blocks outbound websockets by default, contact Harmony support for the precise list for your instance. A blocked websocket stops live ticket updates without showing an error.
{% endhint %}

### What lands on the device

|                |                                                           |
| -------------- | --------------------------------------------------------- |
| **Appears as** | Harmony, in the Start menu, search and Launchpad          |
| **Window**     | Standalone, with no address bar and its own taskbar entry |
| **Opens at**   | Your Harmony workspace root                               |

The app updates itself from the web, so there is nothing for your MDM to maintain after the initial deployment. Harmony asks the user before applying a new version rather than reloading underneath them, so users occasionally see an update prompt in the app window. This is deliberate, to avoid losing a half-written ticket.

{% hint style="info" %}
The Harmony app always opens at your workspace root. Pointing the policy at a deeper path, such as `/portal`, does not produce an app that opens there.
{% endhint %}

### Understanding the policy value

Every platform below uses the same setting, `WebAppInstallForceList`, but the format differs by operating system. Pick your platform:

{% tabs %}
{% tab title="Windows" %}
A JSON array, written as a single string value.

```json
[
  {
    "url": "https://yourcompany.harmony.io/",
    "default_launch_container": "window",
    "create_desktop_shortcut": true,
    "fallback_app_name": "Harmony"
  }
]
```

{% endtab %}

{% tab title="macOS" %}
A property list array of dictionaries, not a JSON string.

```xml
<key>WebAppInstallForceList</key>
<array>
  <dict>
    <key>url</key>
    <string>https://yourcompany.harmony.io/</string>
    <key>default_launch_container</key>
    <string>window</string>
    <key>fallback_app_name</key>
    <string>Harmony</string>
  </dict>
</array>
```

{% endtab %}

{% tab title="Linux" %}
A JSON file, with the setting name as a key.

```json
{
  "WebAppInstallForceList": [
    {
      "url": "https://yourcompany.harmony.io/",
      "default_launch_container": "window",
      "fallback_app_name": "Harmony"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

Whichever format you use, the fields mean the same thing.

| Field                      | What it does                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`                      | Required. Your Harmony address, including the trailing slash.                                                                                                             |
| `default_launch_container` | `window` opens Harmony standalone, with no address bar and its own taskbar button. `tab` opens it as an ordinary browser tab.                                             |
| `create_desktop_shortcut`  | Adds a desktop icon. A Start menu entry is created either way. Ignored on macOS, where the app goes to the Applications folder.                                           |
| `fallback_app_name`        | The name used if Harmony cannot be reached at install time, for example on a laptop that first starts up off the network. Prevents a raw URL appearing in the Start menu. |

{% hint style="warning" %}
Write this value in a plain text editor. Curly quotes from a word processor or a rich text ticket field are the most common reason a policy is silently rejected.
{% endhint %}

### Configuring Microsoft Intune

Microsoft Edge policies ship with Intune, so Edge is the shortest path. Google Chrome requires importing Google's policy templates first.

#### Microsoft Edge

1. Sign in to `intune.microsoft.com` as **Intune Administrator** or **Policy and Profile Manager**.
2. Go to **Devices**, then **Configuration**, then select **Create** and **New Policy**.
3. Set **Platform** to `Windows 10 and later` and **Profile type** to `Settings catalog`, then select **Create**.
4. On **Basics**, name the profile, for example `WIN-Edge-Harmony-App`, and record your Harmony address in the description. Select **Next**.
5. Select **Add settings** and search for `WebAppInstallForceList`.
6. Under the category **Microsoft Edge**, select **Configure list of force-installed Web Apps**, then close the picker. The policy is published for both device and user scope, so two copies appear. Choose the one that matches what you will assign to. Device scope installs Harmony for every user of a shared machine.
7. Set the toggle to **Enabled**. The value box is a single free-text field, so paste the whole JSON array into it.
8. Select **Next** through **Scope tags**.
9. On **Assignments**, select **Add groups** and choose a pilot group of five to ten devices. Select **Next**.
10. Review the summary and select **Create**. Widen the assignment once the pilot confirms Harmony installs and signs in.

#### Google Chrome

Chrome's settings are not in the Intune settings catalog by default, so you must import Google's policy templates first.

1. Download `policy_templates.zip` from [chromeenterprise.google/browser/download](https://chromeenterprise.google/browser/download/). From `windows/admx/`, take `google.admx`, `chrome.admx`, and the `en-US` copies of `google.adml` and `chrome.adml`.
2. Go to **Devices**, then **Configuration**, then the **Import ADMX** tab, then select **Import**.
3. Import `google.admx` first, paired with `google.adml`. This file defines the namespace that Chrome's template depends on, so importing Chrome first fails validation.
4. Import `chrome.admx` paired with `chrome.adml`. Wait until both rows show status **Available**.
5. Create a settings catalog profile as in steps 2 to 4 above, named for example `WIN-Chrome-Harmony-App`.
6. Search for `WebAppInstallForceList`. The imported settings appear under **Google**, then **Google Chrome**. Enable the setting, paste the same JSON array, assign the profile and create it.

#### Using a script instead

If ADMX import is unavailable in your tenant, write the value directly with a script. This covers Chrome and Edge together.

Go to **Devices**, then **Scripts and remediations**, then **Platform scripts**, then **Add**, and select `Windows 10 and later`. Set **Run this script using the logged-on credentials** to `No`, **Enforce script signature check** to `No`, and **Run script in 64-bit PowerShell host** to `Yes`.

```powershell
$json = @'
[{"url":"https://yourcompany.harmony.io/","default_launch_container":"window","create_desktop_shortcut":true,"fallback_app_name":"Harmony"}]
'@

$targets = @(
    'HKLM:\SOFTWARE\Policies\Google\Chrome',
    'HKLM:\SOFTWARE\Policies\Microsoft\Edge'
)

foreach ($key in $targets) {
    if (-not (Test-Path $key)) { New-Item -Path $key -Force | Out-Null }
    New-ItemProperty -Path $key -Name 'WebAppInstallForceList' `
        -Value $json -PropertyType String -Force | Out-Null
}
```

#### Opening Harmony at sign-in

On service desk workstations where Harmony is the primary tool for the shift, you can have it open automatically. Add the `WebAppSettings` policy in the same category, with this value:

```json
[
  {
    "manifest_id": "https://yourcompany.harmony.io/",
    "run_on_os_login": "run_windowed"
  }
]
```

Confirm the identifier at `chrome://web-app-internals` on a machine that already has Harmony installed before rolling this out widely.

### Configuring Jamf Pro

Jamf manages Apple platforms. If you also have Windows devices, pair this with Intune or JumpCloud.

1. Go to **Computers**, then **Configuration Profiles**, then select **New**.
2. On the **General** payload, name the profile, for example `MAC-Harmony-App`, set **Level** to `Computer Level`, and set **Distribution Method** to `Install Automatically`. Computer Level matters, because a user-level profile installs Harmony for one account only.
3. Select the **Application & Custom Settings** payload, then **External Applications**, then **Add**.
4. Set **Source** to `Upload File (plist)` and **Preference Domain** to `com.google.Chrome`. For Microsoft Edge, use `com.microsoft.Edge` in a second payload.
5. Upload or paste the property list below. If your Jamf Pro version offers a **Google Chrome** manifest under the **Jamf Repository** source, you can use that instead and fill the field in a typed form.
6. On the **Scope** tab, target a smart computer group. Start with a test group.
7. Select **Save**. The profile installs at the next check-in, and Harmony appears the next time Chrome starts.

```xml
<key>WebAppInstallForceList</key>
<array>
  <dict>
    <key>url</key>
    <string>https://yourcompany.harmony.io/</string>
    <key>default_launch_container</key>
    <string>window</string>
    <key>fallback_app_name</key>
    <string>Harmony</string>
  </dict>
</array>
```

{% hint style="warning" %}
On macOS this value must be a real property list array of dictionaries, as shown above. Pasting the Windows JSON string into a Mac profile does not work, and fails without an error message.
{% endhint %}

On macOS, Harmony installs to `~/Applications/Chrome Apps.localized/` and appears in Launchpad and Spotlight.

### Configuring JumpCloud

JumpCloud covers Windows and macOS through two different mechanisms, so build one policy per platform and bind both to the same device group. Windows devices need the JumpCloud agent, and Macs must be enrolled in JumpCloud MDM.

#### Windows

1. Go to **Device Management**, then **Policy Management**, then **New Policy**, and select the **Windows** tab.
2. Choose the **Advanced: Windows Registry** template.
3. Name the policy, then add a registry value with **Registry Hive** `HKEY_LOCAL_MACHINE`, **Path** `SOFTWARE\Policies\Google\Chrome`, **Name** `WebAppInstallForceList`, and **Type** `String (REG_SZ)`. Paste the JSON array as the value, on a single line.
4. Add a second registry value, identical except for the path, using `SOFTWARE\Policies\Microsoft\Edge`.
5. On the **Device Groups** tab, bind the policy and save.

If the registry template is not available in your tenant, use **Commands** with the PowerShell script from the Intune section, run as `System` on a repeating schedule so it reapplies itself.

#### macOS

Save a configuration profile containing the `com.google.Chrome` payload shown in the Jamf Pro section, then go to **Policy Management**, **New Policy**, **Mac**, and choose the **Custom MDM Configuration Profile** template. Upload the profile and bind it to your Mac device group.

### Configuring Workspace ONE UEM

#### Windows

A script is the lower-friction route, because it needs no template import and covers both browsers at once. Go to **Resources**, then **Scripts**, then **Add**, and select Windows. Set the language to **PowerShell**, the execution context to **System**, and the architecture to **64-bit**, then paste the script from the Intune section. Assign it to a smart group with a periodic trigger, so the value is restored if it is changed locally.

#### macOS

Go to **Resources**, then **Profiles**, then **Add**, then **Apple macOS**, then **Device Profile**. Select the **Custom Settings** payload and paste the property list from the Jamf Pro section, with the target domain `com.google.Chrome`. Assign to a smart group and select **Save & Publish**.

### Configuring Ivanti Neurons for UEM

This applies to Ivanti Neurons for UEM and to older MobileIron Core builds. Console labels differ slightly between the two, but the mechanism is the same.

#### Windows

Go to **Configurations**, then **Add**, then Windows, then **Custom Settings**, and add an OMA-URI setting. For Microsoft Edge, no template import is needed. For Chrome, ingest Google's templates through the same mechanism first, then reference the Chrome node at:

```
./Device/Vendor/MSFT/Policy/Config/Chrome~Policy~googlechrome/WebAppInstallForceList
```

Set the value using ADMX policy syntax, with the quotes in the JSON escaped for XML:

```
<enabled/><data id="WebAppInstallForceList" value="...escaped JSON..."/>
```

{% hint style="info" %}
The escaping makes this route easy to get wrong. If Ivanti can run PowerShell against your Windows devices, the script from the Intune section does the same job with no escaping and is easier to audit.
{% endhint %}

#### macOS

Go to **Configurations**, then **Add**, then macOS, then **Custom Configuration**, and upload the same configuration profile you would use with Jamf Pro or JumpCloud.

### Configuring Kandji

1. Save a configuration profile containing the `com.google.Chrome` payload from the Jamf Pro section.
2. Go to **Library**, then **Add New**, then **Custom Profile**.
3. Upload the profile, name the library item, for example `Harmony app`, and assign it to the Blueprints that should receive it.
4. Select **Save**. Kandji applies the profile at the next agent check-in, and Harmony appears at the next Chrome launch.

### Configuring any other MDM

There is no Harmony-specific integration involved. If your management tool can do any one of the following, it can deploy the Harmony app.

**Write a Windows registry value.** Set `WebAppInstallForceList` as a `REG_SZ` value containing the JSON array, under `HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome` for Chrome, or `HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge` for Edge.

**Deliver a macOS configuration profile.** Use the `com.google.Chrome` property list payload from the Jamf Pro section. It is portable across every Apple MDM.

**Manage Chrome from the Google Admin console.** If your browsers or ChromeOS devices are enrolled in Chrome Browser Cloud Management, go to `admin.google.com`, then **Devices**, then **Chrome**, then **Settings**, then **Users & browsers**. Select the target organizational unit, find **Force-installed web apps**, and paste the same JSON array. On Windows, note that registry policies take precedence over cloud policies by default.

**Place a file on Linux.** Write a JSON file with `WebAppInstallForceList` as a key to `/etc/opt/chrome/policies/managed/harmony.json` for Chrome, or `/etc/opt/edge/policies/managed/harmony.json` for Edge, owned by root with mode 0644.

### Setting up iPhone and iPad

Apple provides no equivalent of `WebAppInstallForceList`, so the Harmony app cannot be installed silently on iOS or iPadOS the way it can on Windows and macOS.

What you can do instead is push a managed **Web Clip**: a Harmony icon on the home screen that opens the app full screen, without Safari's browser controls. Harmony supports this, so the icon uses the Harmony name and opens without a browser bar.

Most MDM platforms offer a Web Clip payload directly. In Intune it is under **Apps**, then **iOS/iPadOS**, as the **Web clip** app type. In Jamf Pro it is the **Web Clip** payload. Set the URL to `https://yourcompany.harmony.io/` and enable full screen.

{% hint style="info" %}
Most Web Clip payloads let you prevent users removing the icon. On corporate-owned devices this is usually fine. On personally-owned devices enrolled in your MDM, an icon that cannot be removed tends to generate complaints, so consider leaving it removable.
{% endhint %}

### What your users see

Installation is invisible. There is no prompt, no progress bar, no restart, and no administrator rights required.

Afterwards your users find a **Harmony** entry in the Start menu, or in Launchpad on macOS, with the Harmony icon and searchable from the taskbar. They also get a desktop shortcut if you enabled it. Opening it gives a clean standalone window with no address bar and its own taskbar button, which can be pinned like any other application. While the policy is assigned, the app cannot be removed and shows as managed by your organization.

Allow up to eight hours for the policy to reach a device, then a browser restart for the app to appear. To test immediately, force an MDM sync on the device and fully close and reopen the browser.

### Verifying the installation

1. On a target device, open `chrome://policy` or `edge://policy` and select **Reload policies**.
2. Find `WebAppInstallForceList`. The status should read **OK**. Anything else, or the policy missing entirely, tells you where the problem is.
3. Check `chrome://apps` for the Harmony app.

A successful result in your MDM console confirms only that the policy value was written, not that the app installed. That evidence is in the browser.

### Troubleshooting

| Symptom                                         | Likely cause                                                                                                      | What to do                                                                                      |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| The policy does not appear at `chrome://policy` | For Chrome, the policy templates were never imported. Otherwise the value was written to the wrong registry hive. | Confirm the ADMX import status is **Available**, or check the value under `HKEY_LOCAL_MACHINE`. |
| The policy appears with status **Error**        | The JSON is malformed, usually curly quotes or a trailing comma.                                                  | Re-paste the value from a plain text editor.                                                    |
| The policy reads **OK** but no app appears      | Harmony or its icons could not be reached at install time, usually a proxy or SSL inspection rule.                | Allow `*.harmony.io`, then open `chrome://web-app-internals` for the exact reason.              |
| Harmony opens in a browser tab                  | `default_launch_container` is missing or set to `tab`.                                                            | Set it to `window`. The change applies to new installations.                                    |
| It works in Edge but not Chrome                 | Only one browser's policy was deployed.                                                                           | The two browsers read separate settings, so deploy both.                                        |

### Removing the app

Remove the group from the policy assignment, or set the value to an empty array `[]`. Enforcement stops at the next browser launch.

The app itself stays installed and simply becomes removable by the user. This is deliberate, so that a policy change does not delete an app someone is working in. Neither browser offers a supported silent uninstall for web apps, so plan removal as a message to your users rather than a command.

### Related Resources

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Using the Harmony Portal</strong></td><td>What your employees see in the app</td><td><a href="https://github.com/harmonyso/public-docs/tree/main/guides/using-the-harmony-portal/README.md">https://github.com/harmonyso/public-docs/tree/main/guides/using-the-harmony-portal/README.md</a></td></tr><tr><td><strong>User Roles and Permissions</strong></td><td>Make sure your users have access first</td><td><a href="https://github.com/harmonyso/public-docs/tree/main/guides/understanding-user-roles-and-permissions/README.md">https://github.com/harmonyso/public-docs/tree/main/guides/understanding-user-roles-and-permissions/README.md</a></td></tr><tr><td><strong>Unified MDM Device Management</strong></td><td>Connect your MDM so Harmony can read devices</td><td><a href="https://github.com/harmonyso/public-docs/tree/main/guides/unified-mdm-device-management/README.md">https://github.com/harmonyso/public-docs/tree/main/guides/unified-mdm-device-management/README.md</a></td></tr><tr><td><strong>Navigating the Interface</strong></td><td>Find your way around Harmony</td><td><a href="https://github.com/harmonyso/public-docs/tree/main/guides/navigating-the-interface/README.md">https://github.com/harmonyso/public-docs/tree/main/guides/navigating-the-interface/README.md</a></td></tr></tbody></table>


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.harmony.io/getting-started/installing-harmony-app-on-mdm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
