Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebAuthn support #2123

Open
Obiwarn opened this issue Aug 29, 2019 · 33 comments
Open

WebAuthn support #2123

Obiwarn opened this issue Aug 29, 2019 · 33 comments

Comments

@Obiwarn
Copy link

Obiwarn commented Aug 29, 2019

I could not find FIDO2 support. Is there a roadmap for this?

@google-oss-bot
Copy link
Contributor

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

@bojeil-google
Copy link
Contributor

We don't currently support WebAuthn. Please file an official feature request for it. Long term, we are definitely interested in supporting it.

@sgammon
Copy link

sgammon commented Mar 20, 2020

@bojeil-google could I kindly ask the status of this feature?

@yinonov
Copy link

yinonov commented Sep 5, 2020

just experienced fingerprint authentication with ebay and it's great! really seem fit for firebase to align with edge of such technology

@rosalyntan
Copy link
Member

Thanks for filing this feature request! This is being tracked internally at b/168498557.

@dweekly
Copy link

dweekly commented Jan 6, 2021

Happy New Year! Our team would really like to see this implemented to be able to offer our users reasonable 21st century security and protections against phishing while staying on the Firebase platform.

@maccman
Copy link

maccman commented Mar 22, 2021

Our team would love to see this in Firebase.

@mouneyrac
Copy link

I vote for it too :)

https://webauthn.me/ - a site created by Auth0 to promote it.

Auth0 apparently supports web biometric authentication - I am not affiliated to Auth0, I am not even using them but it does look attractive. I also read Safari is supposed to support it in iOS14 - but I don't know if it landed.

@Gitzman
Copy link

Gitzman commented Aug 4, 2021

Would love this to be supported

@npwork
Copy link

npwork commented Oct 14, 2021

+1

@TechWilk
Copy link

Seems like a major omission for an auth service

@michburkhalter
Copy link

This would definitely add a lot of value to my application.

@omar2205
Copy link

Is there any update to this request?

@ivstiv
Copy link

ivstiv commented Nov 22, 2021

This would add a lot of value to the service. Should be considered!

@jacobg
Copy link

jacobg commented Dec 6, 2021

Yep! TOTP too using Authenticator app. Google itself realized over 4 years ago that SMS is a weak MFA option:
https://www.zdnet.com/article/google-wants-you-to-stop-using-its-sms-two-factor-sign-in/

@eliabieri
Copy link

Any updates on this?
Now that Apple featured Passkeys, that seem to be based on WebAuthn

@jaymathew
Copy link

Is there any update to this request?

@sergiocampama
Copy link

looks like Cognito offers this: https://aws.amazon.com/blogs/security/how-to-implement-password-less-authentication-with-amazon-cognito-and-webauthn/

@johnozbay
Copy link

Some good news from 2 days ago:
https://firebase.blog/posts/2022/07/new-firebase-auth-features

@jacobg
Copy link

jacobg commented Jul 28, 2022

Some good news from 2 days ago: https://firebase.blog/posts/2022/07/new-firebase-auth-features

It's nice to see Firebase giving Auth some attention, but there's not any new feature here. These features have already been available on Cloud Identity Platform and available via the Firebase SDK. It seems all that's new is they've added the information to the Firebase Console website, so you don't have to go to Google Cloud console to view it.

What we really want to see is real MFA.

@ghost
Copy link

ghost commented Sep 9, 2022

Following up on this. When is passkey login going to be supported natively under Firebase Auth? This seems like the highest ROI update. I'm hoping this doesn't launch later than October 6th (Pixel announcement)!

Seems sad that AWS has a full tutorial up on this.

@rorito
Copy link

rorito commented Oct 25, 2022

+1

@omar2205
Copy link

+1

Please don't reply with this. You just notified all of us subscribed to this issue, and gave a false impression that there was an update added.

@gavinsawyer
Copy link

gavinsawyer commented Apr 22, 2023

FirebaseWebAuthn is a Firebase extension for authentication with WebAuthn passkeys.

@firebase-web-authn/extension conforms to the Firebase Extensions spec. If you know a way to install it from the source code, you will be able to bypass most of the setup process. I've applied to the Early Access Program to hopefully make this available in the Extensions Marketplace.

There are 3 other packages on npm which can be used without the Firebase Extensions process:

  • browser: This package contains five tree-shakeable async methods for using FirebaseWebAuthn in components and a strongly-typed error object.
  • functions: This package contains a Firebase Function that registers and authenticates WebAuthn passkeys, manages public key credentials in Firestore, and cleans up data if the user cancels a process or unlinks a passkey.
  • types: This package contains types and interfaces used internally by FirebaseWebAuthn and for implementing it in a secure context.

