Credential Management Level 1

Editor’s Draft,

This version:
https://w3c.github.io/webappsec/specs/credentialmanagement/
Latest version:
http://www.w3.org/TR/credential-management/
Version History:
https://github.com/w3c/webappsec/commits/master/specs/credentialmanagement/index.src.html
Feedback:
public-webappsec@w3.org with subject line “[credential-management] … message topic …” (archives)
Issue Tracking:
GitHub
Editor:
(Google Inc.)
Use Cases:
https://w3c.github.io/webappsec/usecases/credentialmanagement/
Bug Reports:
via the w3c/webappsec repository on GitHub

Abstract

This specification describes an imperative API enabling a website to request a user’s credentials from a user agent, and to help the user agent correctly store user credentials for future use.

Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

Changes to this document may be tracked at https://github.com/w3c/webappsec.

The (archived) public mailing list public-webappsec@w3.org (see instructions) is preferred for discussion of this specification. When sending e-mail, please put the text “credential-management” in the subject, preferably like this: “[credential-management] …summary of comment…

This document was produced by the Web Application Security Working Group.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 September 2015 W3C Process Document.

Table of Contents

1. Introduction

This section is not normative.

Signing into websites is more difficult than it should be. The user agent is in a unique position to improve the experience in a number of ways, and most modern user agents have recognized this by providing some measure of credential management natively in the browser. Users can save usernames and passwords for websites, and those credentials are autofilled into sign-in forms with varying degrees of success.

The autocomplete attribute offers a declarative mechanism by which websites can work with user agents to improve the latter’s ability to detect and fill sign-in forms by marking specific fields as "username" or "password", and user agents implement a wide variety of detection heuristics to work with websites which haven’t taken the time to provide this detail in markup.

While this combination of heuristic and declarative detection works relatively well, the status quo leaves some large gaps where detection is problematic. Sites with uncommon sign-in mechanisms (submitting credentials via XMLHttpRequest [XMLHTTPREQUEST], for instance) are difficult to reliably detect, as is the increasingly common case in which users wish to authenticate themselves using a federated identity provider. Allowing websites to more directly interact with the user agent’s credential manager would allow the credential manager to be more accurate on the one hand, and to assist users with federated sign-in on the other.

These use cases are explored in more detail in §1.1 Use Cases and in Credential Management: Use Cases and Requirements; this specification attempts to address many of the requirements that document outlines by defining a Credential Manager API which a website can use to request credentials for a user, and to ask the user agent to persist credentials when a user signs in successfully.

Note: The API defined here is intentionally small and simple: it does not intend to provide authentication in and of itself, but is limited to providing an interface to the existing credential managers implemented by existing user agents. That functionality is valuable right now, without significant effort on the part of either vendors or authors. There’s certainly quite a bit more which could be done, of course. See §9 Future Work for some thoughts we’ve punted for now, but which could be explored in future iterations of this API.

1.1. Use Cases

Modern user agents generally offer users the capability to save passwords when signing into a website, and likewise offer the capability to fill those passwords into sign-in forms fully- or semi-automatically when users return to a website. From the perspective of a website, this behavior is completely invisible: the website doesn’t know that passwords have been stored, and it isn’t notified that passwords have been filled. This is both good and bad. On the one hand, a user agent’s password manager works regardless of whether or not a site cooperates, which is excellent for users. On the other, the password managers' behaviors are a fragile and proprietary hodgepodge of heuristics meant to detect and fill sign-in forms, password change forms, etc.

A few problems with the status quo stand out as being particularly problematic:

  • User agents have an incredibly difficult time helping users with federated identity providers. While detecting a username/password form submission is fairly straightforward, detecting sign-in via a third-party is quite difficult to reliably do well. It would be nice if a website could help the user agent understand the intent behind the redirects associated with a typical federated sign-in action.
  • Likewise, user agents struggle to detect more esoteric sign-in mechanisms than simple username/password forms. Authors increasingly asynchronously sign users in via XMLHttpRequest or similar mechanisms in order to improve the experience and take more control over the presentation. This is good for users, but tough for user agents to integrate into their password managers. It would be nice if a website could help the user agent make sense of the sign-in mechanism they choose to use.
  • While signing into a website with a username and password is fairly well supported, creating a new account on a website is more or less left up to the user. The user agent’s knowledge of a user’s browsing history, access to the credential store, and general mediation of a user’s activity means that it is in a very good position indeed to help users sign up for new sites.

    Note: This is especially true for sites which support federated identity providers, as those often support not just one or two, but many. Rather than presenting a user with a dozen icons from which to choose a familiar-looking provider, the site can ask the user agent to display only those providers the user actually uses. See §5.3 Credential Selection for discussion.

  • Finally, changing passwords is less well-supported than it could be if the website explicitly informed the user agent that credentials had changed.

1.2. Examples

1.2.1. Password-based Sign-in

A website that supports only username/password pairs can request credentials, and use them in existing sign-in forms:

navigator.credentials.get({ "password": true }).then(
    function(credential) {
      if (!credential) {
        // The user either doesn’t have credentials for this site, or
        // refused to share them. Insert some code here to show a basic
        // login form (or, ideally, do nothing, since this API should
        // really be progressive enhancement on top of an existing form).
        return;
      }
      if (credential.type == "password") {
        fetch("https://example.com/loginEndpoint", { body: credential.toFormData(), method: "POST" })
          .then(function (response) {
            // Notify the user that signin succeeded! Do amazing, signed-in things!
          });
      } else {
        // See the Federated Sign-in example
      }
    });

1.2.2. Federated Sign-in

A website that supports federated identity providers as well as passwords can request credentials, and use them to kick off the sign-in flow for the user’s chosen provider:

navigator.credentials.get({
  "password": true,
  "federated": {
    "providers": [ "https://federation.com" ]
  }
}).then(
    function(credential) {
      if (!credential)
        return;

      if (credential.type == "federated") {
        switch (credential.provider) {
        case "https://www.facebook.com/":
          // Use Facebook’s SDK, a la
          // https://developers.facebook.com/docs/facebook-login/login-flow-for-web/#logindialog
          FB.login(function (response) {
            if (response.status === "authorized") {
              // Can now use FB.api() calls
            } else {
              // Explain to the user that we would really like them to
              // click "Log me in".
            }
          });
          break;

        case "https://accounts.google.com/":
          // Ditto
          break;

        // ...
        }
      } else {
        fetch("https://example.com/loginEndpoint", { body: credential.toFormData(), method: "POST" })
          .then(function (response) { ... })
          .catch(function (response) { ... });
      }
    });

