---
url: 'https://www.corbado.com/blog/passkeys-managed-ios-android-testing'
title: 'How to Test Passkeys on Managed iOS & Android Devices'
description: 'Learn to test passkey behavior on managed iOS & Android devices where syncing is disabled. A technical, hands-on guide for developers and testers.'
lang: 'en'
author: 'Vincent Delitz'
date: '2025-06-16T17:50:24.449Z'
lastModified: '2026-10-02T06:00:49.550Z'
keywords: 'managed device, managed ios, managed android, managed android test, managed ios test'
category: 'Passkeys Strategy'
---

# How to Test Passkeys on Managed iOS & Android Devices

## Key Facts

- Testing passkeys on managed devices requires simulating corporate MDM policies that
  disable syncing, forcing passkeys to become device-bound in the Secure Enclave or
  Trusted Execution Environment.
- On iOS, a **`.mobileconfig` profile** with 'Disallow iCloud Keychain sync' enables
  managed testing: iOS 18 allows device-bound passkey creation while iOS 16 and 17 block
  it entirely.
- On Android, the **Test DPC** enrollment code `afw#testdpc` provisions a fully managed
  device; enabling `DISALLOW_AUTOFILL_SERVICE` blocks Google Password Manager from saving
  or providing passkeys.
- The **`DISALLOW_AUTOFILL_SERVICE`** policy on Android 14 blocks passkey creation
  entirely: no user prompt appears and the Credential Manager API returns an error to the
  application.

## 1. Introduction: Testing Passkeys on managed Devices

