• General
  • FIDO2 security keys on GrapheneOS: a summary

Last updated on Nov. 9th 2024. from https://gist.github.com/FID02/48f5130c2151b6d10a04bdfda0cb1c90

This text summarises the usage and compatibility of FIDO security keys on GrapheneOS. It was written by a community member, and is not an official guide by the GrapheneOS project.

This text covers only the usage of physical security keys. Any reference to FIDO and passkeys in this text refers to FIDO in the context of security keys. The usage of passkeys with password managers and cloud services is not covered in this guide.


I have tested FIDO functionality on GrapheneOS and PixelOS over several weeks on multiple Yubikeys of the Security Key series, as well as keys by Token2. It's likely that other security keys will work fine. You can search this forum and the issue tracker for specific models to see if issues have been reported. If you can't find anything, you are also free to ask in the community forum or in the chat rooms.

I have not tested any OTP functionality of security keys. Only FIDO is covered here.

Prerequisites

Sandboxed Google Play is required for practically most FIDO functionality. This is because there is currently no native support for FIDO in the Android Open Source Project (AOSP), which GrapheneOS is based upon. Apps can provide FIDO functionality without Play services if they include a non-Play FIDO library for that, but very few apps do this.[1] Most apps choose to use the Google Play FIDO library, which depends on Play services. Chromium also has no native FIDO support.[2]

Therefore, this text assumes that you are using Sandboxed Google Play.

To use Sandboxed Google Play, simply go to App Store and install Google Play services. You do not have to grant Play services the Network permission in order for security keys to work.

Passkeys

For passkeys, also called resident keys, your key needs to support the storage of these. The latest firmware (v. 5.7) for the Yubikey 5 and Yubikey Security Key series can store a total of 100 resident keys. The newest model of the Google Titan Security Key (launched Nov. 15, 2023[3]) can store up to 250 resident keys. These are probably the most popular keys on the market. Check with your vendor's customer support if you are unsure whether the key that you intend to obtain can store passkeys. Also, ask them if their key supports deletion and management of passkeys, as not all security keys do.[4]

Multi-factor authentication with FIDO2 and U2F

Registration and sign-in works seamlessly, both with USB and NFC, in Vanadium and in apps. No further steps are required.

If your security key functions fine with USB but not NFC, please see the section "PIN and NFC".

FIDO2 passkeys

Passkeys work fully on GrapheneOS, but note the following:

Compatibility with autofill services

On GrapheneOS, it currently does not seem possible to conveniently switch between passkey autofill with a "third-party" autofill service and passkey usage on a security key.

In contrast, when using passkeys on the stock PixelOS, Google Play services serves a dialog that allows you to choose between using passkeys in either a password manager or on an external device such as a security key. It's not clear why this option is currently not displayed with Sandboxed Google Play.

If you are only using passkeys with your security key, this should not pose a problem.

By an "autofill service", I am referring to the service(s) (usually a password manager) that you have configured in the Settings app → Passwords, passkeys & accounts.

By a "third-party" autofill service, I am referring to autofill services other than Vanadium's built-in password manager and Google's Password Manager. Bitwarden and Proton Pass are examples of third-party autofill services.

Note that this does not influence password autofill with these services, which works fine.

Signing in with passkeys

In Vanadium

The setup steps you need to follow here depend on whether or not you are using a third-party autofill service.

When no third-party autofill service is enabled:

Then signing in with passkeys should work without having to change any settings.

When a third-party autofill service is enabled:

You will have to disable the browser's support for passkeys with password managers. This is done by changing an experimental setting:

  1. In the address bar, type chrome://flags and press enter
  2. In the search bar, type passkeys
  3. A setting called "Android Credential Management for passkeys" will appear. Change this setting to "Disabled"
  4. Select "Relaunch"

Again, note that following those steps will disable passkey autofill with password managers. Password autofill should not be affected.

In other apps

A lot of apps simply redirect you to the web browser for passkey authentication, which should not pose any issues if your default browser is Vanadium and you have followed the steps in the previous section.