Note: This API does not go out to the identity provider to grab a token, or authenticate the user in any way. It provides a hint to the website as to which identity provider the user prefers to use, and little more. See §9 Future Work for directions future versions of this API could take.

1.2.3. Post-sign-in Confirmation

To ensure that credentials are persisted correctly, it may be useful for a website to tell the credential manager that sign-in succeeded.

If a user is signed in by calling toFormData() on a PasswordCredential object, and submitting that data to a sign-in endpoint via fetch() then we can check the response to determine whether the user was signed in successfully, and notify the user agent accordingly:
var credential = new PasswordCredential({
  "id": "JaneDoe98",
  "password": "MfPeRQq5P3yVry68Q4KZMMhB"
});
fetch("https://example.com/sign-in/", { body: credential.toFormData(), method: "POST" })
  .then(function (response) {
    if (response.status == 200)
      navigator.credentials.store(credential);
  });

Note: This example assumes that the sign-in API endpoint will differentiate between success and failure via an HTTP response code. This is a reasonable model, but it would of course also be possible to parse the response body for a success property, or some other form of application-specific signal.

If we’re using a federated identity provider:
if (navigator.credentials) {
  navigator.credentials.store(
    new FederatedCredential({
      "id": "username",
      "provider": "https://federation.com"
    })
  );
}

1.2.4. Sign-Up

The "federated sign-in" mechanism can be reused for "sign-up" with no modifications: if the user has a credential from a supported federated identity provider, it could be offered to the user via the same request mechanism.

1.2.5. Change Password

The "Password Sign-In" mechanism can be reused for "password change" with no modifications: if the user changes her credentials, the website can notify the user agent that she’s successfully signed in with new credentials. The user agent can then update the credentials it stores.

2. Key Concepts and Terminology

Credentials
Password Credentials
Federated Credentials
Broadly speaking, credential is an assertion about an entity which enables a trust decision. This specification defines two specific types of credentials which are useful for authentication: "password" credentials, which consist of a username/password pair, and "federated" credentials, which point out to a federated identity provider which is trusted to correctly assert a user’s authentication.

Note: These two types are, of course, not exhaustive. Future versions of this and other documents will likely define other types of credentials.

Credential Store
A credential store is an opaque storage mechanism which offers a user agent the ability to:
  1. Store, retrieve, and modify Credential objects.

  2. To mark an origin with a requires user mediation flag.

  3. To associate an origin with a protocol set.

The implementation is vendor-specific, and the interface provided is not exposed to the web.

Note: The types of credentials defined in this document are stored locally in a user agent’s credential store, but future versions of this and other documents will likely define credential types which are external to the user agent.

Federated Identity Provider
A federated identity provider is an entity which a website trusts to correctly authenticate a user, and which provides an API for that purpose. OpenID Connect is an example of such a framework, used by a number of providers.

3. Interfaces

3.1. Credential Types

This document defines a generic and extensible Credential interface from which all credentials will inherit, and a slightly less generic OriginBoundCredential, which defines the specific attributes shared by any Credential persisted in user agent’s credential store.

PasswordCredential and FederatedCredential both inherit from OriginBoundCredential, and, as you might expect, are the concrete types mapped to password credentials and federated credentials, respectively.

3.1.1. Credential

dictionary CredentialData {
  DOMString id;
};

interface Credential {
  readonly attribute DOMString id;
  readonly attribute DOMString type;
};
Credential implements Transferable;
id, of type DOMString, readonly
The credential’s identifier. This might be a GUID, username, or email address, for instance.
type, of type DOMString, readonly
The credential’s type. This attribute’s getter returns the value of the credential’s [[type]] slot.

Note: The [[type]] slot’s value will be the same for all credentials implementing a particular interface. Currently, PasswordCredential objects have a [[type]] of password, and FederatedCredential objects have a [[type]] of federated.

[[type]]
All Credential objects have an internal slot named [[type]], which unsurprisingly contains a string representing the type of the credential. This property is exposed to the web via the type attribute.

Credential objects implement Transferable, and MUST support the the structured clone algorithm. Unless otherwise specified, the cloning mechanism for all objects which implement Credential is defined in §4.1.3 Clone credential.

dictionary OriginBoundCredentialData : CredentialData {
  DOMString name;
  USVString iconURL;
};

interface OriginBoundCredential : Credential {
  readonly attribute DOMString name;
  readonly attribute USVString iconURL;
};

3.1.2. OriginBoundCredential

name, of type DOMString, readonly
A name associated with the credential, intended as a human-understandable public name.
iconURL, of type USVString, readonly
A URL pointing to an image for the credential. This URL MUST NOT be an a priori insecure URL.

Anne suggests that this might be better modeled as an ImageBitmap or blob:. We also need to figure out responsiveness. Perhaps [MANIFEST]'s format? <https://github.com/w3c/webappsec/issues/247>

[[origin]]
All OriginBoundCredential objects have an internal slot named [[origin]], which stores the origin to which the credential is bound. This property is not directly exposed to the web.

All OriginBoundCredential objects MUST define an options matching algorithm which returns Match if the object matches a CredentialRequestOptions object, and Does Not Match otherwise.

3.1.3. PasswordCredential

dictionary PasswordCredentialData : OriginBoundCredentialData {
  DOMString password;
};

dictionary FormDataOptions {
  DOMString idName = "username";
  DOMString passwordName = "password";
};

[Constructor(PasswordCredentialData data), Exposed=Window]
interface PasswordCredential : OriginBoundCredential {
  FormData toFormData(optional FormDataOptions formDataOptions);
};
toFormData(formDataOptions)
This method will generate an opaque FormData object containing the id and [[password]] associated with this credential, which can then be used to asynchronously sign a user into an origin via Fetch.

The user agent MUST execute the algorithm described in §4.3.1 Generate a FormData object from password credential when this method is executed.

Parameter Type Nullable Optional Description
formDataOptions FormDataOptions A set of options governing the FormData object’s construction.
Arguments for the PasswordCredential.toFormData(formDataOptions) method.
[[type]]
All PasswordCredential objects have their [[type]] slot’s value set to the string "password".

All PasswordCredential objects have an internal slot named [[password]] which stores the credential’s password. This property is not directly exposed to the web, but used to construct the FormData object generated during toFormData().

3.1.3.1. Matching Algorithm