@gavinsawyer
Copy link

gavinsawyer commented Apr 23, 2023

^ Update on this, sorry if y'all don't appreciate the notifications:

I just dropped @firebase-web-authn/extension@9.4.4 which is actually installable! There's no documentation for this, but I found out that you can install it from the source code with:

% npm install @firebase-web-authn/extension --save-dev
% firebase ext:install ./node_modules/@firebase-web-authn/extension
% firebase deploy --only extensions

If you do that it'll walk you through the configuration and you'll then be able to use createUserWithPasskey and other methods from @firebase-web-authn/browser in your app.

Here's what it looks like in the console for the demo site:

@zaghoo-amwal
Copy link

In case you are looking for a solution which works in both web and mobile, please check out our extension Justpass.me

It is simple, secure (OpenID and FIDO certified) and handles existing user migration in a powerful way.

Here is the link for the repo
https://github.com/justpass-me/justpass-me-firebase-ext

@gavinsawyer
Copy link

In case you are looking for a solution which works in both web and mobile, please check out our extension Justpass.me

It is simple, secure (OpenID and FIDO certified) and handles existing user migration in a powerful way.

Here is the link for the repo https://github.com/justpass-me/justpass-me-firebase-ext

$29/mo + 10¢/user is a lot for putting a PublicKeyCredential in a db imo. I don't see the point of a managed solution for passkeys like this. It's like selling W3C standards back to you, and separating you from the data further.

In the case of this extension, it doesn't even have a way to access when the user was verified last in a secure context. It's useful for signing in and creating an account, but it then makes you assume whoever is using that browser is that person forever. You couldn't ask for biometric verification before doing an action server-side, for example.

  • It's not actually web and mobile given that the recommended library for web is the React Native library.
  • It has a very clunky API which takes a URL and headers object and outputs the token rather than behaving like the Firebase SDK for easy learning.
  • The error reporting is also very basic and not type safe.

Basically just use mine it'll be free forever and has more features:

createUserWithPasskey: (auth: Auth, functions: Functions, name: string) => Promise<UserCredential>;
    signInWithPasskey: (auth: Auth, functions: Functions)               => Promise<UserCredential>;
      linkWithPasskey: (auth: Auth, functions: Functions, name: string) => Promise<UserCredential>;
        unlinkPasskey: (auth: Auth, functions: Functions)               => Promise<void>;
verifyUserWithPasskey: (auth: Auth, functions: Functions)               => Promise<void>;

Client-side error reporting:

class FirebaseWebAuthnError extends Error {
  code: `firebaseWebAuthn/${FirebaseError["code"] | "missing-auth" | "missing-user-doc" | "no-op" | "not-verified" | "user-doc-missing-challenge-field" | "user-doc-missing-passkey-fields" | "cancelled" | "invalid"}`;
  message: FirebaseError["message"] | "No user is signed in." | "No user document was found in Firestore." | "No operation is needed." | "User not verified." | "User doc is missing challenge field from prior operation." | "User doc is missing passkey fields from prior operation.";
  method?: "httpsCallableFromURL" | "signInAnonymously" | "signInWithCustomToken";
  operation?: "clear challenge" | "clear user doc" | "create authentication challenge" | "create reauthentication challenge" | "create registration challenge" | "verify authentication" | "verify reauthentication" | "verify registration";
}

Secure context interfaces/How credentials go in Firestore:

interface WebAuthnUserCredential {
  "backupEligible": boolean,   // Whether the private key is eligible to be backed up.
  "backupSuccessful": boolean, // Whether the private key has been backed up successfully.
  "counter": number,           // Updated automatically by some browsers to help prevent replay attacks.
  "id": Uint8Array,            // ID associated with the credential.
  "publicKey": Uint8Array,     // Public key associated with the credential.
}
interface WebAuthnUserDocument {
  "challenge"?: string,                  // Only present between operations and cleaned up if the user cancels.
  "credential"?: WebAuthnUserCredential, // Information about the public key credential associated with the user.
  "lastPresent"?: Timestamp,             // Automatically updated on successful operations.
  "lastVerified"?: Timestamp,            // Automatically updated on successful operations that verified the user with biometrics.
}

Release candidate is available:

% firebase ext:install gavinsawyer/firebase-web-authn@9.4.18-rc.0

But I prefer NPM for getting updates alongside the browser package:

% npm i @firebase-web-authn/extension --save-dev
% firebase ext:install ./node_modules/@firebase-web-authn/extension

@sameh-amwal
Copy link

