Skip to content
KeystoneJS LogoKeystoneJS
👋🏻 Keystone 5 has officially moved to maintenance only. For the latest release of Keystone please visit the Keystone website.

Password

Password fields are unusual in that they do not store the value they are supplied. The value is run through the bcrypt algorithm to generate a hash which is stored instead.

bcrypt is a one-way, cryptographic hash function with build-in salt and a flexible work factor. It allows a candidate string (eg. a password sent for a login attempt) to be verified without knowledge of the original value.

Note: The bcrypt algorithm is applied by pre-save hooks on the model. Values set to Password fields may be readable by Node until the item has been saved.

Usage

JS
const { Password, Text } = require('@keystonejs/fields');

keystone.createList('User', {
  fields: {
    email: { type: Text },
    password: { type: Password },
  },
});

Config

OptionTypeDefaultDescription
minLengthInteger8The minimum number of characters this field will accept
rejectCommonBooleanfalseChecks the password against a list of commonly used passwords
workFactorInteger10Controls the processing time required to generate and validate hashes
isRequiredBooleanfalseDoes this field require a value?
useCompiledBcryptBooleanfalseUse the compiled bcrypt package rather than bcryptjs

minLength

The minimum number of characters this field will accept.

minLength must be greater than or equal to 1. Zero-length values can be suppled for a Password field but they will not be hashed; instead the stored value will be set to null.

The length of supplied values is evaluated using String().length. Due to JavaScript's Unicode problem, this does not account well for multibyte characters (such as some emoji), multi-code-point glyphs and other Unicode magic.

If a value is supplied that fails to fulfil the minimum length an error will be thrown. The error message will contain the string [password:minLength:${listKey}:${fieldPath}].

rejectCommon

Values are checked against a list of 10,000 common passwords as compiled by Mark Burnett. You should strongly consider enabling this feature in accordance with the NIST Digital Identity Guidelines.

When enable, if a a known-common password is supplied, an error will be thrown. The error message will contain the string [password:rejectCommon:${listKey}:${fieldPath}].

workFactor

Supplied as the bcrypt cost parameter; controls the computational cost of both creating and validating a hash. The value supplied should be between 4 and 31 (lower/higher values will be limited to this range). The default value is 10.

Higher values are slower but, since they take longer to generate, more secure against brute force attacks. The default value of 10 will allow the generation of a several hashes per second, per core, on most machines.

Note the workFactor supplied is applied by the bcrypt algorithm as an exponent of 2. As such, a work factor of 11 will cause passwords to take twice as long to hash and validate as a work factor of 10. A work factor of 12 will cause passwords to take four times as long as 10. Etc.

bcrypt

By default the bcryptjs package is used for computing and comparing hashes. This package provides a javascript implementation of the bcrypt algorithm. A compiled version of this algorithm is provided by the bcrypt package. Setting { bcrypt: require('bcrypt') } will make Keystone use the compiled package. If you use this, you must include bcrypt in your package dependencies.

The compiled package provides a ~20% performance improvement, and avoids the thread blocking of the JavaScript implementation. This comes with the trade off that the compiled package can be challenging to work with when working in some environments (e.g. Windows) or when trying to deploy code built in one environment onto a different environment (e.g. build on OSX to deploy in a Linux based lambda process).

Auth strategies

The Password field exposes a compare() function. This allows Password fields to be specified as a secretField when configuring a PasswordAuthStrategy. See the Authentication docs for details.

GraphQL

Password fields are somewhat unusual in that they can be written to but not read.

Input fields

Password fields at a String field to both create and update GraphQL Input types.

Field nameTypeDescription
${path}StringThe value to be hashed

Output fields

In normal usage, hash values should not be externally accessible. As such Password fields do not add a String output field.

Field nameTypeDescription
${path}_is_setBooleanDoes this field contain a hash

Filters

Field nameTypeDescription
${path}_is_setBooleanDoes this field contain a hash

Storage

The value stored is a bcrypt hash of the string provided.

Mongoose adapter

The hash is stored at ${path} as a String.

Knex adapter

The hash is stored at ${path} using the Knex string type with a max length of 60.

On this page

Edit on GitHub