safari webauthn user activated events coverWebAuthn Know-How

Safari WebAuthn User Gesture Requirements Not Detected

Analysis of “To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events”-error & user gesture requirements

Blog-Post-Author

Vincent

Created: May 14, 2024

Updated: June 19, 2024


Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.

  1. Introduction: User Gesture Requirements in Safari

  2. What is the “User gesture is not detected” Error?

  3. Timeline: Different Safari Versions and User Gesture Requirements

    3.1 Overview of Version and Announcements of Technical Changes

    3.2 Current Market Shares of Different iOS Versions (Q1 2024)

  1. Recommendation

  2. Conclusion: The Ways to Deal with User Gesture Requirements

1. Introduction: User Gesture Requirements in Safari#

In the past, authentication was primarily managed in the backend, largely independent of the browser's implementation standards. However, the introduction of social logins began to shift some of these challenges to the frontend, necessitating the integration of redirects and layers to accommodate the OAuth protocol used to integrate SSO via social logins. The emergence of passkeys has further expanded these frontend responsibilities by the implementation of the WebAuthn standard. This standard, unfortunately, is sometimes interpreted differently across browsers, leading to unique challenges.

In this blog post, we aim to help developers who are navigating the complexities of developing passkey-based applications, especially those experiencing problems with WebAuthn operations on Apple devices using Safari, where you receive `User gesture is not detected. We are going to cover:

  • What user gesture requirements in Safari are and when they have been introduced / changed: We want to give an overview of the evolution of user gesture requirements and explain what the user gesture errors are about.

  • How to avoid user gesture errors: We will give our recommendation on how to structure a passkey-login to avoid user gesture errors.

Having encountered and investigated this issue ourselves, we want to share our insights here.

2. What is the “User gesture is not detected” Error?#

With iOS 14, iPadOS 14 and Safari 14, Apple introduced Touch ID / Face ID for the web, which for the first time allowed leveraging the local hardware security module (HSM) for the creation of WebAuthn credentials. This was before passkeys were introduced on Apple devices with iOS 16.

Touch ID Face ID for Web

To prevent users getting distracting operating system dialogues from pages triggering WebAuthn operations without user consent, Apple implemented a protection that requires the user to have directly triggered the following WebAuthn request. Those actions were called “user activation” and therefore, for WebAuthn calls, were subsequently protected and had “user gesture requirements”. In the first version, there was only a narrow list of use cases that were counted as user gestures:

  • Calling the API Directly from User Activated Events
  • Propagating User Gestures Through XHR Events
  • Propagating User Gestures Through Fetch API
  • Propagating User Gestures Through setTimeout (max one second)
Slack Icon

Become part of our Passkeys Community for updates and support.

Join

This was a problem for relying parties and websites that had already created flows that would automatically trigger such an operation in a two-factor authentication process. An example can be seen here from AWS today:

Video: AWS Login with automatic WebAuthn Authentication call

After requesting the user identifier (e.g. username / email) and password (first factor), the user is redirected to an intermediate page that would show an animation and at the same time automatically triggers the second factor validation via a WebAuthn call. On Safari 14, this would immediately result in one of those error messages:

  • To use the WebAuthn API, call 'navigator.credentials.create' or 'navigator.credentials.get' within user activated events
  • User gesture is not detected. To use the WebAuthn API, call 'navigator.credentials.create' within user activated events.
  • NotAllowedError: This request has been cancelled by the user.

Large companies suffered at that time under this breaking change (Firefox & Chrome both did not require user gestures prior to WebAuthn operations). Followed by a heated discussions among WebAuthn working group members, there was a prominent patch whitelisting some important Relying Parties (Dropbox, Microsoft, Google, Twitter/X, Facebook):

Whitelisting Large Relying PartiesTaken from: https://github.com/w3c/webauthn/issues/1293#issuecomment-829789071

Although there was some understanding of the reason why this was implemented, the WebAuthn standard was a bit ambiguous about “requiring user gesture”. It was unclear if a user gesture for verification was meant, or if the browser should reasonably make sure that the user actually triggered the action.

Substack Icon

Subscribe to our Passkeys Substack for the latest news, insights and strategies.

Subscribe

Starting with iOS16, this was addressed and relaxed:

Safari 16 FreebieSee original Tweet

A “freebie” was introduced, meaning that every website can trigger one `navigator.credentials.get()` call without a user gesture until the next page reload or the next successful WebAuthn operation happen.

Depending on the type of the application and how the page is built, there can be some problems:

  • Freebie attempt consumed by Conditional UI: The freebie attempt might be consumed by Conditional UI if it is triggered at page load and not when entering the field with an `onClick` event.

  • User action is not detected as “user gesture”: This can happen within Single Page Applications (SPA) in case the context, where the WebAuthn call is made, is different from the one initiating the user action and therefore destroys the link between the user action / gesture and the following WebAuthn call.

Here is an example of an implementation that triggers the user gesture error on an iOS 16 simulator. Follow these steps to experience the error yourself or watch the video below:

  1. Step 1: Before the video started, the freebie attempt was already consumed by Conditional UI.

  2. Step 2: We switch to a new waiting screen and start the WebAuthn authentication ceremony.

  3. Step 3: Safari immediately interrupts the process with an error

  4. Step 4: We trigger the WebAuthn authentication ceremony by clicking on “Try again”. This time it works (because of the user gesture).

Video: Safari user gesture requirements in action blocking authentication

An important detail here is: This an SPA implemented with React and the specific implementation does change the current page and document structure, therefore destroying the link between the click (user gesture) and the WebAuthn call.

Starting with iOS 17.4 the user gesture requirements were completely lifted and replaced with rate-limiting. Therefore, the problem does not occur anymore. Details about the rate-liming have not been released yet but cause other problems (see Webkit bug we commented on here).

3. Timeline: Different Safari Versions and User Gesture Requirements#

We have prepared a timeline / version history of the releases and current market share of iOS versions, so that the appropriate settings for different operating system versions are easily accessible.

3.1 Overview of Version and Announcements of Technical Changes#

VersionUser gesture requirementsBackground links
< iOS14NoneDiscussion about introduction of user gestures: https://github.com/w3c/webauthn/issues/1293
iOS14Required for every operationRelease of first version with user gestures: https://webkit.org/blog/11312/meet-face-id-and-touch-id-for-the-web/
iOS 14.5Whitelisting of important providershttps://bugs.webkit.org/show_bug.cgi?id=220897
iOS 16One .get() w/o limitationTwitter confirmation of “Freebie” iOS16 solution: https://bugs.webkit.org/show_bug.cgi?id=220897
iOS 17.4+User gesture requirements liftedhttps://bugs.webkit.org/show_bug.cgi?id=264444 https://forums.developer.apple.com/forums/thread/747036

(*) = Versions apply to concurrent iPad/Safari releases (e.g. iOS 14 includes iPadOS 14 & Safari 14)

3.2 Current Market Shares of Different iOS Versions (Q1 2024)#

As of today, iOS 17+ is already installed on most iOS devices (~70-75%), but for now and for the next 12-18 months, a significant share of iOS devices with user gesture requirements will still remain.

iOS Version share

What we see within our data and available public statistics depending on the website the following share of iOS Versions is a good approximation as of today:

VersionShareRelease dateUser gesturePasskeys & Conditional UI support
17.4+50%2024-03-05Noneyes
17.0-17.325%2023-09-18One freebieyes
1615%2022-09-12One freebieyes
155%2021-09-20Allno
141%2020-09-16Allno
Older4%Nono

This leaves about 50% of all iOS devices with stricter user gesture requirements that still need to be considered. From a passkey perspective, only iOS 16 and iOS 17 (versions before 17.4) are of special interest as on those iOS version isUserVerifyingPlatformAuthenticatorAvailable() and isConditionalMediationAvailable() will return true, because since iOS 16, passkeys are fully supported by iOS including Conditional UI.

4. Recommendation#

Our approach to this problem is to recommend solutions that allow serving a great UX for all operating systems and versions. In general, there are three options

  • Option 1 - No Conditional UI: Since Conditional UI is implemented on loading, the page consumes the freebie request. The first option is to not implement Conditional UI. We think this significantly impairs functionality, but for example, Google has opted for this solution. They keep their freebie request for automatically triggering WebAuthn after the login identifier has been requested. Maybe this will change in the future.
  • Option 2 - Trigger Conditional UI onClick: When triggering Conditional UI after the user clicks into an input element to enter their login identifier (e.g., email) for WebKit, the freebie request is prevented from being consumed by Conditional UI. As most Apple authenticators are quite fast, this has proven to be an acceptable solution.
  • Option 3 - Conditional UI + user gestures for authentication (our recommendation): The best solution from a technical or UX standpoint is to implement Conditional UI on page load without user gesture, thereby consuming the freebie operation. Then, adhere to Apple's guidelines to implement WebAuthn only on user interaction. This comes with the limitation that for SPAs, there should be no page interactions before clicking and starting WebAuthn ceremonies.

Our recommendation covers the majority of the problem. However, there are other situations for SPAs where issues might occur, especially with "back navigation" after a passkey operation fails (when navigating back after an aborted passkey authentication the next authentication might fail directly when it is triggered automatically by the back navigation). This is because SPAs never have a "page reload" to reset the freebie counter. Solutions for this issue range from reloading the application to changing flows. Contact us if you need help with your SPA.

5. Conclusion: The Ways to Deal with User Gesture Requirements#

In this blog post, we have addressed the complexities of developing passkey-based applications, especially the challenges related to WebAuthn operations on Apple devices using Safari. We covered the evolution of user gesture requirements, how to avoid user gesture errors, and the impacts of different iOS versions on these requirements. To summarize:

  • User gesture requirements have evolved: Starting with iOS 14, Safari introduced user gesture requirements to prevent unauthorized WebAuthn operations. These requirements have been gradually relaxed and have been removed in iOS 17.4, replaced by rate-limiting.

  • Solutions vary by implementation: Depending on the type of application and its specific needs, different approaches can be taken to avoid user gesture errors. Options include not implementing Conditional UI, triggering Conditional UI onClick, and combining Conditional UI with an implementation that only triggers WebAuthn after user gestures specified by Apple.

  • SPAs require special consideration: For single-page applications, issues like "back navigation" after passkey errors/aborts can complicate passkey operations. Solutions may involve reloading the application or changing the flow to reset the freebie counter.

Successfully implementing passkeys requires dedicated know-how and presents with a lot of unknowns. Sharing experiences and solutions can help the developer community overcome these challenges. We invite you to join our passkeys community to discuss these issues and share learnings. Contact us if you need help with your SPA or have any questions about passkey implementation. Let's work together to make passkey authentication a great experience for users.

Share this article


LinkedInTwitterFacebook

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free