Proposal for a credential management API.

TL;DR: Strawman spec and usecases at
https://github.com/mikewest/credentialmanagement

# Use Cases

User agents' password managers are a fragile and proprietary hodgepodge of
heuristics meant to detect and fill sign-in forms, password change forms,
etc.
We can do significantly better if we invite websites' explicit cooperation:

* Federated identity providers are nigh undetectable; I don't know of
any password managers that try to help users remember that they signed
into Stack Overflow with Twitter, not Google.

* Signing in without an explicit form submission (via XHR, WebSockets(!),
etc) is good for user experience, but difficult to reliably detect.

* Password change forms are less well-supported than they could be.

* Users are on their own when creating new accounts, faced either with a
list of identity providers they've mostly never heard of, or with the
challenge of coming up with a clever new password.

More background and exploration of native equivalents at
http://projects.mikewest.org/credentialmanagement/usecases/.

# Workarounds

HTML defines a number of `autocomplete` attributes which help explain
fields'
purpose to user agents. These make the common case of form submission more
reliably detectable, but are less helpful for XHR-based sign-in, and don't
address federated identity providers at all.

# Proposal:

The API I'm outlining here is intentionally small and simple: it does not
attempt to solve the general authentication problem in itself, but instead
provides an interface to user agents' existing password managers. That
functionality is valuable _now_, without significant effort on the part of
either browser vendors or website authors.

The API quite intentionally winks suggestively in the direction of an
authentication API that would, for instance, do an OAuth dance on behalf of
an
application, but that's not the immediate goal.

```
[NoInterfaceObject]
interface Credential {
  readonly attribute DOMString id;
  readonly attribute DOMString name;
  readonly attribute DOMString avatarURL;
};

[Constructor(DOMString id, DOMString password, DOMString name, DOMString
avatarURL)]
interface LocalCredential : Credential {
  readonly attribute DOMString password;
};

[Constructor(DOMString id, DOMString federation, DOMString name, DOMString
avatarURL)]
interface FederatedCredential : Credential {
  readonly attribute DOMString federation;
};

partial interface Navigator {
  readonly attribute CredentialsContainer credentials;
};

interface CredentialsContainer {
  Promise<Credential?> request(optional CredentialRequestOptions options);
  Promise<any> notifySignedIn(optional Credential credential);
  Promise<any> notifyFailedSignIn(optional Credential credential);
  Promise<any> notifySignedOut();
  readonly attribute PendingCredential? pending;
};
```

A more detailed specification is up at
http://projects.mikewest.org/credentialmanagement/spec/.

# Example:

```
navigator.credentials.request({
  'federations': [ 'https://federated-identity-provider.com/' ]
}).then(function(credential) {
  if (!credential) {
    // The user had no credentials, or elected not to provide one to this
site.
    // Fall back to an existing login form.
  }

  var xhr = new XMLHttpRequest();
  xhr.open("POST", "https://example.com/loginEndpoint");
  var formData = new FormData();
  formData.append("username", credential.id);
  formData.append("password", credential.password);
  xhr.onreadystatechange = function () {
    if (this.readyState != this.DONE)
      return;
    var loginSucceeded = // Process response: if login succeeded, yay! If
not, boo!;
    if (loginSucceeded) {
      navigator.credentials.notifySignedIn(credential);
      // Notify the user that signin succeeded! Do amazing, signed-in
things!
    } else {
      navigator.credentials.notifyFailedSignIn(credential);
      // Notify the user that signin failed, and fall back to the usual
experience.
    }
  };
  xhr.send(formData);
});
```

More examples at
http://projects.mikewest.org/credentialmanagement/spec/#introduction-examples
.

It's not clear to me that WebApps is the right venue from a process
perspective,
but this is almost certainly the right group of people to evaluate the
proposal.
Thanks in advance for your feedback, suggestions, and time. :)

-mike

--
Mike West <mkwst@google.com>
Google+: https://mkw.st/+, Twitter: @mikewest, Cell: +49 162 10 255 91

Google Germany GmbH, Dienerstrasse 12, 80331 München, Germany
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Christine Elizabeth Flores
(Sorry; I'm legally required to add this exciting detail to emails. Bleh.)

Received on Thursday, 31 July 2014 07:49:04 UTC