The #ChromeDevSummit site is live, happening Nov 12-13 in San Francisco, CA
Check it out for details and request an invite. We'll be diving deep into modern web tech & looking ahead to the platform's future.

Credential Management API Feature Detection Check-up

TL;DR

WebAuthn helps increase security by bringing public-key credential based authentication to the Web, and is soon to be supported in Chrome, Firefox and Edge (with the updated spec). It adds a new kind of Credential object, which, however, may break websites that use the Credential Management API without feature-detecting the specific credential types they're using.

If you are currently doing this for feature detection:

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
  // use CM API
}

Do these instead:

if (window.PasswordCredential || window.FederatedCredential) {
  // Call navigator.credentials.get() to retrieve stored
  // PasswordCredentials or FederatedCredentials.
}

if (window.PasswordCredential) {
  // Get/Store PasswordCredential
}

if (window.FederatedCredential) {
  // Get/Store FederatedCredential
}

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
  // Call navigator.credentials.preventSilentAccess()
}

See changes made to the sample code as an example.

Read on to learn more.

What is the Credential Management API

The Credential Management API (CM API) gives websites programmatic access to the user agent’s credential store for storing/retrieving user credentials for the calling origin.

Basic APIs are:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.create()
  • navigator.credentials.preventSilentAccess()

The original CM API specification defines 2 credential types:

  • PasswordCredential
  • FederatedCredential

The PasswordCredential is a credential that contains user's id and password.
The FederatedCredential is a credential that contains user's id and a string that represents an identity provider.

With these 2 credentials, websites can:

  • Let the user sign-in with a previously saved password-based or federated credential as soon as they land (auto sign-in),
  • Store the password-based or federated credential the user has signed in with,
  • Keep the user's sign-in credentials up-to-date (e.g. after a password change)

What is WebAuthn

WebAuthn (Web Authentication) adds public-key credentials to the CM API. For example, it gives websites a standardized way to implement second-factor authentication using FIDO 2.0 compliant authenticator devices.

On a technical level, WebAuthn extends the CM API with the PublicKeyCredential interface.

What is the problem?

Previously we have been guiding developers to feature detect the CM API with following code:

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
  // Use CM API
}

But as you can see from the descriptions above, the navigator.credentials is now expanded to support public-key credentials in addition to password credentials and federated credentials.

The problem is that user agents don't necessarily support all kinds of credentials. If you continue feature detect using navigator.credentials, your website may break when you are using a certain credential type not supported by the browser.

Supported credential types by browsers

PasswordCredential / FederatedCredential PublicKeyCredential
Chrome Available In development
Firefox N/A Aiming to ship on 60
Edge N/A Implemented with older API. New API (navigator.credentials) coming soon.

The solution

You can avoid this by modifying feature detection code as follows to explicitly test for the credential type that you intend to use.

if (window.PasswordCredential || window.FederatedCredential) {
  // Call navigator.credentials.get() to retrieve stored
  // PasswordCredentials or FederatedCredentials.
}

if (window.PasswordCredential) {
  // Get/Store PasswordCredential
}

if (window.FederatedCredential) {
  // Get/Store FederatedCredential
}

if (navigator.credentials && navigator.credentials.preventSilentAccess) {
  // Call navigator.credentials.preventSilentAccess()
}

See actual changes made to the sample code as an example.

For a reference, here's how to detect PublicKeyCredential added in WebAuthn:

if (window.PublicKeyCredential) {
  // use CM API with PublicKeyCredential added in the WebAuthn spec
}

Timeline

Earliest available implementation of WebAuthn is Firefox and is planned to be stable around early May 2018.

Finally

If you have any questions, send them over to @agektmr or agektmr@chromium.org.