PasswordCredential objects' options matching algorithm always returns Match.

3.1.4. FederatedCredential

dictionary FederatedCredentialData : OriginBoundCredentialData {
  USVString provider;
  DOMString protocol;
};

[Constructor(FederatedCredentialData data), Exposed=Window]
interface FederatedCredential : OriginBoundCredential {
  readonly attribute USVString provider;
  readonly attribute DOMString? protocol;

  static Promise<any> registerAsProvider(DOMString protocol);
};
provider, of type USVString, readonly
The credential’s federated identity provider. For details regarding valid formats, see §3.2.2 Identifying providers.
protocol, of type DOMString, readonly, nullable
The credential’s federated identity provider’s protocol (e.g. "openidconnect"). If this value is null, then the protocol can be inferred from the provider.
registerAsProvider(protocol)
When this method is called, execute the §4.4.1 Register origin as a federated identity provider which supports protocol algorithm on the origin of the incumbent settings object and protocol.
[[type]]
All FederatedCredential objects have their [[type]] slot’s value set to the string "federated".
3.1.4.1. Matching Algorithm

FederatedCredential objects' options matching algorithm is as follows. Given a FederatedCredential (credential) and a CredentialRequestOptions (options):

  1. Let federated be the value of options’s federated property.
  2. If the providers property is present in federated:
    1. For each provider in federated' providers list:
      1. Return Matches if credential’s provider is a case-sensitive match for provider.
  3. If the protocols property is present in federated:
    1. For each protocol in federated' protocols list:
      1. Return Matches if credential’s protocol is a case-insensitive match for protocol.
  4. Return Does Not Match.

3.2. Credential Manager

The credential manager hangs off of the Navigator object, and exposes methods to request credentials, and to notify the user agent when interesting events occur: successful sign in and sign out.

partial interface Navigator {
  readonly attribute CredentialContainer credentials;
};
interface CredentialContainer {
  Promise<Credential?> get(CredentialRequestOptions options);
  Promise<Credential> store(Credential credential);
  Promise<void> requireUserMediation();
};
get()
Request a credential from the credential manager.

The options argument contains an object filled with type-specific sets of parameters which will be used to select a particular Credential to return. This process is described in each Credential type’s options matching algorithm.

When get() is called, the user agent MUST execute the algorithm defined in §4.1.1 Request a Credential on types and options.

Note: If and when we need to support returning more than a single credential in response to a single call, we will likely introduce a getAll() method which would return Promise<sequence<Credential>>.

Parameter Type Nullable Optional Description
options CredentialRequestOptions The set of properties governing the scope of the request.
Arguments for the CredentialContainer.get(options) method.
store()
Ask the credential manager to store a Credential for the user. Authors could call this method after a user successfully signs in, or after a successful password change operation.

When store() is called, the user agent MUST execute the algorithm defined in §4.1.2 Store a Credential with credential as an argument.

Parameter Type Nullable Optional Description
credential Credential The credential to be stored.
Arguments for the CredentialContainer.store(credential) method.
requireUserMediation()
Ask the credential manager to require user mediation before returning credentials for the origin in which the method is called. This might be called after a user signs out of a website, for instance, in order to ensure that she isn’t automatically signed back in next time she visits.

When requireUserMediation() is called, the user agent MUST execute the algorithm defined in §4.5.1 Require user mediation for origin with the origin of the incumbent settings object in which this method is called.

3.2.1. get() Parameters

In order to obtain the desired Credential via get(), the caller specifies a few parameters in a CredentialRequestOptions object.

Note: The CredentialRequestOptions dictionary is an extension point. If and when new types of credentials are introduced that require options, their dictionary types will be added to the dictionary so they can be passed into the request. See §8.2 Extension Points.

3.2.1.1. CredentialRequestOptions dictionary
dictionary CredentialRequestOptions {
  boolean password;
  FederatedCredentialRequestOptions federated;

  boolean suppressUI = false;
};
password, of type boolean
If set, the user agent will request PasswordCredential objects, as outlined in §4.1.1 Request a Credential.
federated, of type FederatedCredentialRequestOptions
If set, the user agent will request FederatedCredential objects, as outlined in §4.1.1 Request a Credential.
suppressUI, of type boolean, defaulting to false
If true, the user agent will only attempt to provide a Credential without user interaction: if the user has explicitly opted-into always giving a particular site access to a particular set of credentials, they will be provided. If not, the promise will resolve with undefined. For processing details, see the algorithm defined in §4.1.1 Request a Credential.
3.2.1.2. FederatedCredentialRequestOptions dictionary
dictionary FederatedCredentialRequestOptions {
  sequence<USVString> providers;
  sequence<DOMString> protocols;
};
providers, of type sequence<USVString>
An array of federation identifiers. For details regarding valid formats see §3.2.2 Identifying providers.
protocols, of type sequence<DOMString>
A sequence of protocol identifiers.
Suppose https://example.com/ only supports federated sign-in via https://identity.example.com/. It could request credentials via the following call:
navigator.credentials.get({
  "federated": {
    "providers": [ "https://identity.example.com/" ]
  }
}).then(function (credential) {
  // ...
});

If it wanted to ensure that the user agent didn’t bother the user with questions, it could ask to suppress UI for the request (and, therefore, to receive Credentials if and only if the user had chosen to automatically sign into the origin):

navigator.credentials.get(
  "federated": {
    "providers": [ "https://identity.example.com/" ]
  },
  "suppressUI: true
).then(function (credential) {
  // ...
});

3.2.2. Identifying providers

Every site should use the same identifier when referring to a specific federated identity provider. For example, Facebook Login shouldn’t be "Facebook" and "Facebook Login" and "FB" and "FBL" and "Facebook.com" and so on. It should have a canonical identifier which everyone can make use of, as consistent identification makes it possible for user agents to be helpful.

For consistency, federations passed into the APIs defined in this document (e.g. FederatedCredentialRequestOptions's providers array, or FederatedCredential's provider property) MUST be identified by the ASCII serialization of the origin the provider uses for sign in. That is, Facebook would be represented by https://www.facebook.com and Google by https://accounts.google.com.

The ASCII serialization of an origin does not include a trailing U+002F SOLIDUS ("/"), but user agents SHOULD accept them silently: https://accounts.google.com/ is clearly intended to be the same as https://accounts.google.com.

3.3. Opaque FormData objects