This guide offers developers and test engineers a comprehensive walkthrough to simulate
enterprise-managed environments for testing passkey behavior in native
[iOS](https://www.corbado.com/blog/webauthn-errors) and [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)
applications. We focus on scenarios where corporate policies disable passkey syncing via
[iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain) and
[Google Password Manager](https://www.corbado.com/blog/how-to-use-google-password-manager), a common setup in
corporate environments. This article is technical and based on real-world testing with
physical devices.

The guide details the setup of a **managed iOS test** and a **managed Android test**
environment. By simulating corporate policies that disable passkey syncing, you can
validate your application's passkey implementation on managed devices. The procedures are
based on hands-on testing with physical devices.

## 2. How to Test Passkeys on managed iOS Devices

Our goal is to create a test environment that mimics an iPhone where a Mobile Device
Management (MDM) profile forbids [iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain)
synchronization. This will force passkeys to be "device-bound," stored only in the
device's [Secure Enclave](https://www.corbado.com/glossary/secure-enclave).

[Watch on YouTube](https://www.youtube.com/watch?v=0hRYXHESA24)

### 2.1. Prerequisites and Tools

- A physical test iPhone
- A macOS computer
- **iMazing Profile Editor**: A free tool for creating Apple configuration profiles.
  Download from the [iMazing website](https://imazing.com/profile-editor) or the Mac App
  Store.
- **Apple Configurator**: A free tool for supervising devices and deploying profiles.
  Download from the
  [Mac App Store](https://apps.apple.com/us/app/apple-configurator/id1037126344).

Relying parties can determine if a passkeys work on a device by using the
´isUserVerifyingPlatformAuthenticatorAvailable()´ JavaScript API in the browser.

### 2.2 Step-by-Step Setup Guide

Let's review the steps to configure the test environment.

#### 2.2.1 Create a "Disable iCloud Keychain" Profile

We will use the iMazing Profile Editor to create a profile that disables keychain syncing.

1. Open iMazing Profile Editor.
2. Create a new profile (**File** &gt; **New**).

![new profile imazing profile editor](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/new_profile_imazing_profile_editor_7f82e1f8a4.png)

3. In the **General** section, fill out the details:
    - **Name**: A descriptive name, e.g., "Disable iCloud Keychain Sync".
    - **Identifier**: A unique identifier, e.g., `com.yourcompany.disablekeychainsync`.

![imazing profile editor](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/imazing_profile_editor_199c1ee08e.png)

4. In the left sidebar, find the **Restrictions** payload and click **Add Payload**.

![imazing profile editor restrictions](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/imazing_profile_editor_restrictions_3837ee2edb.png)

5. Navigate to the **iCloud** tab within the Restrictions payload.
6. Check the box for **Disallow iCloud Keychain sync**.

![imazing profile editor restrictions icloud](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/imazing_profile_editor_restrictions_icloud_33a3385130.png)

![imazing profile editor restrictions icloud deactivated](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/imazing_profile_editor_restrictions_icloud_deactivated_f94911908a.png)

7. Save the profile (**File** &gt; **Save**). It will be saved as a `.mobileconfig` file.

#### 2.2.2 Deploy the Profile to the iPhone

To install the profile, the iPhone must be "supervised," which typically requires a
factory reset.

1. Connect the supervised iPhone to your Mac.
2. Open Apple Configurator.
3. Right-click on the device, select **Add** &gt; **Profiles...**.

![apple configurator add profile](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/apple_configurator_add_profile_4f97f4e089.png)

4. Choose the `.mobileconfig` file you just created.
5. On the iPhone, you will likely need to approve the installation. Open the **Settings**
   app

![choose device for profile installation](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/choose_device_for_profile_installation_d48cfdfcf9.PNG)

![managed profile downloaded](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/managed_profile_downloaded_b60ce685b6.PNG)

6. Search for "Profile" and open the "VPN & Device Management" section.
7. On the bottom of the screen should be the profile you just transferred. Click on it.
8. Tap **Install** in the top-right corner and follow the on-screen prompts to complete
   the installation.

![open managed profile](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/open_managed_profile_ff39135c33.PNG)

9. Confirm by clicking **Install** again.

![install profile](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/install_profile_4896025f22.PNG)

10. Click **Install** again.

![confirm profile installation](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/confirm_profile_installation_f331d83895.PNG)

11. The profile is successfully installed.

![managed profile installed](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/managed_profile_installed_e35a957652.PNG)

### 2.3 Testing Scenarios and Expected Behavior

With the "Disable [iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain)" profile active, passkeys
become device-bound. They are created and stored exclusively in the device's
[Secure Enclave](https://www.corbado.com/glossary/secure-enclave) and will not synchronize across a user's
devices. This is a critical **managed iOS test** case.

The user experience during [passkey creation](https://www.corbado.com/blog/passkey-creation-best-practices) may
differ slightly across [iOS](https://www.corbado.com/blog/webauthn-errors) versions, but the underlying principle
remains the same.

#### 2.3.1 Observations on managed iOS 18

- **Passkey Creation**: When a user attempts to
  [create a passkey](https://www.corbado.com/blog/passkey-creation-best-practices), the operating system will
  typically proceed with the creation. However, [iOS](https://www.corbado.com/blog/webauthn-errors) may present a
  notification to inform the user that the passkey will only be saved on the current
  device and will not be available on their other devices due to organizational
  restrictions. The `ASAuthorizationController` will complete successfully, returning a
  valid credential.
- **Passkey Login**: Authentication with an existing
  [device-bound passkey](https://www.corbado.com/blog/device-bound-synced-passkeys) functions as expected.
  Logging in with a passkey that was previously synced via iCloud Keychain before the
  policy was enforced also remains operational.

![ios 18 create passkey managed iphone](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/ios_18_create_passkey_managed_iphone_fa04f50f7c.jpeg)

#### 2.3.2 Observations on managed iOS 17

- **Passkey Creation**: The behavior is different to
  [iOS 18](https://www.corbado.com/blog/ios-18-passkeys-automatic-passkey-upgrades).
  [Passkey creation](https://www.corbado.com/blog/passkey-creation-best-practices) cannot be completed and the
  error message from below appears.
- **Passkey Login**: Works without issue for both
  [device-bound passkeys](https://www.corbado.com/faq/are-passkeys-device-specific) and previously synced
  passkeys.

![ios 17 create passkey managed iphone](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/ios_17_create_passkey_managed_iphone_cd93a9112b.jpeg)

#### 2.3.3 Observations on managed iOS 16

- **Passkey Creation**: The behavior is consistent to
  [iOS 17](https://www.corbado.com/blog/apple-passkeys-integration).
  [Passkey creation](https://www.corbado.com/blog/passkey-creation-best-practices) cannot be completed and the
  error message from below appears.
- **Passkey Login**: Works without issue for both
  [device-bound passkeys](https://www.corbado.com/faq/are-passkeys-device-specific) and previously synced
  passkeys.

![ios 16 create passkey managed iphone](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/ios_16_create_passkey_managed_iphone_741f8b75ac.jpeg)

## 3. How to Test Passkeys on managed Android Devices

For [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android), our goal is to set up a "fully
managed" device and use a Device Policy Controller (DPC) to block passkey syncing via
[Google Password Manager](https://www.corbado.com/blog/how-to-use-google-password-manager). This setup is a
common scenario for a corporate **managed device**.

### 3.1 Prerequisites and Tools

- An [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) device that has been or can be
  factory reset.
- (Optional) Android Debug Bridge (`adb`) installed on your computer for inspection.

### 3.2 Step-by-Step Setup Guide

Let's see the different steps needed to get to our test setup.

#### 3.2.1 Provision the Device with Test DPC

We will use a special code during setup to install Google's **Test DPC** app as the device
owner. This grants it full administrative control.

1. **Factory reset** the Android device.
2. Proceed through the initial setup screens (language, Wi-Fi, etc.).
3. When you reach the Google Account sign-in screen, instead of an email, enter the code:
   `afw#testdpc`.
4. The system will now download and install the Test DPC app.
5. Follow the on-screen prompts to set up the device. Agree to make Test DPC the owner of
   the device. Choose to set up a **fully managed device** ("USE FOR WORK ONLY").

#### 3.2.2 Configure Policies with Test DPC

Once the device is set up, we'll use the Test DPC app to apply the necessary restrictions.

1. Open the Test DPC app from the app drawer.

![android testdpc](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/android_testdpc_51114d22d5.png)

2. Search for "user restrictions" and select **Set user restrictions**.
3. Find and enable the following two restrictions by toggling them on:
    - **Disallow autofill** (`DISALLOW_AUTOFILL_SERVICE`): This is the primary policy that
      prevents [Google Password Manager](https://www.corbado.com/blog/how-to-use-google-password-manager) (and
      other autofill services) from saving or providing passkeys.

![testdpc disallow autofill](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/testdpc_disallow_autofill_e9159365ca.png)

```
*   **Disallow modify accounts** (`DISALLOW_MODIFY_ACCOUNTS`): This adds a secondary layer of restriction, preventing users from adding or removing accounts, which can interfere with sync services.
```

![testdpc disallow modify accounts](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/testdpc_disallow_modify_accounts_5a00911893.png)

### 3.3 Testing Scenarios & Observed Behavior

With the above configuration, passkeys should become device-bound. They would be created
and stored only in the local Trusted Execution Environment (TEE) and will not sync.

For testing, you might need to enable Chrome from the system apps. To do so:

1. Open the Test DPC app.
2. Search for "enable system apps".
3. Click on the Chrome icon to enable and use it for testing.

Below are the results from our **managed Android test** on different OS versions.

#### 3.3.1 Observations on managed Android 12

Passkey creation and login work as long as a device screen lock is set up. However, the
passkey is not synced via Google Password Manager, thus it's only available on this one
device, making it effectively device-bound.

#### 3.3.2 Observations on managed Android 14

On Android 14, our **managed Android test** revealed that the `DISALLOW_AUTOFILL_SERVICE`
policy is highly restrictive. When an application initiates the create call from the
Credential Manager API, the operating system may not show any user-facing prompt for
passkey creation, including the screen lock or biometrics confirmation. Consequently,
passkey creation fails and the API returns an error to the application. This makes it
impossible to create or test [device-bound passkeys](https://www.corbado.com/faq/are-passkeys-device-specific)
under this specific policy configuration.

### 3.4 Results Overview

The following diagram summarizes the observed behavior in our test environments.

```mermaid
graph TD;
    subgraph "Managed Passkey Test Environment Summary";
        direction LR;

        subgraph "iOS (Managed via Profile)";
            direction TB;
            A["<b>Policy:</b><br/>'Disallow iCloud Keychain'"] --> B["<b>Passkey Creation:</b><br/>Succeeds (Device-Bound)<br/>User is notified it won't sync."];
            A --> C["<b>Passkey Sync:</b><br/>Blocked by Policy"];
        end

        subgraph "Android (Managed via DPC)";
            direction TB;
            D["<b>Policy:</b><br/>'DISALLOW_AUTOFILL_SERVICE'"] --> E["<b>Passkey Creation:</b><br/>Blocked on Android 14+<br/>May succeed on older versions (Device-Bound)"];
            D --> F["<b>Passkey Sync:</b><br/>Blocked by Policy"];
        end
    end
    style A fill:#f9f9f9,stroke:#333,stroke-width:2px
    style B fill:#e8f5e9,stroke:#333,stroke-width:1px
    style C fill:#ffebee,stroke:#333,stroke-width:1px
    style D fill:#f9f9f9,stroke:#333,stroke-width:2px
    style E fill:#fff8e1,stroke:#333,stroke-width:1px
    style F fill:#ffebee,stroke:#333,stroke-width:1px
```

## 4. How Corbado can help

This guide gives you three devices with policies you set yourself. Production gives you a
fleet whose MDM profiles you never see, configured by IT departments you do not talk to.
[Corbado Observe](https://www.corbado.com/observe) is the
[authentication observability](https://www.corbado.com/blog/authentication-observability) layer, and for native
apps it records the device signals that a management policy actually moves.

[Video: Device health](https://www.corbado.com/videos/features/device-health.mp4) ([See how Corbado Connect ships this](https://www.corbado.com/connect))

- **The attributes an MDM profile changes.** Every app session carries the screen lock the
  device reports (biometric, passcode or none), whether Bluetooth is available, the Google
  Play Services version and the app build and locale. A managed Android device running
  without Play Services, or an enrolled iPhone with no lock set, is visible in that record
  before anyone opens a ticket.
- **Device-bound credentials as a number.** A credential that reports the internal
  transport and comes back with its backup bit clear is a
  [device-bound passkey](https://www.corbado.com/blog/device-bound-synced-passkeys), and Observe records it as
  one. The share of your base that "Disallow iCloud Keychain" actually produced is then a
  figure you can read off directly.
- **Failures clustered by device model and OS version.** The Android 14 creation failure
  described above shows no prompt and returns an error to the app. Observe groups passkey
  failures by OS, browser, device model and [authenticator](https://www.corbado.com/glossary/authenticator), so a
  policy that breaks creation on one OS version is visible as that one version while the
  overall enrollment rate is still flat.

[Corbado Connect](https://www.corbado.com/connect) turns a finding from your managed test devices into policy. A
ruleset decides [passkey login](https://www.corbado.com/blog/passkey-login-best-practices), append and management
separately, so creation can be blocked on a device model while login with an existing
credential keeps working there, and the whole ruleset can be replayed against recorded
traffic as a simulation before it takes effect. That is the piece an MDM profile cannot
give you, because the profile is set by someone else.

## 5. Conclusion: Testing Passkeys on managed Devices

Testing passkeys in an environment that simulates corporate restrictions is a
non-negotiable step for any application intended for enterprise use. By following this
guide, you can configure both **managed iOS** and **managed Android** devices to create
robust test cases for device-bound passkeys.

This validation ensures that your application handles these scenarios gracefully, provides
clear user feedback, and maintains a high standard of reliability and security.
Proactively testing on a **managed device** will prevent unexpected issues for your
enterprise customers and is a critical part of a comprehensive quality assurance strategy.

## Frequently Asked Questions

### How do I set up a managed iOS passkey test environment without a real MDM server?

Use the free iMazing Profile Editor to create a .mobileconfig file with the 'Disallow
iCloud Keychain sync' restriction enabled, then deploy it to a supervised iPhone via Apple
Configurator. The iPhone must be supervised, which typically requires a factory reset, but
no paid MDM server is necessary.

### Why does passkey creation fail on managed Android 14 but succeed on Android 12 with the same policy?

On Android 14, the DISALLOW_AUTOFILL_SERVICE policy prevents the OS from showing any
user-facing prompt during passkey creation, including biometric or screen lock
confirmation, so the Credential Manager API returns an error. On Android 12, passkey
creation succeeds under the same policy and the credential is stored locally in the TEE
without syncing to Google Password Manager.

### What is the difference in passkey creation behavior between iOS 17 and iOS 18 on a managed device?

On managed iOS 18 with iCloud Keychain sync disabled, passkey creation completes
successfully via ASAuthorizationController and the user receives a notification that the
passkey is device-bound only. On iOS 16 and iOS 17 under the same restriction, passkey
creation cannot be completed and an error message is displayed.

### How can I detect programmatically whether passkeys are available on a managed device before prompting the user?

Relying parties can use the isUserVerifyingPlatformAuthenticatorAvailable() JavaScript API
in the browser to determine if a passkey-capable platform authenticator is available on
the device. This check helps applications handle managed device scenarios gracefully
before initiating a passkey creation or authentication flow.