Other apps will directly call Play Services for authentication, and it's not clear if this generally works on GrapheneOS: There are very few apps that call Play Services directly instead of redirecting you to the default web browser, so right now there's not much opportunity to test this with more than a couple of apps.

Registering passkeys

In order to register passkeys using Vanadium, you will have to disable the browser's support for passkeys with password managers. If you already did this when following the steps in "Signing in with passkeys", there is no need to do it again.

  1. In the address bar, type chrome://flags and press enter
  2. In the search bar, type passkeys
  3. A setting called "Android Credential Management for passkeys" will appear. Change this setting to "Disabled"
  4. Select "Relaunch"

The next time you opt to register a passkey for a website you visit in Vanadium, you will be shown the option "Use a different device".

Other notes

PIN creation and entry

This works fine.

PIN and NFC

Play services does not support PIN functionality over NFC. As such, if a service requests you to use a PIN (or if your key is set to require a PIN for all authentication) you will have to use USB. Play services might display the NFC option regardless, even when it will not work for you.

This is especially relevant for passkeys, where a PIN or other user verification is often set to be required or preferred by the service. Notably, and perhaps slightly ridiculously, Play Store allows you to sign in with a passkey using NFC without having to enter a PIN at all.[5]

Google accounts

It does not appear to be possible to register a passkey from within the Play Store app, as the button "Create passkey" does nothing. I am observing the same behaviour on stock PixelOS. You will have to register the passkey by signing in to your Google account in a web browser.

Signing in to the Play Store with a passkey seems to work fine.

Network access for Play services

In the past, Play services needed occasional network access in order for FIDO authentication to function. As of the latest update to this guide, security keys now work fine even if the Network permission has never been granted to Play services.

Error messages from Play services

When FIDO authentication fails, Play services will not provide you with any useful error messages. For instance, if your security key is not actually registered against the service you are attempting to sign in to, a generic error will be displayed. One might contrast this to Windows, which in such a case will display the slightly more useful message "this security key does not look familiar". Hence, until you start troubleshooting, you usually can't know immediately why an authentication fails.


I am no expert in this field, so please comment any corrections regarding this text, or inaccurate usage of terms.

[1]: Some services implements – or implemented – a custom FIDO library because of Android's lack of native support for authentication with CTAP2 and FIDO2 passkeys on security keys. Buypass is one example of a service utilizing an API to overcome this.
Since Play services now has support for CTAP2 and FIDO2 passkeys, it's likely that more services will phase out their use of custom FIDO libraries.


[2]: On the status of native FIDO support in AOSP and GrapheneOS, here is some information given by the GrapheneOS project: https://x.com/GrapheneOS/status/1847994282994458682#m

Quote from the tweets:

User: @GrapheneOS please make passkeys work on GrapheneOS! Crypto people need this

GrapheneOS: "FIDO2 and passkeys work on GrapheneOS. Many apps implement it via the Google Play FIDO library which requires sandboxed Google Play. We plan to provide an alternative implementation for Vanadium. Google engineers told us they were going to add a standalone implementation to AOSP."

GrapheneOS: "We don't know if and when they're actually going to add a standalone FIDO2/passkey implementation to AOSP and it's not a priority for them because they work fine via Google Play already. They're fine with it so they're in no rush to fix this, but they did claim they would."

Other user: "When they follow up on that promise is irrelevant. You don't need passkeys."

GrapheneOS: "Passkeys work fine on GrapheneOS. We want to have an implementation not depending on the Google Play SDK and Google Play services. We were told that it would be added to the Android Open Source Project but that has yet to materialize in any form years later."

GrapheneOS: "This is not only about passkeys but also more traditional FIDO2 security key usage too. Most apps implement both using the Google Play SDK. We could make our own independent implementation of course but they told us they'd be adding it to AOSP which discouraged us from doing it."

[3]: As far as I know, older models of the Google Titan Key cannot store passkeys. I am unable to test the newest model, as Google does not ship to where I reside.

[4]: Keys that support the CTAP2.1 standard ought to be able to support passkey management – perhaps the most useful aspect of this being the ability to delete passkeys from the device, which is especially welcome if your security key has a limited number of passkey slots.