FormData objects have a opaque flag, unset by default, and set only if the object is constructed from a PasswordCredential. Opaque FormData objects return null and the empty sequence when their get() and getAll() methods are executed, respectively. Further, data from opaque FormData objects can only be extracted in the context of executing XMLHttpRequest's send() method.

Opaque FormData objects have the following properties:

  1. Whenever the user agent would execute an opaque FormData object’s get() method, it MUST return null.
  2. Whenever the user agent would execute an opaque FormData object’s getAll() method, it MUST return the empty sequence.
  3. The opaqueness of a FormData object taints Request objects created from them. The Body accessor methods will reject with a TypeError.

3.3.1. Algorithm Modifications

Monkey-patching! Hooray! Talk with Anne, et al.

3.3.1.1. XHR: FormData Iteration

Replace the following text from FormData:

The value pairs to iterate over are the entries with the key being the name and the value the value.

With:

The value pairs to iterate over is an empty list if the opaque flag is set, otherwise the entries with the key being the name and the value the value.
3.3.1.2. XHR: FormData’s get()

Redefine FormData's get() method as follows:

  1. If the opaque flag is set, return null.
  2. Otherwise, return the value of the first entry whose name is is name, and null if no such entry exists.
3.3.1.3. XHR: FormData’s getAll()

Redefine FormData's getAll() method as follows:

  1. If the opaque flag is set, return the empty sequence.
  2. Otherwise, return the values of all entries whose name is name, in list order, and the empty sequence if no such entry exists.
3.3.1.4. Fetch: Body objects

Add a new opaque flag to Fetch’s Body interface. This flag is unset unless otherwise specified.

Replace the arrayBuffer() method’s definition with:

  1. If the opaque flag is set, return a Promise rejected with a TypeError.

  2. Return the result of running consume body with ArrayBuffer.

Replace the blob() method’s definition with:

  1. If the opaque flag is set, return a Promise rejected with a TypeError.

  2. Return the result of running consume body with Blob.

Replace the formData() method’s definition with:

  1. If the opaque flag is set, return a Promise rejected with a TypeError.

  2. Return the result of running consume body with FormData.

Replace the json() method’s definition with:

  1. If the opaque flag is set, return a Promise rejected with a TypeError.

  2. Return the result of running consume body with JSON.

Replace the text() method’s definition with:

  1. If the opaque flag is set, return a Promise rejected with a TypeError.

  2. Return the result of running consume body with text.

Note: We reject each of the accessor methods' Promises, which which means that the body remains unconsumed.

3.3.1.5. Fetch: Request’s constructor

Perform the following after step 33 of the current Request() constructor:

  1. If init’s body member is a FormData object whose opaque flag is set, or input’s opaque flag is set, set r’s opaque flag.

4. Algorithms

4.1. Processing Credentials

4.1.1. Request a Credential

Given a sequence<DOMString> (types) and a CredentialRequestOptions object (options), this algorithm returns a Promise which resolves with either a single Credential object if one can be obtained, or undefined if not.

If called from an environment which is not a secure context, or from somewhere other than a top-level browsing context, the Promise will be rejected with a NotSupportedError.

  1. Let settings be the incumbent settings object.
  2. Let origin be settings' origin.
  3. Return a Promise rejected with NotSupportedError if any of the following statements are true:
    1. settings does not have a responsible document
    2. settings' responsible document is not the active document in the top-level browsing context
    3. settings is not a secure context
  4. Let types be an empty set.
  5. For each key in options:
    1. Let interface be the interface whose name is key, or null if no interface’s name matches.
    2. If interface is not null, insert interface into possible types.
  6. Let type be the lowest common ancestor interface of the interfaces contained in types.

    Note: That is, given a set containing PasswordCredential and FederatedCredential, type will be OriginBoundCredential.

  7. Return a Promise rejected with TypeMismatchError if type is Credential.
  8. Let promise be a newly created Promise object.
  9. Return promise, and execute the remaining steps asynchronously.
  10. Switch on type, and execute the associated steps:
    FederatedCredential
    OriginBoundCredential
    PasswordCredential
    1. Let result be the result of executing §4.2.2 Request an OriginBoundCredential without user mediation, passing in origin, types and options.
    2. If result is not null, resolve promise with result, and terminate this algorithm.
    3. If options’s suppressUI is true, resolve promise with undefined, and terminate this algorithm.
    4. If this algorithm would not be allowed to show a popup, then reject promise with a SecurityError and terminate this algorithm.

      Note: This boils down to requiring a user gesture for get() before showing the user any UI.

    5. Resolve promise with the result of executing §4.2.3 Request a OriginBoundCredential with user mediation, passing in origin, types, and options.
    This is an extension point.
    When new credential types are defined in the future, they’ll go here.

Note: Currently, we reject a call to get() if the options provided specify a set of Credential types that don’t play well together (e.g. some future "NeedsLotsOfUserInteractionCredential" type in the same request as an PasswordCredential). We may wish to define a more graceful fallback mechanism if/when new credential types are defined.

4.1.2. Store a Credential

Given a Credential object (credential), this algorithm executes a type-specific storage algorithm. OriginBoundCredential objects will be persisted to the user agent’s credential store. Future object types could, for instance, be persisted to some other (potentially remote) storage mechanism.

If called from an environment which is not a secure context, or from somewhere other than a top-level browsing context, the Promise will be rejected with a NotSupportedError.

  1. Let settings be the incumbent settings object.
  2. Let origin be settings' origin.
  3. Return a Promise rejected with NotSupportedError if any of the following statements are true:
    1. settings does not have a responsible document
    2. settings' responsible document is not the active document in the top-level browsing context
    3. settings is not a secure context
  4. Let promise be a newly created Promise object.
  5. Return promise, and execute the remaining steps asynchronously.
  6. Switch on type, and execute the associated steps:
    FederatedCredential
    OriginBoundCredential
    PasswordCredential
    1. Resolve promise with the result of executing §4.2.4 Store OriginBoundCredential, passing in credential and origin.
    This is an extension point.
    When new credential types are defined in the future, they’ll go here.

4.1.3. Clone credential

Given a Credential (input), the following algorithm defines the way in which a structured clone will be produced. This algorithm plugs into the internal structured cloning algorithm defined in [HTML]:

  1. Let output be a Credential object of the same type as input’s constructor.
  2. For each internal slot on input:
    1. Let name be the name of the slot.
    2. Let source value be the slot’s value.
    3. Let cloned value be the result of invoking the internal structured cloning algorithm with source value as the "input" argument, and memory as the "memory" argument.
    4. If an exception results from the previous step, abort the overall structured clone algorithm, and pass that exception through to the caller.
    5. Add a new slot to output having name name and value cloned value.
  3. Set deep clone to own.

