---
description: Unofficial Capacitor plugin for the Microsoft Intune App SDK to enforce app protection policies (MAM) in your Android and iOS apps.
title: Capacitor Intune Plugin for Android & iOS - Capawesome
image: https://capawesome.io/docs/assets/images/social/sdks/capacitor/intune.png
---

<!doctype html> 

[Skip to content ](#capacitor-intune-plugin) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* Intune [ Intune ](/docs/sdks/capacitor/intune/)
* [ iOS ](#ios)
* [ Automated Setup with Trapeze ](#automated-setup-with-trapeze)
* [ Web ](#web)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Type Aliases ](#type-aliases)
* [ Platform Support ](#platform-support)
* [ Choosing between the MAM and MDM channel ](#choosing-between-the-mam-and-mdm-channel)
* [ Testing ](#testing)
* [ Licensing ](#licensing)
* [ FAQ ](#faq)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ License ](#license)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ iOS ](#ios)
* [ Automated Setup with Trapeze ](#automated-setup-with-trapeze)
* [ Web ](#web)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Type Aliases ](#type-aliases)
* [ Platform Support ](#platform-support)
* [ Choosing between the MAM and MDM channel ](#choosing-between-the-mam-and-mdm-channel)
* [ Testing ](#testing)
* [ Licensing ](#licensing)
* [ FAQ ](#faq)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ License ](#license)

# Capacitor Intune Plugin[¶](#capacitor-intune-plugin "Permanent link")

Unofficial Capacitor plugin for [Microsoft Intune](https://www.microsoft.com/en-us/security/business/microsoft-intune).[1](#fn:1)

[ ![Deliver Live Updates to your Capacitor app with Capawesome Cloud](../../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://cloud.capawesome.io/) 

## Features[¶](#features "Permanent link")

The Capacitor Intune plugin integrates the Microsoft Intune App SDK for Mobile Application Management (MAM) into Capacitor apps. Here are some of the key features:

* 🖥️ **Cross-platform**: Supports Android and iOS.
* 🛡️ **App Protection Policies**: Automatic enforcement of PIN, encryption, copy/paste and screenshot restrictions after the native integration.
* 🔑 **MSAL**: Acquire tokens interactively or silently via the Microsoft Authentication Library.
* 🧾 **Enrollment**: Register and enroll accounts in Mobile Application Management (MAM) — without device enrollment.
* 📋 **Typed Policy Introspection**: Read the applied app protection policy as typed booleans to adapt your UI.
* ⚙️ **App Configuration**: Read the application configuration deployed via the MAM channel, including conflict information.
* 🧹 **Selective Wipe Events**: Get notified when the Intune service requests a wipe so you can purge the web layer storage (e.g. IndexedDB, Local Storage) that the SDK cannot wipe itself.
* 🩺 **Diagnostics**: Show the Intune diagnostic console from JavaScript.
* 📌 **Current SDK Pins**: Built against current Microsoft Intune App SDK and MSAL versions — Microsoft blocks apps that ship outdated SDKs.
* 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
* 🔁 **Up-to-date**: Always supports the latest Capacitor version.
* 🤝 **Compatibility**: Works alongside the [Managed Configurations](https://capawesome.io/docs/sdks/capacitor/managed-configurations/) plugin, which covers the MDM channel (see [Choosing between the MAM and MDM channel](#choosing-between-the-mam-and-mdm-channel)).

Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!

## Use Cases[¶](#use-cases "Permanent link")

The Intune plugin is typically used in line-of-business apps that are distributed to employees of organizations that manage corporate data with Microsoft Intune, for example:

* **App protection without device enrollment**: Protect corporate data in your app on personal (BYOD) devices via Mobile Application Management (MAM).
* **Conditional access**: Combine with Microsoft Entra conditional access policies that require an Intune-protected app.
* **Policy-aware UI**: Read the applied app protection policy and hide or disable features (e.g. local export) that the policy does not allow.
* **Per-tenant configuration**: Read the application configuration that the organization's IT administrator has deployed for the signed-in account.
* **Selective wipe**: Clean up the web layer storage of your app when the organization wipes its corporate data.
* **Ionic enterprise migration**: Migrate from the discontinued Ionic enterprise Intune integration to a maintained, free plugin.

## Compatibility[¶](#compatibility "Permanent link")

| Plugin Version | Capacitor Version | Status         |
| -------------- | ----------------- | -------------- |
| 0.x.x          | \>=8.x.x          | Active support |

## Installation[¶](#installation "Permanent link")

You can use our **AI-Assisted Setup** to install the plugin. Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:

`[](#%5F%5Fcodelineno-0-1)npx skills add capawesome-team/skills --skill capacitor-plugins
`

Then use the following prompt:

`` [](#%5F%5Fcodelineno-1-1)Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome/capacitor-intune` plugin in my project.
 ``

If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:

`[](#%5F%5Fcodelineno-2-1)npm install @capawesome/capacitor-intune
[](#%5F%5Fcodelineno-2-2)npx cap sync
`

This plugin requires a [Microsoft Intune](https://www.microsoft.com/en-us/security/business/microsoft-intune) tenant with Intune licenses and an app registration in [Microsoft Entra ID](https://entra.microsoft.com/). Create the app registration in the Microsoft Entra admin center, note its **Application (client) ID** and configure the platform-specific redirect URIs (see below). The `acquireToken(...)` scopes you request must be exposed or granted on this app registration.

> \[!IMPORTANT\] The Intune App SDKs are developed and licensed by Microsoft (see [Licensing](#licensing)). This plugin declares them as dependencies and downloads them from Microsoft's official repositories at build or install time. It does not bundle or modify them.

### Android[¶](#android "Permanent link")

The Microsoft Intune App SDK for Android is downloaded automatically from [Microsoft's official GitHub repository](https://github.com/microsoftconnect/ms-intune-app-sdk-android) during the Gradle build. However, the Intune App SDK requires several changes to your app project that no plugin can make for you. Follow the steps below or use [Trapeze](#automated-setup-with-trapeze) to automate them.

#### Variables[¶](#variables "Permanent link")

This plugin will use the following project variables (defined in your app's `variables.gradle` file):

* `$intuneMamSdkVersion` version of the [Microsoft Intune App SDK for Android](https://github.com/microsoftconnect/ms-intune-app-sdk-android) (default: `12.4.0`)
* `$msalVersion` version of `com.microsoft.identity.client:msal` (default: `8.4.0`)

#### MAM Build Plugin[¶](#mam-build-plugin "Permanent link")

The Intune App SDK relies on a Gradle build plugin that rewrites the Android base classes of your app **and all Capacitor plugins** to their MAM equivalents. Only the app module can apply this plugin — it cannot be applied by a library. Add the following to the `buildscript` block of your `android/build.gradle` file:

`[](#%5F%5Fcodelineno-3-1) buildscript {
[](#%5F%5Fcodelineno-3-2)     repositories {
[](#%5F%5Fcodelineno-3-3)         google()
[](#%5F%5Fcodelineno-3-4)         mavenCentral()
[](#%5F%5Fcodelineno-3-5)+        ivy {
[](#%5F%5Fcodelineno-3-6)+            url 'https://raw.githubusercontent.com/microsoftconnect/ms-intune-app-sdk-android'
[](#%5F%5Fcodelineno-3-7)+            patternLayout { artifact '[revision]/GradlePlugin/[artifact].[ext]' }
[](#%5F%5Fcodelineno-3-8)+            metadataSources { artifact() }
[](#%5F%5Fcodelineno-3-9)+            content { includeGroup 'com.microsoft.intune.mam.build' }
[](#%5F%5Fcodelineno-3-10)+        }
[](#%5F%5Fcodelineno-3-11)     }
[](#%5F%5Fcodelineno-3-12)     dependencies {
[](#%5F%5Fcodelineno-3-13)         classpath 'com.android.tools.build:gradle:8.13.0'
[](#%5F%5Fcodelineno-3-14)+        classpath 'org.javassist:javassist:3.29.2-GA'
[](#%5F%5Fcodelineno-3-15)+        classpath 'com.microsoft.intune.mam.build:com.microsoft.intune.mam.build:12.4.0@jar'
[](#%5F%5Fcodelineno-3-16)     }
[](#%5F%5Fcodelineno-3-17) }
`

Then apply the plugin in your `android/app/build.gradle` file:

`[](#%5F%5Fcodelineno-4-1) apply plugin: 'com.android.application'
[](#%5F%5Fcodelineno-4-2)+apply plugin: 'com.microsoft.intune.mam'
`

#### Application Class[¶](#application-class "Permanent link")

The Intune App SDK requires an `Application` class that registers the MAM components before any other code runs. Set the ready-made class provided by this plugin in the `application` tag of your `android/app/src/main/AndroidManifest.xml` file:

`[](#%5F%5Fcodelineno-5-1)<application
[](#%5F%5Fcodelineno-5-2)    android:name="io.capawesome.capacitorjs.plugins.intune.IntuneApplication"
[](#%5F%5Fcodelineno-5-3)    ...>
`

If your app already uses a custom `Application` class, call the initializer yourself instead:

`[](#%5F%5Fcodelineno-6-1)import io.capawesome.capacitorjs.plugins.intune.Intune;
[](#%5F%5Fcodelineno-6-2)
[](#%5F%5Fcodelineno-6-3)public class MyApplication extends Application {
[](#%5F%5Fcodelineno-6-4)
[](#%5F%5Fcodelineno-6-5)    @Override
[](#%5F%5Fcodelineno-6-6)    public void onCreate() {
[](#%5F%5Fcodelineno-6-7)        super.onCreate();
[](#%5F%5Fcodelineno-6-8)        Intune.initialize(this);
[](#%5F%5Fcodelineno-6-9)    }
[](#%5F%5Fcodelineno-6-10)}
`

It's also recommended to disable predictive back gestures in the `application` tag since the Intune App SDK does not support them yet:

`[](#%5F%5Fcodelineno-7-1)<application
[](#%5F%5Fcodelineno-7-2)    android:enableOnBackInvokedCallback="false"
[](#%5F%5Fcodelineno-7-3)    ...>
`

#### MSAL Configuration[¶](#msal-configuration "Permanent link")

Create the file `android/app/src/main/res/raw/auth_config.json` with your MSAL configuration:

`[](#%5F%5Fcodelineno-8-1){
[](#%5F%5Fcodelineno-8-2)  "client_id": "YOUR_CLIENT_ID",
[](#%5F%5Fcodelineno-8-3)  "authorization_user_agent": "DEFAULT",
[](#%5F%5Fcodelineno-8-4)  "redirect_uri": "msauth://YOUR_PACKAGE_NAME/YOUR_BASE64_URL_ENCODED_PACKAGE_SIGNATURE",
[](#%5F%5Fcodelineno-8-5)  "account_mode": "MULTIPLE",
[](#%5F%5Fcodelineno-8-6)  "broker_redirect_uri_registered": true,
[](#%5F%5Fcodelineno-8-7)  "authorities": [
[](#%5F%5Fcodelineno-8-8)    {
[](#%5F%5Fcodelineno-8-9)      "type": "AAD",
[](#%5F%5Fcodelineno-8-10)      "audience": {
[](#%5F%5Fcodelineno-8-11)        "type": "AzureADMultipleOrgs"
[](#%5F%5Fcodelineno-8-12)      }
[](#%5F%5Fcodelineno-8-13)    }
[](#%5F%5Fcodelineno-8-14)  ]
[](#%5F%5Fcodelineno-8-15)}
`

You can generate the base64-encoded signature hash of your signing key with:

`[](#%5F%5Fcodelineno-9-1)keytool -exportcert -alias YOUR_KEY_ALIAS -keystore YOUR_KEYSTORE | openssl sha1 -binary | openssl base64
`

Make sure the same redirect URI (`msauth://YOUR_PACKAGE_NAME/YOUR_BASE64_URL_ENCODED_PACKAGE_SIGNATURE`) is registered as an **Android** platform redirect URI on your app registration in the Microsoft Entra admin center.

Next, add the following activity to the `application` tag of your `android/app/src/main/AndroidManifest.xml` file so that MSAL can receive the redirect from the Microsoft sign-in flow:

`[](#%5F%5Fcodelineno-10-1)<activity android:name="com.microsoft.identity.client.BrowserTabActivity" android:exported="true">
[](#%5F%5Fcodelineno-10-2)    <intent-filter>
[](#%5F%5Fcodelineno-10-3)        <action android:name="android.intent.action.VIEW" />
[](#%5F%5Fcodelineno-10-4)        <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-10-5)        <category android:name="android.intent.category.BROWSABLE" />
[](#%5F%5Fcodelineno-10-6)        <data android:scheme="msauth" android:host="YOUR_PACKAGE_NAME" android:path="/YOUR_BASE64_ENCODED_PACKAGE_SIGNATURE" />
[](#%5F%5Fcodelineno-10-7)    </intent-filter>
[](#%5F%5Fcodelineno-10-8)</activity>
`

#### Gradle Properties[¶](#gradle-properties "Permanent link")

Add the following to your `android/gradle.properties` file. Without it, release builds may report `MAM Enabled: No` in the diagnostic console:

`[](#%5F%5Fcodelineno-11-1)android.enableResourceOptimizations=false
`

#### Company Portal[¶](#company-portal "Permanent link")

App protection policies are only applied when the [Company Portal](https://play.google.com/store/apps/details?id=com.microsoft.windowsintune.companyportal) app is installed on the device. The user does **not** need to sign in to the Company Portal. Without it, your app behaves as unmanaged.

### iOS[¶](#ios "Permanent link")

The Microsoft Intune App SDK for iOS requires **iOS 17+** as deployment target and a current Xcode version. This deviates from the usual iOS 15 minimum of the Capawesome plugin collection. Make sure the deployment target of your app is set to iOS 17.0 or later (in `ios/App/App.xcodeproj` and, if you use Swift Package Manager, in `ios/App/CapApp-SPM/Package.swift`).

The SDK is consumed from [Microsoft's official GitHub repository](https://github.com/msintuneappsdk/ms-intune-app-sdk-ios): via Swift Package Manager it is resolved like any other package; via CocoaPods it is downloaded automatically during `pod install` (Microsoft does not publish a CocoaPods pod).

#### Info.plist[¶](#infoplist "Permanent link")

Add the `IntuneMAMSettings` dictionary to your `ios/App/App/Info.plist` file (the keys keep their legacy `ADAL` names for historical reasons):

`[](#%5F%5Fcodelineno-12-1)<key>IntuneMAMSettings</key>
[](#%5F%5Fcodelineno-12-2)<dict>
[](#%5F%5Fcodelineno-12-3)    <key>ADALAuthority</key>
[](#%5F%5Fcodelineno-12-4)    <string>https://login.microsoftonline.com/YOUR_TENANT_ID</string>
[](#%5F%5Fcodelineno-12-5)    <key>ADALClientId</key>
[](#%5F%5Fcodelineno-12-6)    <string>YOUR_CLIENT_ID</string>
[](#%5F%5Fcodelineno-12-7)    <key>ADALRedirectUri</key>
[](#%5F%5Fcodelineno-12-8)    <string>msauth.YOUR_BUNDLE_ID://auth</string>
[](#%5F%5Fcodelineno-12-9)</dict>
`

This plugin also uses these values to configure MSAL, so no separate MSAL configuration is needed.

Next, register the MSAL redirect URL scheme and the query schemes in the same file:

`[](#%5F%5Fcodelineno-13-1)<key>CFBundleURLTypes</key>
[](#%5F%5Fcodelineno-13-2)<array>
[](#%5F%5Fcodelineno-13-3)    <dict>
[](#%5F%5Fcodelineno-13-4)        <key>CFBundleURLName</key>
[](#%5F%5Fcodelineno-13-5)        <string>MSAL</string>
[](#%5F%5Fcodelineno-13-6)        <key>CFBundleURLSchemes</key>
[](#%5F%5Fcodelineno-13-7)        <array>
[](#%5F%5Fcodelineno-13-8)            <string>msauth.YOUR_BUNDLE_ID</string>
[](#%5F%5Fcodelineno-13-9)        </array>
[](#%5F%5Fcodelineno-13-10)    </dict>
[](#%5F%5Fcodelineno-13-11)</array>
[](#%5F%5Fcodelineno-13-12)<key>LSApplicationQueriesSchemes</key>
[](#%5F%5Fcodelineno-13-13)<array>
[](#%5F%5Fcodelineno-13-14)    <string>msauthv2</string>
[](#%5F%5Fcodelineno-13-15)    <string>msauthv3</string>
[](#%5F%5Fcodelineno-13-16)    <string>http-intunemam</string>
[](#%5F%5Fcodelineno-13-17)    <string>https-intunemam</string>
[](#%5F%5Fcodelineno-13-18)</array>
`

Make sure the redirect URI (`msauth.YOUR_BUNDLE_ID://auth`) is registered as an **iOS/macOS** platform redirect URI on your app registration in the Microsoft Entra admin center. The plugin handles the MSAL redirect automatically — no `AppDelegate` changes are required.

Finally, add a Face ID usage description if your app does not have one yet, since app protection policies may require biometric unlock:

`[](#%5F%5Fcodelineno-14-1)<key>NSFaceIDUsageDescription</key>
[](#%5F%5Fcodelineno-14-2)<string>This app uses Face ID to secure corporate data.</string>
`

#### Keychain Sharing[¶](#keychain-sharing "Permanent link")

Enable the **Keychain Sharing** capability for your app target in Xcode and add the following keychain groups (in this order):

1. `com.example.app` (your bundle ID, usually already present)
2. `com.microsoft.intune.mam`
3. `com.microsoft.adalcache`

#### IntuneMAMConfigurator[¶](#intunemamconfigurator "Permanent link")

Microsoft ships the `IntuneMAMConfigurator` tool with the [SDK repository](https://github.com/msintuneappsdk/ms-intune-app-sdk-ios). It applies the minimum required `Info.plist` changes for Intune management (including the `-intunemam` query scheme variants for every scheme your app queries) and is idempotent:

`[](#%5F%5Fcodelineno-15-1)IntuneMAMConfigurator -i ios/App/App/Info.plist -e ios/App/App/App.entitlements
`

Running it is recommended before you ship, especially if your app passes additional URL schemes to `canOpenURL`.

### Automated Setup with Trapeze[¶](#automated-setup-with-trapeze "Permanent link")

Most of the host app changes above can be automated with [Trapeze](https://trapeze.dev/), which is also used by [Capawesome Cloud](https://capawesome.io/cloud/). Save the following configuration as `trapeze.yaml` and run `npx @trapezedev/configure run trapeze.yaml` with the `CLIENT_ID`, `TENANT_ID`, `PACKAGE_NAME`, `BUNDLE_ID` and `SIGNATURE_HASH` variables set:

`[](#%5F%5Fcodelineno-16-1)vars:
[](#%5F%5Fcodelineno-16-2)  CLIENT_ID:
[](#%5F%5Fcodelineno-16-3)  TENANT_ID:
[](#%5F%5Fcodelineno-16-4)  PACKAGE_NAME:
[](#%5F%5Fcodelineno-16-5)  BUNDLE_ID:
[](#%5F%5Fcodelineno-16-6)  SIGNATURE_HASH:
[](#%5F%5Fcodelineno-16-7)
[](#%5F%5Fcodelineno-16-8)platforms:
[](#%5F%5Fcodelineno-16-9)  android:
[](#%5F%5Fcodelineno-16-10)    gradle:
[](#%5F%5Fcodelineno-16-11)      - file: build.gradle
[](#%5F%5Fcodelineno-16-12)        target:
[](#%5F%5Fcodelineno-16-13)          buildscript:
[](#%5F%5Fcodelineno-16-14)            dependencies:
[](#%5F%5Fcodelineno-16-15)        insert: |
[](#%5F%5Fcodelineno-16-16)          classpath 'org.javassist:javassist:3.29.2-GA'
[](#%5F%5Fcodelineno-16-17)          classpath 'com.microsoft.intune.mam.build:com.microsoft.intune.mam.build:12.4.0@jar'
[](#%5F%5Fcodelineno-16-18)      - file: build.gradle
[](#%5F%5Fcodelineno-16-19)        target:
[](#%5F%5Fcodelineno-16-20)          buildscript:
[](#%5F%5Fcodelineno-16-21)            repositories:
[](#%5F%5Fcodelineno-16-22)        insert: |
[](#%5F%5Fcodelineno-16-23)          ivy {
[](#%5F%5Fcodelineno-16-24)              url 'https://raw.githubusercontent.com/microsoftconnect/ms-intune-app-sdk-android'
[](#%5F%5Fcodelineno-16-25)              patternLayout { artifact '[revision]/GradlePlugin/[artifact].[ext]' }
[](#%5F%5Fcodelineno-16-26)              metadataSources { artifact() }
[](#%5F%5Fcodelineno-16-27)              content { includeGroup 'com.microsoft.intune.mam.build' }
[](#%5F%5Fcodelineno-16-28)          }
[](#%5F%5Fcodelineno-16-29)      - file: app/build.gradle
[](#%5F%5Fcodelineno-16-30)        target:
[](#%5F%5Fcodelineno-16-31)        insert: |
[](#%5F%5Fcodelineno-16-32)          apply plugin: 'com.microsoft.intune.mam'
[](#%5F%5Fcodelineno-16-33)    manifest:
[](#%5F%5Fcodelineno-16-34)      - file: AndroidManifest.xml
[](#%5F%5Fcodelineno-16-35)        target: manifest/application
[](#%5F%5Fcodelineno-16-36)        attrs:
[](#%5F%5Fcodelineno-16-37)          android:name: io.capawesome.capacitorjs.plugins.intune.IntuneApplication
[](#%5F%5Fcodelineno-16-38)          android:enableOnBackInvokedCallback: 'false'
[](#%5F%5Fcodelineno-16-39)      - file: AndroidManifest.xml
[](#%5F%5Fcodelineno-16-40)        target: manifest/application
[](#%5F%5Fcodelineno-16-41)        inject: |
[](#%5F%5Fcodelineno-16-42)          <activity android:name="com.microsoft.identity.client.BrowserTabActivity" android:exported="true">
[](#%5F%5Fcodelineno-16-43)            <intent-filter>
[](#%5F%5Fcodelineno-16-44)              <action android:name="android.intent.action.VIEW" />
[](#%5F%5Fcodelineno-16-45)              <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-16-46)              <category android:name="android.intent.category.BROWSABLE" />
[](#%5F%5Fcodelineno-16-47)              <data android:scheme="msauth" android:host="$PACKAGE_NAME" android:path="/$SIGNATURE_HASH" />
[](#%5F%5Fcodelineno-16-48)            </intent-filter>
[](#%5F%5Fcodelineno-16-49)          </activity>
[](#%5F%5Fcodelineno-16-50)    res:
[](#%5F%5Fcodelineno-16-51)      - path: raw
[](#%5F%5Fcodelineno-16-52)        file: auth_config.json
[](#%5F%5Fcodelineno-16-53)        text: |
[](#%5F%5Fcodelineno-16-54)          {
[](#%5F%5Fcodelineno-16-55)            "client_id": "$CLIENT_ID",
[](#%5F%5Fcodelineno-16-56)            "authorization_user_agent": "DEFAULT",
[](#%5F%5Fcodelineno-16-57)            "redirect_uri": "msauth://$PACKAGE_NAME/$SIGNATURE_HASH",
[](#%5F%5Fcodelineno-16-58)            "account_mode": "MULTIPLE",
[](#%5F%5Fcodelineno-16-59)            "broker_redirect_uri_registered": true,
[](#%5F%5Fcodelineno-16-60)            "authorities": [
[](#%5F%5Fcodelineno-16-61)              {
[](#%5F%5Fcodelineno-16-62)                "type": "AAD",
[](#%5F%5Fcodelineno-16-63)                "audience": {
[](#%5F%5Fcodelineno-16-64)                  "type": "AzureADMultipleOrgs"
[](#%5F%5Fcodelineno-16-65)                }
[](#%5F%5Fcodelineno-16-66)              }
[](#%5F%5Fcodelineno-16-67)            ]
[](#%5F%5Fcodelineno-16-68)          }
[](#%5F%5Fcodelineno-16-69)  ios:
[](#%5F%5Fcodelineno-16-70)    targets:
[](#%5F%5Fcodelineno-16-71)      App:
[](#%5F%5Fcodelineno-16-72)        buildSettings:
[](#%5F%5Fcodelineno-16-73)          IPHONEOS_DEPLOYMENT_TARGET: '17.0'
[](#%5F%5Fcodelineno-16-74)        entitlements:
[](#%5F%5Fcodelineno-16-75)          - keychain-access-groups:
[](#%5F%5Fcodelineno-16-76)              [
[](#%5F%5Fcodelineno-16-77)                '$BUNDLE_ID',
[](#%5F%5Fcodelineno-16-78)                'com.microsoft.intune.mam',
[](#%5F%5Fcodelineno-16-79)                'com.microsoft.adalcache',
[](#%5F%5Fcodelineno-16-80)              ]
[](#%5F%5Fcodelineno-16-81)        plist:
[](#%5F%5Fcodelineno-16-82)          - entries:
[](#%5F%5Fcodelineno-16-83)              - IntuneMAMSettings:
[](#%5F%5Fcodelineno-16-84)                  ADALAuthority: https://login.microsoftonline.com/$TENANT_ID
[](#%5F%5Fcodelineno-16-85)                  ADALClientId: $CLIENT_ID
[](#%5F%5Fcodelineno-16-86)                  ADALRedirectUri: msauth.$BUNDLE_ID://auth
[](#%5F%5Fcodelineno-16-87)              - CFBundleURLTypes:
[](#%5F%5Fcodelineno-16-88)                  - CFBundleURLName: MSAL
[](#%5F%5Fcodelineno-16-89)                    CFBundleURLSchemes:
[](#%5F%5Fcodelineno-16-90)                      - msauth.$BUNDLE_ID
[](#%5F%5Fcodelineno-16-91)              - LSApplicationQueriesSchemes:
[](#%5F%5Fcodelineno-16-92)                  - msauthv2
[](#%5F%5Fcodelineno-16-93)                  - msauthv3
[](#%5F%5Fcodelineno-16-94)                  - http-intunemam
[](#%5F%5Fcodelineno-16-95)                  - https-intunemam
[](#%5F%5Fcodelineno-16-96)              - NSFaceIDUsageDescription: This app uses Face ID to secure corporate data.
`

> \[!NOTE\] Trapeze cannot edit `gradle.properties`, so the [Gradle Properties](#gradle-properties) step must still be done manually. Review the result after running Trapeze: some list-valued Info.plist entries may be merged rather than replaced, and the Gradle insertions are not idempotent — run them only once.

### Web[¶](#web "Permanent link")

This plugin does not provide a web implementation. All methods reject with an `unimplemented` error on the web platform.

## Configuration[¶](#configuration "Permanent link")

No configuration required for this plugin.

## Usage[¶](#usage "Permanent link")

The following examples show how to use the plugin.

### Sign in and enroll an account[¶](#sign-in-and-enroll-an-account "Permanent link")

Acquire a token via MSAL and enroll the returned account in Mobile Application Management (MAM). The enrollment itself is asynchronous — listen for the `enrollmentChange` event to get the result:

`[](#%5F%5Fcodelineno-17-1)import { Intune } from '@capawesome/capacitor-intune';
[](#%5F%5Fcodelineno-17-2)
[](#%5F%5Fcodelineno-17-3)const signInAndEnroll = async () => {
[](#%5F%5Fcodelineno-17-4)  await Intune.addListener('enrollmentChange', event => {
[](#%5F%5Fcodelineno-17-5)    console.log('Enrollment status:', event.status);
[](#%5F%5Fcodelineno-17-6)  });
[](#%5F%5Fcodelineno-17-7)  const { accountId } = await Intune.acquireToken({
[](#%5F%5Fcodelineno-17-8)    scopes: ['https://graph.microsoft.com/.default'],
[](#%5F%5Fcodelineno-17-9)  });
[](#%5F%5Fcodelineno-17-10)  await Intune.registerAndEnrollAccount({ accountId });
[](#%5F%5Fcodelineno-17-11)};
`

### Read the app protection policy[¶](#read-the-app-protection-policy "Permanent link")

Adapt your UI to the applied app protection policy:

`[](#%5F%5Fcodelineno-18-1)import { Intune } from '@capawesome/capacitor-intune';
[](#%5F%5Fcodelineno-18-2)
[](#%5F%5Fcodelineno-18-3)const applyPolicy = async () => {
[](#%5F%5Fcodelineno-18-4)  const { account } = await Intune.getEnrolledAccount();
[](#%5F%5Fcodelineno-18-5)  if (!account) {
[](#%5F%5Fcodelineno-18-6)    return;
[](#%5F%5Fcodelineno-18-7)  }
[](#%5F%5Fcodelineno-18-8)  const policy = await Intune.getPolicy({ accountId: account.accountId });
[](#%5F%5Fcodelineno-18-9)  if (!policy.saveToPersonalStorageAllowed) {
[](#%5F%5Fcodelineno-18-10)    // Hide your export/download buttons.
[](#%5F%5Fcodelineno-18-11)  }
[](#%5F%5Fcodelineno-18-12)};
`

### Read the app configuration[¶](#read-the-app-configuration "Permanent link")

Read the configuration values that the organization's IT administrator has deployed:

`[](#%5F%5Fcodelineno-19-1)import { Intune } from '@capawesome/capacitor-intune';
[](#%5F%5Fcodelineno-19-2)
[](#%5F%5Fcodelineno-19-3)const readAppConfig = async () => {
[](#%5F%5Fcodelineno-19-4)  const { account } = await Intune.getEnrolledAccount();
[](#%5F%5Fcodelineno-19-5)  if (!account) {
[](#%5F%5Fcodelineno-19-6)    return;
[](#%5F%5Fcodelineno-19-7)  }
[](#%5F%5Fcodelineno-19-8)  const { values } = await Intune.getAppConfig({ accountId: account.accountId });
[](#%5F%5Fcodelineno-19-9)  console.log('Server URL:', values['com.example.serverUrl']);
[](#%5F%5Fcodelineno-19-10)};
`

### Handle selective wipe[¶](#handle-selective-wipe "Permanent link")

The Intune App SDK wipes the data it manages, but it does **not** wipe the web layer storage of your Capacitor app. Register the `wipeRequested` listener as early as possible and purge your web storage when it fires:

`[](#%5F%5Fcodelineno-20-1)import { Intune } from '@capawesome/capacitor-intune';
[](#%5F%5Fcodelineno-20-2)
[](#%5F%5Fcodelineno-20-3)const registerWipeListener = async () => {
[](#%5F%5Fcodelineno-20-4)  await Intune.addListener('wipeRequested', async () => {
[](#%5F%5Fcodelineno-20-5)    localStorage.clear();
[](#%5F%5Fcodelineno-20-6)    sessionStorage.clear();
[](#%5F%5Fcodelineno-20-7)    const databases = await indexedDB.databases();
[](#%5F%5Fcodelineno-20-8)    for (const database of databases) {
[](#%5F%5Fcodelineno-20-9)      if (database.name) {
[](#%5F%5Fcodelineno-20-10)        indexedDB.deleteDatabase(database.name);
[](#%5F%5Fcodelineno-20-11)      }
[](#%5F%5Fcodelineno-20-12)    }
[](#%5F%5Fcodelineno-20-13)  });
[](#%5F%5Fcodelineno-20-14)};
`

## API[¶](#api "Permanent link")

* [acquireToken(...)](#acquiretoken)
* [acquireTokenSilent(...)](#acquiretokensilent)
* [getAppConfig(...)](#getappconfig)
* [getEnrolledAccount()](#getenrolledaccount)
* [getPolicy(...)](#getpolicy)
* [getSdkVersion()](#getsdkversion)
* [loginAndEnrollAccount()](#loginandenrollaccount)
* [registerAndEnrollAccount(...)](#registerandenrollaccount)
* [showDiagnosticConsole()](#showdiagnosticconsole)
* [unenrollAccount(...)](#unenrollaccount)
* [addListener('appConfigChange', ...)](#addlistenerappconfigchange-)
* [addListener('enrollmentChange', ...)](#addlistenerenrollmentchange-)
* [addListener('policyChange', ...)](#addlistenerpolicychange-)
* [addListener('wipeRequested', ...)](#addlistenerwiperequested-)
* [removeAllListeners()](#removealllisteners)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)

### acquireToken(...)[¶](#acquiretoken "Permanent link")

`[](#%5F%5Fcodelineno-21-1)acquireToken(options: AcquireTokenOptions) => Promise<AcquireTokenResult>
`

Acquire an access token interactively via the Microsoft Authentication Library (MSAL).

This presents the Microsoft sign-in UI if necessary. Use the returned `accountId` to enroll the account via `registerAndEnrollAccount(...)`.

Only available on Android and iOS.

| Param       | Type                                        |
| ----------- | ------------------------------------------- |
| **options** | [AcquireTokenOptions](#acquiretokenoptions) |

**Returns:** `Promise<[AcquireTokenResult](#acquiretokenresult)>`

**Since:** 0.1.0

---

### acquireTokenSilent(...)[¶](#acquiretokensilent "Permanent link")

`[](#%5F%5Fcodelineno-22-1)acquireTokenSilent(options: AcquireTokenSilentOptions) => Promise<AcquireTokenResult>
`

Acquire an access token silently via the Microsoft Authentication Library (MSAL) for an already signed-in account.

Only available on Android and iOS.

| Param       | Type                                                    |
| ----------- | ------------------------------------------------------- |
| **options** | [AcquireTokenSilentOptions](#acquiretokensilentoptions) |

**Returns:** `Promise<[AcquireTokenResult](#acquiretokenresult)>`

**Since:** 0.1.0

---

### getAppConfig(...)[¶](#getappconfig "Permanent link")

`[](#%5F%5Fcodelineno-23-1)getAppConfig(options: GetAppConfigOptions) => Promise<GetAppConfigResult>
`

Get the application configuration values that the organization's IT administrator has deployed for the given account via the MAM channel.

For configuration deployed via the MDM channel (device enrollment), use the Managed Configurations plugin instead.

Only available on Android and iOS.

| Param       | Type                                        |
| ----------- | ------------------------------------------- |
| **options** | [GetAppConfigOptions](#getappconfigoptions) |

**Returns:** `Promise<[GetAppConfigResult](#getappconfigresult)>`

**Since:** 0.1.0

---

### getEnrolledAccount()[¶](#getenrolledaccount "Permanent link")

`[](#%5F%5Fcodelineno-24-1)getEnrolledAccount() => Promise<GetEnrolledAccountResult>
`

Get the account that is currently enrolled in Mobile Application Management (MAM).

Only available on Android and iOS.

**Returns:** `Promise<[GetEnrolledAccountResult](#getenrolledaccountresult)>`

**Since:** 0.1.0

---

### getPolicy(...)[¶](#getpolicy "Permanent link")

`[](#%5F%5Fcodelineno-25-1)getPolicy(options: GetPolicyOptions) => Promise<GetPolicyResult>
`

Get the app protection policy that is currently applied for the given account.

Only available on Android and iOS.

| Param       | Type                                  |
| ----------- | ------------------------------------- |
| **options** | [GetPolicyOptions](#getpolicyoptions) |

**Returns:** `Promise<[GetPolicyResult](#getpolicyresult)>`

**Since:** 0.1.0

---

### getSdkVersion()[¶](#getsdkversion "Permanent link")

`[](#%5F%5Fcodelineno-26-1)getSdkVersion() => Promise<GetSdkVersionResult>
`

Get the versions of the Intune App SDK and the Microsoft Authentication Library (MSAL) that the plugin was built with.

Only available on Android and iOS.

**Returns:** `Promise<[GetSdkVersionResult](#getsdkversionresult)>`

**Since:** 0.1.0

---

### loginAndEnrollAccount()[¶](#loginandenrollaccount "Permanent link")

`[](#%5F%5Fcodelineno-27-1)loginAndEnrollAccount() => Promise<void>
`

Sign in and enroll an account using the login UI provided by the Intune App SDK.

On Android, use `acquireToken(...)` followed by `registerAndEnrollAccount(...)` instead.

Only available on iOS.

**Since:** 0.1.0

---

### registerAndEnrollAccount(...)[¶](#registerandenrollaccount "Permanent link")

`[](#%5F%5Fcodelineno-28-1)registerAndEnrollAccount(options: RegisterAndEnrollAccountOptions) => Promise<void>
`

Register an account for Mobile Application Management (MAM) and enroll it in the Intune service.

Call this after a successful `acquireToken(...)` call. The enrollment itself is asynchronous; listen for the `enrollmentChange` event to get the enrollment result.

Only available on Android and iOS.

| Param       | Type                                                                |
| ----------- | ------------------------------------------------------------------- |
| **options** | [RegisterAndEnrollAccountOptions](#registerandenrollaccountoptions) |

**Since:** 0.1.0

---

### showDiagnosticConsole()[¶](#showdiagnosticconsole "Permanent link")

`[](#%5F%5Fcodelineno-29-1)showDiagnosticConsole() => Promise<void>
`

Show the diagnostic console of the Intune App SDK.

The console allows the user to inspect the SDK state and collect logs for support requests.

Only available on Android and iOS.

**Since:** 0.1.0

---

### unenrollAccount(...)[¶](#unenrollaccount "Permanent link")

`[](#%5F%5Fcodelineno-30-1)unenrollAccount(options: UnenrollAccountOptions) => Promise<void>
`

Unenroll an account from Mobile Application Management (MAM) and unregister it from the Intune service.

Only available on Android and iOS.

| Param       | Type                                              |
| ----------- | ------------------------------------------------- |
| **options** | [UnenrollAccountOptions](#unenrollaccountoptions) |

**Since:** 0.1.0

---

### addListener('appConfigChange', ...)[¶](#addlistenerappconfigchange "Permanent link")

`[](#%5F%5Fcodelineno-31-1)addListener(eventName: 'appConfigChange', listenerFunc: (event: AppConfigChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when the application configuration changes.

Use `getAppConfig(...)` to read the new configuration values.

Only available on Android and iOS.

| Param            | Type                                                           |
| ---------------- | -------------------------------------------------------------- |
| **eventName**    | 'appConfigChange'                                              |
| **listenerFunc** | (event: [AppConfigChangeEvent](#appconfigchangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('enrollmentChange', ...)[¶](#addlistenerenrollmentchange "Permanent link")

`[](#%5F%5Fcodelineno-32-1)addListener(eventName: 'enrollmentChange', listenerFunc: (event: EnrollmentChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when the enrollment state of an account changes, for example when an enrollment attempt succeeds or fails.

Only available on Android and iOS.

| Param            | Type                                                             |
| ---------------- | ---------------------------------------------------------------- |
| **eventName**    | 'enrollmentChange'                                               |
| **listenerFunc** | (event: [EnrollmentChangeEvent](#enrollmentchangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('policyChange', ...)[¶](#addlistenerpolicychange "Permanent link")

`[](#%5F%5Fcodelineno-33-1)addListener(eventName: 'policyChange', listenerFunc: (event: PolicyChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when the app protection policy changes.

Use `getPolicy(...)` to read the new policy values.

Only available on Android and iOS.

| Param            | Type                                                     |
| ---------------- | -------------------------------------------------------- |
| **eventName**    | 'policyChange'                                           |
| **listenerFunc** | (event: [PolicyChangeEvent](#policychangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('wipeRequested', ...)[¶](#addlistenerwiperequested "Permanent link")

`[](#%5F%5Fcodelineno-34-1)addListener(eventName: 'wipeRequested', listenerFunc: (event: WipeRequestedEvent) => void) => Promise<PluginListenerHandle>
`

Called when the Intune service requests a selective wipe of the account's data.

The Intune App SDK wipes the data it manages, but it does **not** wipe the web layer storage of your Capacitor app (e.g. IndexedDB, Local Storage). Use this event to clean up any data your web code has persisted.

The event is delivered even if the wipe was requested while your app was not running (see the documentation for details).

Only available on Android and iOS.

| Param            | Type                                                       |
| ---------------- | ---------------------------------------------------------- |
| **eventName**    | 'wipeRequested'                                            |
| **listenerFunc** | (event: [WipeRequestedEvent](#wiperequestedevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### removeAllListeners()[¶](#removealllisteners "Permanent link")

`[](#%5F%5Fcodelineno-35-1)removeAllListeners() => Promise<void>
`

Remove all listeners for this plugin.

**Since:** 0.1.0

---

### Interfaces[¶](#interfaces "Permanent link")

#### AcquireTokenResult[¶](#acquiretokenresult "Permanent link")

| Prop            | Type           | Description                                                                                                             | Since |
| --------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------- | ----- |
| **accessToken** | string         | The acquired access token.                                                                                              | 0.1.0 |
| **accountId**   | string         | The Microsoft Entra object ID (OID) of the signed-in account. Use this identifier for all other methods of this plugin. | 0.1.0 |
| **idToken**     | string \| null | The raw ID token of the signed-in account, if available.                                                                | 0.1.0 |
| **tenantId**    | string \| null | The Microsoft Entra tenant ID of the signed-in account, if available.                                                   | 0.1.0 |
| **username**    | string \| null | The username (usually the UPN) of the signed-in account, if available.                                                  | 0.1.0 |

#### AcquireTokenOptions[¶](#acquiretokenoptions "Permanent link")

| Prop            | Type       | Description                                                                                            | Default | Since |
| --------------- | ---------- | ------------------------------------------------------------------------------------------------------ | ------- | ----- |
| **forcePrompt** | boolean    | Whether or not to force the account selection prompt to be shown, even if a user is already signed in. | false   | 0.1.0 |
| **loginHint**   | string     | The username to pre-fill in the sign-in UI.                                                            |         | 0.1.0 |
| **scopes**      | string\[\] | The scopes to request the access token for.                                                            |         | 0.1.0 |

#### AcquireTokenSilentOptions[¶](#acquiretokensilentoptions "Permanent link")

| Prop             | Type       | Description                                                                  | Default | Since |
| ---------------- | ---------- | ---------------------------------------------------------------------------- | ------- | ----- |
| **accountId**    | string     | The Microsoft Entra object ID (OID) of the account to acquire the token for. |         | 0.1.0 |
| **forceRefresh** | boolean    | Whether or not to ignore any cached token and force a token refresh.         | false   | 0.1.0 |
| **scopes**       | string\[\] | The scopes to request the access token for.                                  |         | 0.1.0 |

#### GetAppConfigResult[¶](#getappconfigresult "Permanent link")

| Prop          | Type                   | Description                                                                                                                             | Since |
| ------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **conflicts** | AppConfigConflict\[\]  | The configuration keys for which multiple conflicting values have been deployed.                                                        | 0.1.0 |
| **values**    | Record<string, string> | The merged application configuration values. For keys with conflicting values, the value that the Intune App SDK returns first is used. | 0.1.0 |

#### AppConfigConflict[¶](#appconfigconflict "Permanent link")

| Prop       | Type       | Description                                                   | Since |
| ---------- | ---------- | ------------------------------------------------------------- | ----- |
| **key**    | string     | The configuration key for which conflicting values exist.     | 0.1.0 |
| **values** | string\[\] | All values that have been deployed for the configuration key. | 0.1.0 |

#### GetAppConfigOptions[¶](#getappconfigoptions "Permanent link")

| Prop          | Type   | Description                                                                                  | Since |
| ------------- | ------ | -------------------------------------------------------------------------------------------- | ----- |
| **accountId** | string | The Microsoft Entra object ID (OID) of the account to get the application configuration for. | 0.1.0 |

#### GetEnrolledAccountResult[¶](#getenrolledaccountresult "Permanent link")

| Prop        | Type                                        | Description                                             | Since |
| ----------- | ------------------------------------------- | ------------------------------------------------------- | ----- |
| **account** | [EnrolledAccount](#enrolledaccount) \| null | The enrolled account or null if no account is enrolled. | 0.1.0 |

#### EnrolledAccount[¶](#enrolledaccount "Permanent link")

| Prop          | Type           | Description                                                           | Since |
| ------------- | -------------- | --------------------------------------------------------------------- | ----- |
| **accountId** | string         | The Microsoft Entra object ID (OID) of the enrolled account.          | 0.1.0 |
| **username**  | string \| null | The username (usually the UPN) of the enrolled account, if available. | 0.1.0 |

#### GetPolicyResult[¶](#getpolicyresult "Permanent link")

| Prop                             | Type    | Description                                                                                                                      | Since |
| -------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **contactSyncAllowed**           | boolean | Whether or not the policy allows syncing contacts to the device.                                                                 | 0.1.0 |
| **fileEncryptionRequired**       | boolean | Whether or not the policy requires files to be encrypted. On Android, this reflects whether file encryption is currently in use. | 0.1.0 |
| **managedBrowserRequired**       | boolean | Whether or not the policy requires links to be opened in a managed browser (e.g. Microsoft Edge).                                | 0.1.0 |
| **pinRequired**                  | boolean | Whether or not the policy requires a PIN to access the app.                                                                      | 0.1.0 |
| **saveToPersonalStorageAllowed** | boolean | Whether or not the policy allows saving files to personal (local) storage.                                                       | 0.1.0 |
| **screenCaptureAllowed**         | boolean | Whether or not the policy allows taking screenshots.                                                                             | 0.1.0 |

#### GetPolicyOptions[¶](#getpolicyoptions "Permanent link")

| Prop          | Type   | Description                                                                              | Since |
| ------------- | ------ | ---------------------------------------------------------------------------------------- | ----- |
| **accountId** | string | The Microsoft Entra object ID (OID) of the account to get the app protection policy for. | 0.1.0 |

#### GetSdkVersionResult[¶](#getsdkversionresult "Permanent link")

| Prop                 | Type           | Description                                                               | Since |
| -------------------- | -------------- | ------------------------------------------------------------------------- | ----- |
| **intuneSdkVersion** | string         | The version of the Intune App SDK.                                        | 0.1.0 |
| **msalVersion**      | string \| null | The version of the Microsoft Authentication Library (MSAL), if available. | 0.1.0 |

#### RegisterAndEnrollAccountOptions[¶](#registerandenrollaccountoptions "Permanent link")

| Prop          | Type   | Description                                                                                                  | Since |
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------ | ----- |
| **accountId** | string | The Microsoft Entra object ID (OID) of the account to register and enroll, as returned by acquireToken(...). | 0.1.0 |

#### UnenrollAccountOptions[¶](#unenrollaccountoptions "Permanent link")

| Prop          | Type    | Description                                                                                           | Default | Since |
| ------------- | ------- | ----------------------------------------------------------------------------------------------------- | ------- | ----- |
| **accountId** | string  | The Microsoft Entra object ID (OID) of the account to unenroll.                                       |         | 0.1.0 |
| **wipe**      | boolean | Whether or not the account's data should be wiped as part of the unenrollment. Only available on iOS. | false   | 0.1.0 |

#### PluginListenerHandle[¶](#pluginlistenerhandle "Permanent link")

| Prop       | Type                |
| ---------- | ------------------- |
| **remove** | () => Promise<void> |

#### AppConfigChangeEvent[¶](#appconfigchangeevent "Permanent link")

| Prop          | Type           | Description                                                                | Since |
| ------------- | -------------- | -------------------------------------------------------------------------- | ----- |
| **accountId** | string \| null | The Microsoft Entra object ID (OID) of the affected account, if available. | 0.1.0 |

#### EnrollmentChangeEvent[¶](#enrollmentchangeevent "Permanent link")

| Prop          | Type                                  | Description                                                                | Since |
| ------------- | ------------------------------------- | -------------------------------------------------------------------------- | ----- |
| **accountId** | string \| null                        | The Microsoft Entra object ID (OID) of the affected account, if available. | 0.1.0 |
| **status**    | [EnrollmentStatus](#enrollmentstatus) | The new enrollment status of the account.                                  | 0.1.0 |

#### PolicyChangeEvent[¶](#policychangeevent "Permanent link")

| Prop          | Type           | Description                                                                | Since |
| ------------- | -------------- | -------------------------------------------------------------------------- | ----- |
| **accountId** | string \| null | The Microsoft Entra object ID (OID) of the affected account, if available. | 0.1.0 |

#### WipeRequestedEvent[¶](#wiperequestedevent "Permanent link")

| Prop          | Type           | Description                                                                | Since |
| ------------- | -------------- | -------------------------------------------------------------------------- | ----- |
| **accountId** | string \| null | The Microsoft Entra object ID (OID) of the affected account, if available. | 0.1.0 |

### Type Aliases[¶](#type-aliases "Permanent link")

#### EnrollmentStatus[¶](#enrollmentstatus "Permanent link")

The enrollment status of an account.

`'enrolled' | 'failed' | 'pending' | 'unenrolled'`

## Platform Support[¶](#platform-support "Permanent link")

Not every feature is available on all platforms. The following table lists the notable per-platform differences of the plugin's API:

| Method / Option                    | Android | iOS | Web |
| ---------------------------------- | ------- | --- | --- |
| loginAndEnrollAccount()            | ❌       | ✅   | ❌   |
| unenrollAccount(...) (wipe option) | ❌       | ✅   | ❌   |

Additional notes:

* On Android, use `acquireToken(...)` followed by `registerAndEnrollAccount(...)` instead of `loginAndEnrollAccount()`. The Intune App SDK for Android does not provide its own login UI.
* On Android, `fileEncryptionRequired` reflects whether file encryption is currently **in use** by the Intune App SDK, which is the closest equivalent the SDK exposes.
* The `wipeRequested` event is persisted and replayed on the next app launch if no listener was registered when the wipe arrived. In rare cases the event may be delivered more than once, so make sure your wipe handler is idempotent.
* Policy **enforcement** (PIN, encryption, copy/paste and screenshot restrictions, etc.) is performed automatically by the Intune App SDK once the native integration is in place. The JavaScript API exists for the parts that enforcement cannot do: enrolling accounts, reading configuration, adapting your UI to the policy, and cleaning up web storage on selective wipe.

## Choosing between the MAM and MDM channel[¶](#choosing-between-the-mam-and-mdm-channel "Permanent link")

Organizations can deliver app configuration through two different channels, and administrators frequently mix them up. This plugin covers the **MAM channel**; the [Managed Configurations](https://capawesome.io/docs/sdks/capacitor/managed-configurations/) plugin covers the **MDM channel**:

|                            | MAM channel (this plugin)                       | MDM channel ([Managed Configurations](https://capawesome.io/docs/sdks/capacitor/managed-configurations/)) |
| -------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Device enrollment required | No                                              | Yes                                                                                                       |
| Delivered via              | Intune App SDK (Intune service)                 | RestrictionsManager / com.apple.configuration.managed                                                     |
| Targeted at                | The signed-in account (identity)                | The device                                                                                                |
| EMM vendor                 | Microsoft Intune only                           | Any EMM/MDM vendor                                                                                        |
| Typical scenario           | BYOD / app protection without device management | Corporate-owned, fully managed devices                                                                    |

If your organization deploys the app configuration policy with **"Managed apps"** as the delivery channel in the Intune admin center, use this plugin. If it is deployed with **"Managed devices"**, use the Managed Configurations plugin. Apps that must support both scenarios should read both channels.

## Testing[¶](#testing "Permanent link")

Exercising Mobile Application Management (MAM) requires infrastructure that cannot be simulated locally:

* A **Microsoft Intune tenant** with **Intune licenses** and a **licensed test user**.
* An **app protection policy** and (optionally) an **app configuration policy** targeted at the test user and your app.
* On Android, the **Company Portal** app installed on the test device.

Without a tenant, the plugin compiles and loads, but enrollment fails with `AccountNotLicensed`\-style errors and no policy is applied. Building this plugin (e.g. via `npm run verify`) only proves that the code compiles — it does not exercise any MAM functionality.

## Licensing[¶](#licensing "Permanent link")

The Microsoft Intune App SDKs for Android and iOS are proprietary software, licensed by Microsoft under the [Microsoft License Terms Intune App SDK](https://github.com/msintuneappsdk/ms-intune-app-sdk-ios/blob/master/Microsoft%20License%20Terms%20Intune%20App%20SDK%20for%20iOS.pdf). This plugin does **not** bundle or modify the Intune App SDKs — it declares them as dependencies and downloads them from Microsoft's official repositories at build or install time. By building an app with this plugin, you accept Microsoft's license terms for the Intune App SDK. The Microsoft Authentication Library (MSAL) is licensed under the MIT license. Using the plugin requires a Microsoft Intune tenant with appropriate licenses. The MIT license of this plugin covers the wrapper code only, not the Microsoft SDKs.

Note that Microsoft's license terms also place obligations on **your app** as the distributor of the Intune App SDK binaries — among other things regarding your app's own functionality and copyright notice, license compatibility, and indemnification. Review the license terms linked above before shipping your app.

## FAQ[¶](#faq "Permanent link")

### How is this plugin different from other similar plugins?[¶](#how-is-this-plugin-different-from-other-similar-plugins "Permanent link")

It integrates the Microsoft Intune App SDK for Mobile Application Management on Android and iOS through a fully typed API, enforcing app protection policies and exposing them as typed booleans so you can adapt your UI, acquiring tokens via MSAL, and enrolling accounts without device enrollment. It emits selective-wipe events so you can purge the web-layer storage (such as IndexedDB and Local Storage) that the SDK cannot reach itself, and it is built against current Intune and MSAL versions, which matters because Microsoft blocks apps that ship outdated SDKs. It is a free, actively maintained plugin that stays current with the latest Capacitor version.

### Do I need a Microsoft Intune tenant to use this plugin?[¶](#do-i-need-a-microsoft-intune-tenant-to-use-this-plugin "Permanent link")

Yes. This plugin wraps the Microsoft Intune App SDK, which requires a Microsoft Intune tenant, Intune licenses, and an app registration in Microsoft Entra ID (see [Testing](#testing)).

### Why does the plugin require iOS 17?[¶](#why-does-the-plugin-require-ios-17 "Permanent link")

The current Microsoft Intune App SDK for iOS requires iOS 17 or later. Microsoft actively blocks apps built with outdated Intune App SDK versions, so this plugin always tracks Microsoft's current SDK line instead of pinning an older one.

### Does this plugin enforce the app protection policies?[¶](#does-this-plugin-enforce-the-app-protection-policies "Permanent link")

Yes, automatically. Once the native integration (MAM build plugin on Android, SDK integration on iOS) is in place, the Intune App SDK enforces PIN, encryption, data transfer and screenshot restrictions itself. The JavaScript API of this plugin is for the parts enforcement cannot do: enrollment, introspection, and cleaning up web storage on selective wipe.

### What is the difference between this plugin and the Managed Configurations plugin?[¶](#what-is-the-difference-between-this-plugin-and-the-managed-configurations-plugin "Permanent link")

This plugin reads the MAM channel (Intune App SDK, no device enrollment required). The [Managed Configurations](https://capawesome.io/docs/sdks/capacitor/managed-configurations/) plugin reads the MDM channel (device enrollment required, works with any EMM vendor). See [Choosing between the MAM and MDM channel](#choosing-between-the-mam-and-mdm-channel).

### Can I use this plugin with Ionic, React, Vue or Angular?[¶](#can-i-use-this-plugin-with-ionic-react-vue-or-angular "Permanent link")

Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.

## Newsletter[¶](#newsletter "Permanent link")

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).

## Changelog[¶](#changelog "Permanent link")

See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/intune/CHANGELOG.md).

## License[¶](#license "Permanent link")

See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/intune/LICENSE).

---

1. This project is not affiliated with, endorsed by, sponsored by, or approved by Microsoft Corporation or any of its affiliates or subsidiaries. "Microsoft" and "Microsoft Intune" are trademarks of the Microsoft group of companies. [↩](#fnref:1 "Jump back to footnote 1 in the text")

July 13, 2026 

Back to top

```json
{"@context": "https://schema.org", "@graph": [{"@type": "TechArticle", "@id": "https://capawesome.io/docs/sdks/capacitor/intune/#article", "headline": "Capacitor Intune Plugin for Android & iOS", "name": "Capacitor Intune Plugin for Android & iOS", "description": "Unofficial Capacitor plugin for the Microsoft Intune App SDK to enforce app protection policies (MAM) in your Android and iOS apps.", "inLanguage": "en", "url": "https://capawesome.io/docs/sdks/capacitor/intune/", "mainEntityOfPage": "https://capawesome.io/docs/sdks/capacitor/intune/", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "about": {"@id": "https://capawesome.io/docs/sdks/capacitor/intune/#software"}}, {"@type": "SoftwareSourceCode", "@id": "https://capawesome.io/docs/sdks/capacitor/intune/#software", "name": "Capacitor Intune Plugin for Android & iOS", "description": "Unofficial Capacitor plugin for the Microsoft Intune App SDK to enforce app protection policies (MAM) in your Android and iOS apps.", "url": "https://capawesome.io/docs/sdks/capacitor/intune/", "programmingLanguage": "TypeScript", "runtimePlatform": "Capacitor", "codeRepository": "https://github.com/capawesome-team", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}}]}
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "How is this plugin different from other similar plugins?", "acceptedAnswer": {"@type": "Answer", "text": "It integrates the Microsoft Intune App SDK for Mobile Application Management on Android and iOS through a fully typed API, enforcing app protection policies and exposing them as typed booleans so you can adapt your UI, acquiring tokens via MSAL, and enrolling accounts without device enrollment. It emits selective-wipe events so you can purge the web-layer storage (such as IndexedDB and Local Storage) that the SDK cannot reach itself, and it is built against current Intune and MSAL versions, which matters because Microsoft blocks apps that ship outdated SDKs. It is a free, actively maintained plugin that stays current with the latest Capacitor version."}}, {"@type": "Question", "name": "Do I need a Microsoft Intune tenant to use this plugin?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. This plugin wraps the Microsoft Intune App SDK, which requires a Microsoft Intune tenant, Intune licenses, and an app registration in Microsoft Entra ID (see Testing)."}}, {"@type": "Question", "name": "Why does the plugin require iOS 17?", "acceptedAnswer": {"@type": "Answer", "text": "The current Microsoft Intune App SDK for iOS requires iOS 17 or later. Microsoft actively blocks apps built with outdated Intune App SDK versions, so this plugin always tracks Microsoft's current SDK line instead of pinning an older one."}}, {"@type": "Question", "name": "Does this plugin enforce the app protection policies?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, automatically. Once the native integration (MAM build plugin on Android, SDK integration on iOS) is in place, the Intune App SDK enforces PIN, encryption, data transfer and screenshot restrictions itself. The JavaScript API of this plugin is for the parts enforcement cannot do: enrollment, introspection, and cleaning up web storage on selective wipe."}}, {"@type": "Question", "name": "What is the difference between this plugin and the Managed Configurations plugin?", "acceptedAnswer": {"@type": "Answer", "text": "This plugin reads the MAM channel (Intune App SDK, no device enrollment required). The Managed Configurations plugin reads the MDM channel (device enrollment required, works with any EMM vendor). See Choosing between the MAM and MDM channel."}}, {"@type": "Question", "name": "Can I use this plugin with Ionic, React, Vue or Angular?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects."}}], "url": "https://capawesome.io/docs/sdks/capacitor/intune/"}
```
