The holidays are well and truly over, time to get serious - now is the perfect time to read specifications! If you are planning to read the WebAuthn specification, you can ease into the terminology in a simple way - take a cruise through the W3C Credential Management (aka CredMan) specification first. CredMan sets up the object model for the Credential object model that WebAuthn's PublicKeyCredential extends. This post will be an overview of the CredMan spec, geared for folks who want to call the API as clients, not for those few and proud who are tasked with implementation of the API within a user agent.
#IdentityStandards
CredMan Base Definitions
CredMan unsurprisingly centers on the concept of a Credential. Actions on Credentials are requested by a relying party using JavaScript and fulfilled by a user agent (generally a browser). Credentials can be created stored, retrieved for validation by a relying party and so on. In addition to actions, CredMan defines standardized dictionaries that communicate context. Note that the CredMan API itself does not use the term ‘relying party’ but instead refers to a developer that would write code using the navigator.credentials JavaScript control. Since we are identity architects, we will assume that developed code is deployed and running as a service at a specific origin and that the developed code will call the CredMan API as part of user registration and authentication activities.
The CredMan API defines three actions (and an object constructor):
Initialize
- Credential objects are instantiated with an id and type. Additional parameters can be specified by populating the CredentialData data dictionary.
create()
- The relying party instructs the user agent to make a new credential, based on parameters from the CredentialCreationOptions data dictionary. In the base definition the CredentialCreationOptions data dictionary is empty.
get()
- The relying party instructs the user agent to retrieve an existing credential, based on parameters in the CredentialRequestOptions data dictionary. In the base definition, CredentialRequestOptions contains the mediation parameter: it allows a relying party to instruct the user agent whether it must, may, or must not interact with the end user to gain explicit consent for the action. The mediation default value is ‘optional’, meaning that the relying party leaves the decision up to the user agent.
store()
- The relying party instructs the user agent to directly save an already instantiated credential object – for example a credential that might have been returned via a get() call and subsequently altered.
In addition to the task-specific actions and data dictionaries noted above, one data dictionary is defined that can be optionally added to any of the other dictionaries:
- Describes human-friendly information that the user agent could pass on to help a user properly identify a credential. The base values include a name and an icon URL.
User Mediation
CredMan defines an action as user mediated if the action “takes place after gaining a user’s explicit consent”. Choosing an account from a credential chooser during a get() or confirming storage of a credential both count as user-mediated actions.
Origin-bound credentials require user mediation by default, meaning that user agents must interact with the user in some decision-oriented way before taking actions like storing or retrieving credentials – however in the interests of creating a user experience that is contextually intelligent, options exist to change the circumstances where user mediation takes place:
- A user agent might offer to persist consent for ongoing use of a credential. In this case, access is considered to be “silent” and the action is considered un-mediated.
- Relying parties can choose to require mediation, require silent operation, or let the user agent choose. The mediation property in the CredentialRequestOptions structure is used for this purpose.
- By default, CredMan does not forbid a user agent to offer to persist consent for credential creation, however there are obvious risks, and the specification lays out recommendations for informing end users in the case where a new credential is silently created.
Types of Credential
CredMan extends the credential base class for two uses: Passwords and Federation discovery information. The W3C WebAuthn spec adds a third extension for cryptographic public keys.
PasswordCredential
When a relying party invokes the PasswordCredential interface, the user agent engages to create, retrieve, or change a shared secret stored in a credential store such as a password manager. The credential store might be built into the user agent or might just be facilitated by the user agent. Note that the relying party does not need to know anything about how the credential store works, or even which user agent has been invoked. That is the beauty of standards!
There are a ton of great examples in the spec, take a look through the link above. Here is a quick summary of how PasswordCredential modifies the Credential base class:
- The PasswordCredential object now contains a string for password storage, and defines two different constructor instances – one that will take an HTML form element as input and one that takes a PasswordCredentialData object as input
- CredentialRequestOptions (used to retrieve a password) gets an extra Boolean called password that is set to false by default. The password boolean must be explicitly set to true by the relying party for the user agent to know the relying party is ok with a PasswordCredential coming back from the call.
- CredentialCreationOptions gets a new object called password of type PasswordCredentialInit, which can be either a PasswordCredentialData object or an HTMLFormElement object.
PasswordCredentials are origin bound - the user agent stores a different shared secret per web origin, and takes on the responsibility to ensure that the secret-origin relationship is enforced.
FederatedCredential
Interacting with federated credentials also involves talking to a credential store, but instead of managing a shared secret, the user agent stores and retrieves the metadata necessary to initiate a federated authentication request to a remote identity provider. Whenever the user agent can supply a FederatedCredential to a requesting relying party, the relying party can bypass Identity Provider discovery prompts such as NASCAR interfaces and immediately initiate federation. This can represent a significant improvement in end user experience.
FederatedCredential details of note:
- The FederatedCredential object stores two new properties: provider and protocol. This creates the same internal construction as the FederatedCredentialInit data dictionary.
- A property called “federated” is added to the Request Options, of type FederatedCredentialRequestOptions: It contains two lists: providers and protocols. The federated property must be present in some form for a FederatedCredential to be returned, and the relying party can additionally populate 0 or more specific protocols or providers to be more specific about credentials they will accept.
FederatedCredential is also origin-bound.
Stay Tuned for PublicKeyCredential
Now that you see how PasswordCredental and FederatedCredential work, imagine the same paradigm applying to a cryptographic key, where a client can request a user agent to create or retrieve a public key from a user-controlled cryptographic platform or device. W3C WebAuthn takes on this challenge. Stay tuned for the next blog entry, where we will describe how WebAuthn extends the Credman API, and how a very small number of options and methods can grant relying parties access to a vast and growing set of highly secure user authentication options.
#DeploymentLandscape
Edge browser doesn’t support either PasswordCredential or FederatedCredential but both Firefox and Google have support, you could try this demo app. Google has useful sample code here and Mozilla’s API documentation is here.