4.2. Processing OriginBoundCredentials

4.2.1. Gather OriginBoundCredentials

Given an origin (origin), and a set of interfaces (types), and an CredentialRequestOptions dictionary (options), this algorithm returns a sequence of OriginBoundCredential from the user agent’s credential store which are potential candidates:

  1. Let credentials be the set of Credential objects in the credential store whose [[origin]] slot is equal to the ASCII serialization of origin.

    Note: This is an exact match, not a registerable domain match. See §6.1 Cross-origin Credential Leakage for details as to why.

  2. The user agent MAY synthesize Credential objects to add to the list based on vendor-specific heuristics (as described in §5.3.1 Synthesizing Credentials).
  3. Remove any items from credentials whose interface is not present in types.
  4. Remove any items from credentials whose options matching algorithm returns Does Not Match when executed on options.
  5. Return credentials.

4.2.2. Request an OriginBoundCredential without user mediation

This algorithm accepts an origin (origin), a set of interfaces (types) and an CredentialRequestOptions dictionary (options), and returns either a single OriginBoundCredential object if and only if one can be provided without user mediation, or null if not.

  1. If the user agent has disabled sharing credentials without user mediation, or origin’s requires user mediation flag in the user agent’s credential store is true, return null.

    Note: See §5.2 Requiring User Mediation for details.

  2. Let credentials be the result of executing §4.2.1 Gather OriginBoundCredentials on origin, types, and options.
  3. If credentials is empty, or contains more than one Credential object, return null.

    Note: In the future, we may wish to allow multiple Credential objects to be returned; for the moment, we’re erring on the cautious side to avoid accidentally revealing explicit relationships between user accounts.

  4. Otherwise, let credential be the single Credential object in credentials.
  5. Return credential.

Note: If a user agent implements some sort of "private browsing" mode, we recommend that this algorithm always return null when the user has enabled private browsing.

4.2.3. Request a OriginBoundCredential with user mediation

This algorithm accepts an origin (origin), a set of interfaces (types) and an CredentialRequestOptions dictionary (options), and returns either a single OriginBoundCredential object, or null if none can be provided.

  1. Let credentials be the result of executing §4.2.1 Gather OriginBoundCredentials on origin, types, and options.
  2. Ask the user which Credential to share.

    Note: This behavior is vendor-specific. Guidelines for user agent behavior are presented in §5 User Mediation.

  3. Let credential be the Credential the user chose, or null if the user chose not to share a credential with origin.
  4. Return credential.

4.2.4. Store OriginBoundCredential

This algorithm accepts a OriginBoundCredential (credential), and an origin (origin), and hands it to the internal credential manager for processing. It returns credential regardless of whether the user allows or disallows the credential to be persisted to the credential store:

  1. Set credential’s [[origin]] slot to the ASCII serialization of origin.
  2. If credential’s iconURL is an a priori insecure URL, set credential’s iconURL to the empty string.
  3. Switch on credential’s primary interface, and execute the associated steps:
    PasswordCredential
    1. If the user agent’s credential manager contains a PasswordCredential storedCredential whose id attribute is credential’s id and whose [[origin]] slot is origin, then:
      1. If the user grants origin permission to update credentials (as discussed in §5.1 Storing and Updating Credentials), then:
        1. Set storedCredential’s [[password]] to the value of credential’s [[password]] slot.
        2. Set storedCredential’s name to the value of credential’s name.
        3. Set storedCredential’s iconURL to the value of credential’s iconURL.
    2. Otherwise:
      1. If the user grants origin permission to store credentials (as discussed in §5.1 Storing and Updating Credentials), then store credential in the credential store.
    FederatedCredential
    1. If the user agent’s credential manager does not contain a FederatedCredential storedCredential whose id attribute is credential’s id and whose provider attribute is credential’s provider, then:
      1. If the user grants origin permission to store credentials (as discussed in §5.1 Storing and Updating Credentials), store credential in the credential store.
    This is an extension point.
    When new credential types are defined in the future, they’ll go here.
  4. Return credential.

4.3. Processing PasswordCredentials

4.3.1. Generate a FormData object from password credential

Given a FormDataOptions (options) and a PasswordCredential (credential), this method will create an opaque FormData object which can be used to submit the credential information to a sign-in endpoint.

  1. Let environment be the incumbent settings object.
  2. Return a new FormData object and terminate this algorithm if any of the following conditions are true:
    1. §4.5.2 Does credential match origin B? returns No Match when executed upon credential and environment’s origin.
    2. environment is not a secure context
  3. Let fd be a new FormData object.
  4. Set fd’s opaque flag.
  5. Append a new entry to fd’s list of entries whose name is option’s idName, and whose value is credential’s id.
  6. Append a new entry to fd’s list of entries whose name is option’s passwordName, and whose value is credential’s [[password]].
  7. Resolve fd.

4.4. Processing FederatedCredentials

4.4.1. Register origin as a federated identity provider which supports protocol

Given an origin (origin), and a string which identifies a protocol (protocol), this algorithm registers the association in the credential store:

  1. Let protocols be the protocol set obtained from the credential store for origin.
  2. Add protocol to protocols.

4.5. Helpful Algorithms

4.5.1. Require user mediation for origin

  1. Let promise be a newly created Promise object.
  2. Return promise, and execute the remaining steps asynchronously.
  3. Set origin’s requires user mediation flag to true in the user agent’s credential store.
  4. Resolve promise with undefined.

4.5.2. Does credential match origin B?

  1. Let origin A be the value of credential’s [[origin]] slot.
  2. If origin A is the same as origin B, return Exact Match.
  3. If origin A’s scheme is origin B’s scheme, and origin A’s host's registerable domain is origin B’s host's registerable domain, then return Fuzzy Match.
  4. Return No Match

5. User Mediation

Exposing credential information to the web via an API has a number of potential impacts on user privacy. The user agent, therefore, MUST involve the user in a number of cases in order to ensure that she clearly understands what’s going on, and with whom her credentials are being shared.

5.1. Storing and Updating Credentials