sameh-amwal commented Jun 3, 2023

$29/mo + 10¢/user is a lot for putting a PublicKeyCredential in a db imo. I don't see the point of a managed solution for passkeys like this. It's like selling W3C standards back to you, and separating you from the data further.

AFAIK it's not feasible to implement passkeys directly on firebase functions for mobile apps because the mobile sdks for iOS and android require to establish domain association between the mobile app and the website domain. For example for the robinhood app to use passkeys this file served on this exact location at the root of the domain establishes the association between the website passkeys and the 3M6D9LJW67.com.robinhood.release.Robinhood app. if the file is missing or the linking is not correct, the passkeys won't be displayed to the user.

https://robinhood.com/.well-known/apple-app-site-association

same thing for android establishing link to com.robinhood.android package

https://robinhood.com/.well-known/assetlinks.json

@gavinsawyer
Copy link

gavinsawyer commented Jun 4, 2023

AFAIK it's not feasible to implement passkeys directly on firebase functions for mobile apps because the mobile sdks for iOS and android require to establish domain association between the mobile app and the website domain.

The same is true with browsers, though. My docs mention adding rewrites for each app in firebase.json so https://$YOUR_DOMAIN/firebase-web-authn-api points to the Cloud Function. If you tried giving the in-browser authenticator an origin or relying party ID different from the site hostname, it would refuse. It's interesting that you can bypass that for mobile with just domain association, though.

I couldn't find a browser package anywhere in your code, so you'd run into that issue when you look into adding web support.

If you are using Firebase Hosting and a custom domain, though, the only way to have an API on the domain is thru rewrites. This means any third party passkey authenticator is going to be at least two round trips. Your app will tell the in-browser authenticator to call an API on your domain, which calls JustPass.me, which then finds your public key in a database and authenticates your message. Compared to authenticating the message in the Cloud Function directly using a public key from Firestore (in the same building), this has to take at least twice as long.

edit: I don't know what issue you're referring to with domain association, either. The endpoints your iOS SDK uses are under cloudfunctions.net, so there's no direct interactions with JustPass.me servers from the client.

@sameh-amwal
Copy link

edit: I don't know what issue you're referring to with domain association, either. The endpoints your iOS SDK uses are under cloudfunctions.net, so there's no direct interactions with JustPass.me servers from the client.

https://www.justpass.me/docs/how_it_works#authentication-flow

@gavinsawyer
Copy link

gavinsawyer commented Jun 7, 2023

https://www.justpass.me/docs/how_it_works#authentication-flow

WebAuthn only requires two round trips for either registration or authentication, so this involves a lot of unnecessary complications. WebAuthn is also only useful if you're able to determine that the current user was signed in using biometrics and how long ago on the server.

FirebaseWebAuthn v9.5.1 now has a new package (@firebase-web-authn/server) to help solve this problem. Its only dependency is firebase-admin and all it does is resolve values from Firestore (or null if the user hasn't linked a passkey), but it's useful in certain scenarios.

Somewhere in an API endpoint for a user to send money, change an important setting, etc:

import { lastVerified } from "@firebase-web-authn/server";
// If the user was verified within the past 30 seconds, proceed. Otherwise, ask for reverification:
(await lastVerified(uid)).seconds > (Date.now() / 1000) - 30 ?
  proceed() :
  askForReverification();

In total the server package has four tree-shakeable async methods for determining when the user was present or verified last (See User Presence vs User Verification), whether their passkey is eligible to be backed up, and whether their passkey is successfully backed up:

  backupEligible: (uid: string, app?: App) => Promise<boolean | null>;
backupSuccessful: (uid: string, app?: App) => Promise<boolean | null>;
     lastPresent: (uid: string, app?: App) => Promise<Timestamp | null>;
    lastVerified: (uid: string, app?: App) => Promise<Timestamp | null>;

Complete FirebaseWebAuthn documentation

@cbenhagen
Copy link

cbenhagen commented Jun 29, 2023

Please make sure to vote for official passkey support here:
https://firebase.uservoice.com/forums/948424-general/suggestions/46647016-support-authentication-with-passkeys

And for webauthn here:
https://firebase.uservoice.com/forums/948424-general/suggestions/46591561-webauthn-integration-for-authentication

@cbenhagen
Copy link

cbenhagen commented Jun 29, 2023

Sorry, me again. As Firebase uses Google Cloud Identity Platform, I also created a feature request in their issue tracker. Please head over there and give it a star and hit the +1 button:
https://issuetracker.google.com/issues/289237739

(Only comment on that issue if you have relevant new information. Thanks!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests