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

# Passkey Creation: Automatic Upgrade (conditional create)

> Native apps can create a passkey silently after a user signs in with an autofilled password, with no prompt and no extra step. This flow explains the conditions, the platform APIs and what your server must tolerate.

## Automatic Passkey Creation in Native Apps (Conditional Create)

When a user signs in to your app with a password supplied by their credential manager, the OS can create a passkey for that account **without showing any UI at all**. There is no sheet, no biometric prompt and no interruption to your app. The credential manager notifies the user afterwards.

This is the same conditional create mechanism as the [web automatic upgrade](/passkey-ui-flows/web/passkey-creation/automatic-upgrade), available to native apps on both platforms. It is the highest-yield creation flow available, because it costs the user nothing.

<Info>
  **Support (August 2026):** iOS 18+, iPadOS 18+, macOS 15+ and visionOS 2+ via `ASAuthorizationPlatformPublicKeyCredentialProvider`. Android relying parties use `androidx.credentials` **1.6.0** (stable since 8 April 2026); Google Password Manager support requires Google Play services 25.13 or newer. On both platforms, the user's preferred credential manager can participate when it supports conditional registration. Android providers receive these requests through `CredentialProviderEventsService`, whose provider-facing library is separately versioned and may not yet be implemented by every provider.
</Info>

<Steps>
  <Step title="User signs in with an autofilled password">
    * The user's credential manager fills a saved username and password for your app, and the sign-in succeeds.
    * This is the hard precondition. Sign-ins that do not use a stored password (magic links, SMS or email OTP, and federated or SSO sign-in) do not qualify.
  </Step>

  <Step title="Your app requests a conditional registration">
    * Immediately after the successful password sign-in, the app issues a registration request marked as conditional.
    * On Apple platforms, request `ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest.RequestStyle.conditional`.
    * On Android, set `isConditional = true` on `CreatePublicKeyCredentialRequest` and send it through `CredentialManager.createCredential()`.
  </Step>

  <Step title="The credential manager decides, silently">
    * The provider checks its own conditions: a matching password was filled recently, the device is set up for passkeys, and no passkey exists yet for this account.
    * If an eligibility condition fails, the request returns an expected no-op error and **no UI is shown to the user**. Nothing went wrong; a passkey simply was not created this time.
  </Step>

  <Step title="Passkey created, user informed by the system">
    * On success the passkey is created with no prompt and no user interaction.
    * The credential manager, not your app, notifies the user that a passkey now exists. Do not add your own confirmation screen on top of it.
  </Step>
</Steps>

### What your server must tolerate

<Warning>
  **The registration response carries `UP` and `UV` as `false`.** No user interaction takes place, so there is no user presence or user verification to assert. A registration verifier configured to reject `UV=0` will fail every automatic upgrade. This is the most common integration bug on this flow, and it fails silently from the user's point of view.
</Warning>

### Platform differences worth planning for

<AccordionGroup>
  <Accordion title="Duplicate prevention differs by platform">
    On Android, include every server-known credential ID in `excludeCredentials`. This prevents the selected provider from creating a duplicate of a credential it already holds, and a duplicate surfaces through `InvalidStateError`. On Apple platforms the native registration request has **no** `excludedCredentials` property, so duplicate avoidance is delegated entirely to the credential manager. Do not suppress the conditional request merely because your server knows that the account has another passkey: it may live in a different provider or may not be available on this device. Issue the request after an eligible password login and let the credential manager determine whether it already holds a matching passkey.
  </Accordion>

  <Accordion title="Android uses the preferred credential provider">
    Credential Manager forwards a conditional create request to the user's preferred provider when the provider supports the flow. Google Password Manager requires Google Play services 25.13 or newer; older versions may fail with `CreateCredentialUnsupportedException`. Third-party providers can receive conditional requests through `CredentialProviderEventsService`, but support is provider-dependent, so keep the explicit creation fallback described below.
  </Accordion>

  <Accordion title="Apple platforms support third-party credential managers">
    Credential managers implement `performWithoutUserInteractionIfPossible(passkeyRegistration:)` and declare `SupportsConditionalPasskeyRegistration` in their extension capabilities. A provider is not permitted to show UI while fulfilling the request.
  </Accordion>

  <Accordion title="Expected failures should not interrupt the user">
    Do not show a user-facing error when conditional creation is simply ineligible, but do not swallow every exception. On Android, handle `CreateCredentialNoCreateOptionException` as an expected no-op and inspect `CreatePublicKeyCredentialDomException.domError` for expected `InvalidStateError`, `NotAllowedError` and `AbortError` outcomes. Record unsupported, provider-configuration, malformed-request and unexpected failures in telemetry. On Apple platforms, suppress UI for eligibility or cancellation outcomes while logging association, entitlement, request-construction and unexpected failures. Retry expected no-op outcomes on the user's next password sign-in.
  </Accordion>

  <Accordion title="Users can switch it off">
    Google Password Manager offers a setting that disables automatic passkey creation and syncs it across the user's devices. Plan for adoption that never reaches 100%, and keep an explicit creation path such as the [post-login nudge](/passkey-ui-flows/native/passkey-creation/non-mfa) available.
  </Accordion>
</AccordionGroup>

<Tip>
  Because the passkey is created without the user choosing to create it, keep [passkey management](/passkey-ui-flows/native/passkey-management) easy to find. A user who is surprised by the system notification should be able to see and remove the credential immediately.
</Tip>

### Further reading

* [Conditional create](https://developer.chrome.com/docs/identity/webauthn-conditional-create) and [automatic passkey creation on Android](https://developer.chrome.com/blog/automatic-passkey-creation-android), Chrome for Developers
* [Streamline sign-in with passkey upgrades and credential managers](https://developer.apple.com/videos/play/wwdc2024/10125/), WWDC24 session 10125
* [Create passkeys](https://developer.android.com/identity/passkeys/create-passkeys), Android Developers
* [CredentialProviderEventsService](https://developer.android.com/reference/androidx/credentials/providerevents/service/CredentialProviderEventsService), Android Developers
* [Conditional create explained](https://www.corbado.com/blog/conditional-create-passkeys), Corbado blog