Credential information is sensitive data, and users MUST remain in control of that information’s storage. Inadvertent credential storage could, for instance, unexpectedly link a user’s local profile on a particular device to a specific online persona. To mitigate the risk of surprise:

  1. Credential information MUST NOT be stored or updated without explicit user consent. For example, the user agent could display a "Save this password?" dialog box to the user in response to each call to store().
  2. User consent MAY be requested every time a credential is stored or updated, or the user agent MAY request a more persistent grant of consent which would apply to some or all subsequent API operations.

    For example, a user agent may offer an option to "Always save passwords", or "Always save password on this site".

  3. User agents SHOULD notify users when credentials are stored. This might take the form of an icon in the address bar, or some similar location.
  4. User agents MUST allow users to manually remove stored credentials. This functionality might be implemented as a settings page, or via interaction with a notification as described above.

5.2. Requiring User Mediation

If a an origin’s requires user mediation flag is set to false in the user agent’s credential store, then Credential objects from that origin MAY be provided to pages from that origin without user interaction. The user will be signed-in to that origin persistently, which, on the one hand, is desirable from the perspective of usability and convenience, but which might nevertheless surprise the user.

If the user agent syncs the state of a Credential between devices, an origin could explicitly tie the devices together in a way which might surprise their owner.

To mitigate the risk of surprise:

  1. User agents MUST allow users to require user mediation for Credential objects. This functionality might be implemented as a global toggle that requires user mediation for all origins, or via more granular settings for specific origins (or specific credentials on specific origins).
  2. User agents MUST NOT set an origin’s requires user mediation slot’s value to false without user consent. For example, the credential chooser described in §5.3 Credential Selection could have a checkbox which the user could toggle to mark the selected credential as available without mediation for the origin, or the user agent could have an onboarding process for its credential manager which asked a user for a default setting.
  3. User agents MUST notify users when credentials are provided to an origin. This could take the form of an icon in the address bar, or some similar location.
  4. If a user clears her browsing data for an origin (cookies, localStorage, and so on), the user agent MUST require user mediation for that origin by executing the algorithm defined in §4.5.1 Require user mediation for origin.

5.3. Credential Selection

When responding to a call to get() on an origin without credentials that are available without user mediation, user agents MUST ask the user for permission to share credential information. This SHOULD take the form of a credential chooser which presents the user with a list of credentials that are available for use on a site, allowing her to select one which should be provided to the website, or to reject the request entirely.

The chooser interface SHOULD be implemented in such a way as to be distinguishable from UI which a website could produce. For example, the chooser might overlap the user agent’s UI in some unspoofable way.

The chooser interface SHOULD include an indication of the origin which is requesting credentials.

The chooser interface SHOULD include all Credential objects associated with the origin that requested credentials. It may also synthesize Credential objects to support a sign-up use case, as discussed in §5.3.1 Synthesizing Credentials.

The following image is an exceptionally non-normative mock:

A mockup of what a chooser might look like.

User agents MAY internally associate information with each Credential object beyond the attributes specified in this document in order to enhance the utility of such a chooser. For example, favicons could help disambiguate identity providers, etc. Any additional information stored MUST not be exposed directly to the web.

5.3.1. Synthesizing Credentials

In response to a call to get() a user agent can offer a user the ability to create a Credential on the fly, rather than returning an empty set. Since credentials suggested in the credential chooser are never exposed to the web unless the user explicitly selects them, the user agent is free to use any of a number of heuristics to help a user get signed-into/-up for a website.

Credentials SHOULD be synthesized to populate a chooser based on the following heuristics:

  1. Let synthesized be an empty list.
  2. For each member in the dictionary members of get()'s options argument:
    1. Let interface be the name of the interface inheriting from Credential whose objects' type property’s value matches member’s key, or null if no such interface exists.

      Note: That is, instances of FederatedCredential have a type property with a value of "federated". An options argument’s federated member would map to FederatedCredential in this step.

    2. Switch on interface, and execute the associated steps:
      FederatedCredential
      When executing the §4.2.1 Gather OriginBoundCredentials algorithm, a user agent MAY populate the chooser with options based on the following heuristic, if no OriginBoundCredentials are available:
      1. For each PasswordCredential credential in the credential store:
        1. For each provider in options' providers property:
          1. If §4.5.2 Does credential match origin B? returns Exact Match or Fuzzy Match when executed upon credential and provider:
            1. Create a new FederatedCredential object new whose [[origin]] slot is set to the origin of the incumbent settings object, id is set to credential’s id, provider is set to provider.
            2. Append new to synthesized.
      2. For each origin for which the credential store has stored a protocol set:
        1. For each protocol in options' protocols property:
          1. If origin’s protocol set contains protocol:
            1. Create a new FederatedCredential object new whose [[origin]] slot is set to the origin of the incumbent settings object, provider is set to origin, and protocol is set to protocol.
            2. Append new to synthesized.
      This is an extension point.
      When new credential types are defined in the future, they’ll go here.
  3. Return synthesized.

User agents MAY employ additional heuristics (based, for instance, on a user’s browsing history, crowdsourcing, etc) to further populate the chooser.

Assume for a moment that https://example.com/ is an amazing new website that supports a large number of federated identity providers in an effort to make sign-up as seamless as possible for new users. This ends up being a bit counterproductive, as the site needs to display a list of dozens of providers, hoping that users will see an icon they remember.

A call to get() will end up with an empty list of Credential objects for new users, as they won’t have any https://example.com/ credentials. They might, however, have a PasswordCredential stored for the exciting social media site https://federation.com/, which they visit daily.

In this case, based on its knowledge of the user’s history and credentials, the user agent might choose to synthesize a FederatedCredential for https://example.com/, using the id from https://federation.com/’s PasswordCredential, and offer it to the user as a sign-up options in a chooser.

In this way, https://example.com/ can support dozens of providers as arguments to get() (via FederatedCredentialRequestOptions's providers property), and the user agent can cull that list down to the federations with which the user regularly interacts (or which have been previously used as FederatedCredentials, or any of a number of other heuristics).

6. Security Considerations

6.1. Cross-origin Credential Leakage

Credentials are sensitive information, and user agents need to exercise caution in determining when they can be safely shared with a website. The safest option is to restrict credential sharing to the exact origin on which they were saved. That is likely too restrictive for the web, however: consider sites which divide functionality into subdomains: example.com vs admin.example.com.