[5]: You can set a flag on your security key in order to make all authentication require a PIN. Your key needs to support CTAP2.1. When the flag is enabled, all sign-in attempts, including when using multi-factor with a password, will require a PIN. Naturally this adds a slight inconvenience, at the benefit of some extra protection against an attacker physically stealing your key and using it to sign in to a service that does not require (or discourages) user verification. I will not make a recommendation on which option to choose; make up your own mind about your security requirements and risks.

    Has anyone extensively tried FIDO2 authentication using the Solokey v2? I have one but I have not used it very much myself with GrapheneOS. I will attempt to do some testing with authenticating logins through Vanadium using it.

    2 months later

    Update, 8th of June:

    fid02 Registration does work for services that specifically presents an option for storing passkeys on a device.

    Very few services now do this. Microsoft no longer does. Although Google appears to offer the option, users are reporting that the actual registration prompt never shows – affects both GrapheneOS and stock PixelOS. This means that passkey registration must be done from a different OS (only affects physical security keys, not password managers. Just to be clear.).

    Users are also reporting that signing in to a Google account with a passkey on a security key is problematic – affects both GrapheneOS and stock PixelOS. The sign-in prompts are shown but the passkey is not accepted. It seems to work in some scenarios but I haven't been able to determine which ones.

    Managing passkeys and FIDO PIN: You can use the open-source Yubico Authenticator app [Play Store] [Github] – even without Play Services – to manage your passkeys on GrapheneOS: you can view them and delete them. You can also change your PIN. I've tested it with Yubikey Security Key FW v. 5.4, so you don't need FW v. 5.7. I've also tested it with this security key by Token2 (NFC only). I'm guessing that the app is compatible with every key that supports FIDO2 and CTAP2.1 – which means it wil not work with the Google Titan Security Key.

    6 days later

    fid02 Registration with passkeys stored on security keys currently only works with a few services.

    Update on this: you can now use Brave or Chrome on GrapheneOS to register passkeys on your security key. There are no settings changes needed. The correct dialog will be shown when you attempt to register a passkey within these browsers.

    It's currently not possible on Vanadium – or at least, I am not able to do it without changing a specific flag in chrome://flags, which I don't recommend because it will cause crashes in other passkey functionality within Vanadium.

    3 months later

    Looks like Android 15 (or at least 15 QPR1)* will support selecting between either roaming or on-device authenticators when authenticating. In English that means: when signing in to a service, you will be able to select between using either a passkey in your password manager or a passkey on a device such as a security key. That means you can store one passkey for a service in your password manager, and another passkey for the same service on your security key, and conveniently select between either of them.

    This might be a niche feature, but there are cases where this is useful. For instance, your workplace might use a Microsoft account and require you to store a passkey for it on a dedicated security key (disallowing password managers) – but you might prefer to have the passkey for your private Microsoft account stored in your personal password manager. With Android 14, in such a case you would have to temporarily disable autofill with your password manager in order to sign in with the security key.

    *At least, this is how Android 15 on the stock PixelOS currently behaves.

    fid02 Therefore, for most services, you will have to register the passkey from a different operating system.

    Update to this: You can currently use Brave – but no longer Chrome; they appear to have removed the option to do so – to register your passkeys. You can do it in Vanadium, but it requires changing a browser flag. If you want to use Vanadium for this, you should undo the flag after registering the passkey, as it will cause issues with password manager autofill.

    1. In Vanadium, go to chrome://flags
    2. Locate the option called "Android Credential Management for passkeys" and set it to Disabled
    3. Exit and relaunch Vanadium
    4. Reset the flag to Default after registering your passkey(s) (optional but recommended)

    I plan to update this guide after having tested security key functionality on GrapheneOS based on AOSP 15.

    5 days later

    Starting with Vanadium 129.0.6668.54, in order to use passkeys on a security key while retaining password autofill in the browser with a third-party* password manager, the following has to be done:
    [Warning: this involves changing experimental settings and is not supported. If you experience browser issues, revert this setting to its default. This will also disable passkey autofill with a third-party passkey manager].

    • Enter the following into the address bar, which will take you to an entry called "Android Credential Management for passkeys": chrome://flags/#web-authentication-android-credential-management
    • Set the flag to 'Disabled' and then restart Vanadium

    Note for future readers: this is subject to change in the future and might not be applicable at the time you're reading this.

    *Meaning any password manager you install yourself, such as Proton Pass and Bitwarden.

    2 months later

    I have updated the guide/text on FIDO security key functionality on GrapheneOS: https://gist.github.com/FID02/48f5130c2151b6d10a04bdfda0cb1c90
    Appreciate any comments or corrections.

    A gist allows me to update it continuously and avoids people having to scroll this thread for the latest updates. I have added several other notes to the gist which might be useful when troubleshooting issues. My original post in this thread is out of date and a lot of the info is now incorrect.

    If any mod is reading this, I would appreciate if the original post was edited and the URL to the gist added to the beginning of the post.

      fid02 If any mod is reading this, I would appreciate if the original post was edited and the URL to the gist added to the beginning of the post.

      Done.

      2 months later

      PIN creation and entry
      This works fine.

      That's where I get stuck.
      Ente, Standard Notes and Proton apps ask me my pin code as a second factor (USB is required on the tablet), I enter it, and the same window reappears to ask me for it a second time, then error. Impossible to connect.
      On my phone it works fine, because it's NFC, but if I try USB too, I get the same problem. I can't validate the pin code.
      The only way I have at the moment is to deactivate fido2 on windows yubikey manager, but this dependence on windows is problematic and it just solve the problem about MFA, not passwordless sign-in.

      Otherwise the key works well with porkbun on vanadium, for example, which doesn't ask for the code.

        AelwennBZH do you have Yubico Authenticator installed on that tablet? We found out that sometimes the app is required to be installed for FIDO functionality, for whatever reason. If you didn't have it installed, try that maybe.

          DeletedUser87

          Yes, the yubico app was already installed, both on phone and tablet.
          When I saw that it wasn't working, I open it with my yubikey and tried the pin code : It works inside yubico app.
          I've just reinstalled yubico to test, restarted my phone. Still the same problem: I'm asked for the pin code twice and the sign-in failed...

          If the yubico authenticator application also allowed you to deactivate and reactivate the key protocols, like yubico manager on windows, that would partially solve my problem, but I don't know if that's planned.

            AelwennBZH that's unfortunate. May be a problem with Play Services? I'm not really sure. @fid02 is a lot more knowledgeable on that matter, so hopefully they can chime in soon.

              DeletedUser87

              May be a problem with Play Services?

              Maybe, since without pin code, it works fine. My phone/tablet and apps are up to date, so if it was coming from there, I guess the problem would affect everyone, at least on GrapheneOS.

              It's really frustrating that fido/passkey integration is so bad on android, even though google is very involved in the field...
              it just makes me want to throw away my keys and give up on 2FA.

                AelwennBZH I completely agree. I haven't invested in HW keys because the solution on Android (at least on GOS) seams so flaky and volatile.

                  trilogy6202

                  I've registered my keys with a dozen services.
                  Everything works on Windows. But I had to register again my key on half of these services because on android, some apps or websites, I had to explicitly disable the fido2 protocol and only use fido U2F just to register the key.
                  GitHub and Bitwarden works with Fido2, but Standard Notes and Proton works only with Fido U2F.
                  It's not uniform at all. Fido is really a huge improvement in security, but it's currently discouraging.

                    AelwennBZH And it's really sad that fido2 and Fido u2f isn't part of AOSP but requires gps. I don't use gps on my main profile so it's not really an option for me until it's included in AOSP or GOS makes their own implementation which I assume is pretty unlikely to happen.

                      AelwennBZH Ente, Standard Notes and Proton apps ask me my pin code as a second factor (USB is required on the tablet), I enter it, and the same window reappears to ask me for it a second time, then error. Impossible to connect.

                      Grant Play services the network permission and reboot your device.