As a compromise between annoying users, and securing their credentials, user agents:

  1. MUST NOT share credentials between origins whose scheme components are not the same. That is: credentials saved on https://example.com/ will never be available to http://example.com/ via a user agent’s autofill mechanism
  2. MAY use the Public Suffix List [PSL] to determine the effective scope of a credential by comparing the registerable domains of the credential’s [[origin]] with the origin in which get() is called. That is: credentials saved on https://admin.example.com/ and https://example.com/ MAY be offered to users when get() is called from https://www.example.com/.
  3. MUST NOT offer credentials to an origin in response to get() without user mediation if the credential’s origin is not an exact match for the calling origin. That is, Credential objects for https://example.com would not be returned directly to https://www.example.com, but could be offered to the user via the chooser.

PasswordCredentials further mitigate the risk of data leakage by never exposing the [[password]] slot directly to a page’s JavaScript, but instead constructing an opaque FormData object via toFormData().

Additionally, authors SHOULD mitigate the risk of leakage by setting a reasonable Content Security Policy [CSP2] which restricts the origins to which data can be sent. In particular, authors should ensure that the following directives are set, explicitly or implicitly, in their pages' policies:

  1. connect-src further restricts the origins to which fetch() may submit data (which mitigates the risk of redirect-based attacks).
  2. child-src restricts the nested browsing contexts which may be embedded in a page, making it more difficult to inject a malicious postMessage() target. [WEBMESSAGING]

6.2. Same-origin Leakage

Cross-site scripting attacks could make it possible to exploit toFormData() and fetch() in order to leak credential information via a vulnerable same-origin endpoint. To mitigate this kind of risk, authors SHOULD set a reasonable Content Security Policy which restricts the kinds of content which can execute in their sites' context. [CSP2] Moreover, authors should ensure that both script-src and object-src directives are set in any policy they specify in order to ensure that only trusted script is executed on a page with access to a user’s credentials.

6.3. Origin Confusion

If framed pages have access to the APIs defined here, it might be possible to confuse a user into granting access to credentials for an origin other than the top-level browsing context, which is the only security origin which users can reasonably be expected to understand.

Therefore, Nested browsing contexts and other environments like Workers [WORKERS] cannot receive or store Credential objects; the user agent MUST reject promises generated by calls to get() and store() with a SecurityError when called from a context which is not a top-level browsing context.

See the algorithms defined in §4.1.1 Request a Credential and §4.1.2 Store a Credential for details.

6.4. Insecure Sites

User agents MUST NOT expose the APIs defined here to environments which are not secure contexts. User agents MAY implement autofill mechanisms which store user credentials and fill sign-in forms on a priori insecure origins, but those sites cannot be trusted to interact directly with the credential manager in any meaningful way, and those sites MUST NOT have access to credentials saved in secure contexts (as discussed in §6.1 Cross-origin Credential Leakage.

6.5. Script Injection

If a malicious party is able to inject script into an origin, they could (among many other things you wouldn’t like) overwrite the behavior of store() to steal a user’s credentials as they’re written into the credential store.

Authors SHOULD mitigate the risk of such attacks by properly escaping input and output, and add layers of defense in depth by setting a reasonably strong Content Security Policy [CSP2] which restricts the origins from which script can be injected, and by using Subresource Integrity checks [SRI] to ensure that only trusted JavaScript is executed.

7. Privacy Considerations

7.1. Timing Attacks

If the user has no credentials for an origin, a call to get() will resolve very quickly indeed. A malicious website could distinguish between a user with no credentials and a user with credentials who chooses not to share them.

This could allow a malicious website to determine if a user has credentials saved for particular federated identity providers by repeatedly calling get() with a single item in the providers array. The risk is mitigated by the fact that a user-mediated get() is tied to a user gesture, and the user would, sooner or later, be prompted to provide credentials to the site which would certainly raise her suspicions as to its behavior.

7.2. Chooser Leakage

If a user agent displays images supplied by a website or federation (for example, if a Credential's iconURL is displayed), requests for these images MUST NOT be directly tied to instantiating the chooser in order to avoid leaking chooser usage. One option would be to fetch the images in the background when saving or updating a Credential, and to cache them for the lifetime of the Credential.

These images MUST be fetched with the credentials mode set to "omit", the skip-service-worker flag set, the client set to null, the initiator set to the empty string, and the destination set to subresource.

Moreover, if the user agent allows the user to change either the name or icon associated with the credential, the alterations to the data SHOULD NOT be exposed to the website (consider a user who names two credentials for an origin "My fake account" and "My real account", for instance).

7.3. Locally Stored Data

This API offers an origin the ability to store data persistently along with a user’s profile. Since most user agents treat credential data differently than "browsing data" (cookies, etc.) this might have the side effect of surprising a user who might believe that all traces of an origin have been wiped out when they clear their cookies.

User agents SHOULD provide UI that makes it clear to a user that credential data is stored for an origin, and SHOULD make it easy for users to remove such data when they’re no longer interested in keeping it around.

Moreover, the credential store’s association between origins and protocol sets SHOULD be cleared along with "browsing data" if no Credential has been stored for the origin.

8. Implementation Considerations

This section is non-normative.

8.1. Website Authors

Add some thoughts here about when and how the API should be used, especially with regard to suppressUI. <https://github.com/w3c/webappsec/issues/290>

8.2. Extension Points

As noted in §9 Future Work, there is known interest in extending the API defined here to serve use cases beyond those this document addresses. To that end, the API is fairly generic, with several explicit extension points.

If we wished to add a new credential type, how would we spell it out?
  1. Define a new ExampleCredential that inherits from Credential, and define the value of its [[type]] slot:
    interface ExampleCredential : Credential {
      // Definition goes here.
    };
    
    ...
    
    All `ExampleCredential` objects have their [[type]] slot’s
    value set to the string "example".
    
  2. Define the options that the new credential type requires, and add them to the CredentialRequestOptions dictionary with a property name that matches the [[type]] slot’s value.
    dictionary ExampleCredentialRequestOptions {
      // Definition goes here.
    };
    
    partial dictionary CredentialRequestOptions {
      ExampleCredentialRequestOptions? example;
    };
    
  3. Add ExampleCredential to the switch in step 8 of §4.1.1 Request a Credential, and define the request behavior necessary to grab and return the new type.
  4. Add ExampleCredential to the switch in step 6 of §4.1.2 Store a Credential, and define the persistance behavior necessary to store the new type.

You might also need new primitives. For instance, you might want to return many Credential objects rather than just one. That might be accomplished in a generic fashion by adding a getAll() method to CredentialContainer, and defining a CredentialSet object that contained a sequence<Credential>, and could be easily extended to meet some use case.

For any such extension, we recommend getting in touch with public-webappsec@ for consultation and review.

8.3. Browser Extensions

Ideally, user agents that implement an extension system of some sort will allow third-parties to hook into these API endpoints in order to improve the behavior of third party credential management software in the same way that user agents can improve their own via this imperative approach.

This could range from a complex new API that the user agent mediates, or simply by allowing extensions to overwrite the get() and store() endpoints for their own purposes.

9. Future Work

This section is non-normative.

The API defined here does the bare minimum to expose user agent’s credential managers to the web, and allows the web to help those credential managers understand when federated identity providers are in use. The next logical step will be along the lines sketched in documents like [WEB-LOGIN] (and, to some extent, Mozilla’s BrowserID [BROWSERID]).

The user agent is in the unique position of being able to effectively mediate the relationship between users, identity providers, and websites. If the user agent can remove some of the risk and confusion associated with the typical authentication flows, users will be in a significantly better position than today.

A natural way to expose this information might be to extend the FederatedCredential interface with properties like authentication tokens, and possibly to add some form of manifest format with properties that declare the authentication type which the provider supports.

The API described here is designed to be extensible enough to support use cases that require user interaction, perhaps with websites other than the one which requested credentials. We hope that the Promise-based system we’ve settled on is extensible enough to support these kinds of asynchronous flows which could require some level of interaction between multiple browsing contexts (e.g. mediated activity on idp.com might resolve a Promise handed back to rp.com) in the future without redesigning the API from the ground up.

Baby steps.

Groups like the Web Payments IG and the Credentials CG have expressed interest in extending the API defined in this document in order to address use cases beyond those outlined in §1.1 Use Cases. They’ve documented these use cases in detail in Web Payments Use Cases 1.0 and Credentials CG Use Cases, and anticipate extending the API in a separate document to solve a different set of problems than WebAppSec is currently chartered to deal with.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words "for example" or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word "Note" and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Conformance Classes

A conformant user agent must implement all the requirements listed in this specification that are applicable to user agents.

A conformant server must implement all the requirements listed in this specification that are applicable to servers.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[CSP2]
Mike West; Adam Barth; Dan Veditz. Content Security Policy Level 2. CR. URL: https://w3c.github.io/webappsec/specs/content-security-policy/
[FETCH]
Anne van Kesteren. Fetch. Living Standard. URL: https://fetch.spec.whatwg.org/
[MIX]
Mike West. Mixed Content. LCWD. URL: https://w3c.github.io/webappsec/specs/mixedcontent/
[POWER]
Mike West. Requirements for Powerful Features. ED. URL: https://w3c.github.io/webappsec/specs/powerfulfeatures/
[PSL]
Mozilla Foundation. Public Suffix List. URL: https://publicsuffix.org/
[RFC6454]
Adam Barth. The Web Origin Concept. RFC. URL: http://www.ietf.org/rfc/rfc6454.txt
[URL]
Anne van Kesteren. URL. Living Standard. URL: https://url.spec.whatwg.org/
[WebIDL]
Cameron McCormack; Boris Zbarsky. WebIDL Level 1. 4 August 2015. WD. URL: http://www.w3.org/TR/WebIDL-1/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/
[HTML5]
Ian Hickson; et al. HTML5. 28 October 2014. REC. URL: http://www.w3.org/TR/html5/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WEBMESSAGING]
Ian Hickson. HTML5 Web Messaging. 19 May 2015. REC. URL: http://www.w3.org/TR/webmessaging/

Informative References

[BROWSERID]
Ben Adida; et al. BrowserID. URL: https://github.com/mozilla/id-specs/blob/prod/browserid/index.md
[HTML]
Ian Hickson. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[MANIFEST]
Marcos Caceres; Anssi Kostiainen; Kenneth Rohde Christiansen; et al. Manifest for web application. WD. URL: http://w3c.github.io/manifest/
[SRI]
Frederik Braun. Subresource Integrity. 16 September 2015. WD. URL: http://www.w3.org/TR/SRI/
[WEB-LOGIN]
Jason Denizac; Robin Berjon; Anne van Kesteren. web-login. URL: https://github.com/jden/web-login
[XMLHttpRequest]
Anne van Kesteren; et al. XMLHttpRequest Level 1. 30 January 2014. WD. URL: http://www.w3.org/TR/XMLHttpRequest/
[WORKERS]
Ian Hickson. Web Workers. 1 May 2012. CR. URL: http://www.w3.org/TR/workers/

IDL Index

dictionary CredentialData {
  DOMString id;
};

interface Credential {
  readonly attribute DOMString id;
  readonly attribute DOMString type;
};
Credential implements Transferable;

dictionary OriginBoundCredentialData : CredentialData {
  DOMString name;
  USVString iconURL;
};

interface OriginBoundCredential : Credential {
  readonly attribute DOMString name;
  readonly attribute USVString iconURL;
};

dictionary PasswordCredentialData : OriginBoundCredentialData {
  DOMString password;
};

dictionary FormDataOptions {
  DOMString idName = "username";
  DOMString passwordName = "password";
};

[Constructor(PasswordCredentialData data), Exposed=Window]
interface PasswordCredential : OriginBoundCredential {
  FormData toFormData(optional FormDataOptions formDataOptions);
};

dictionary FederatedCredentialData : OriginBoundCredentialData {
  USVString provider;
  DOMString protocol;
};

[Constructor(FederatedCredentialData data), Exposed=Window]
interface FederatedCredential : OriginBoundCredential {
  readonly attribute USVString provider;
  readonly attribute DOMString? protocol;

  static Promise<any> registerAsProvider(DOMString protocol);
};

partial interface Navigator {
  readonly attribute CredentialContainer credentials;
};

interface CredentialContainer {
  Promise<Credential?> get(CredentialRequestOptions options);
  Promise<Credential> store(Credential credential);
  Promise<void> requireUserMediation();
};

dictionary CredentialRequestOptions {
  boolean password;
  FederatedCredentialRequestOptions federated;

  boolean suppressUI = false;
};

dictionary FederatedCredentialRequestOptions {
  sequence<USVString> providers;
  sequence<DOMString> protocols;
};

Issues Index

Anne suggests that this might be better modeled as an ImageBitmap or blob:. We also need to figure out responsiveness. Perhaps [MANIFEST]'s format? <https://github.com/w3c/webappsec/issues/247>
Monkey-patching! Hooray! Talk with Anne, et al.
Add some thoughts here about when and how the API should be used, especially with regard to suppressUI. <https://github.com/w3c/webappsec/issues/290>