Repository: authelia/authelia (go)

Issue:
High memory usage in docker w/ file-based user database
I've noticed an inordinate amount of memory usage reported following successful authentications when running Authelia inside of a docker container and utilizing a file-based user database.

Before authentication:

```
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
01aa33590ab0        authelia            0.00%               11.09MiB / 15.41GiB   0.07%               1.18kB / 0B         0B / 0B             11
```


After authentication:
```
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
01aa33590ab0        authelia            0.01%               1.049GiB / 15.41GiB   6.81%               22.7kB / 4.98kB     0B / 0B             11
```
I am using the default password hashing configuration (argon2id w/ default settings). It's possible that the libraries used to provide this configuration are not properly releasing memory after it has been allocated.

Pull request:
[BUGFIX] Password hashing schema map mismatch with docs
* fix the schema mapping the YAML to the password hashing configuration
* add a nolint for gosec 'possibly hardcoded password' that was incorrect

Fixes #845

Patch:
diff --git a/config.template.yml b/config.template.yml
index f86eec0d8..ec4672aa1 100644
--- a/config.template.yml
+++ b/config.template.yml
@@ -140,7 +140,7 @@ authentication_backend:
   # which is updated when users reset their passwords.
   # Therefore, this backend is meant to be used in a dev environment
   # and not in production since it prevents Authelia to be scaled to
-  # more than one instance. The options under password_options have sane
+  # more than one instance. The options under 'password' have sane
   # defaults, and as it has security implications it is highly recommended
   # you leave the default values. Before considering changing these settings
   # please read the docs page below:
@@ -148,7 +148,7 @@ authentication_backend:
   #
   ## file:
   ##   path: ./users_database.yml
-  ##   password_options:
+  ##   password:
   ##     algorithm: argon2id
   ##     iterations: 1
   ##     key_length: 32
diff --git a/docs/configuration/authentication/file.md b/docs/configuration/authentication/file.md
index 2c3720841..388e70be6 100644
--- a/docs/configuration/authentication/file.md
+++ b/docs/configuration/authentication/file.md
@@ -19,7 +19,7 @@ file in the configuration file.
         disable_reset_password: false
         file:
             path: /var/lib/authelia/users.yml
-            password_hashing:
+            password:
                 algorithm: argon2id
                 iterations: 1
                 salt_length: 16
@@ -97,26 +97,38 @@ Flags:
 
 ## Password hash algorithm
 
-The default hash algorithm is salted Argon2id version 19. Argon2id is currently considered 
+The default hash algorithm is Argon2id version 19 with a salt. Argon2id is currently considered 
 the best hashing algorithm, and in 2015 won the 
 [Password Hashing Competition](https://en.wikipedia.org/wiki/Password_Hashing_Competition).
 It benefits from customizable parameters allowing the cost of computing a hash to scale 
 into the future which makes it harder to brute-force. Argon2id was implemented due to community 
 feedback as you can see in this closed [issue](https://github.com/authelia/authelia/issues/577).
 
-Additionally SHA512 is supported for backwards compatibility and user choice. While it's a reasonable
-hash function given high enough iterations, as hardware gets better it has a higher chance of being 
-brute-forced.
+For backwards compatibility and user choice support for the SHA512 algorithm is still available. 
+While it's a reasonable hashing function given high enough iterations, as hardware improves it 
+has a higher chance of being brute-forced.
 
 Hashes are identifiable as argon2id or SHA512 by their prefix of either `$argon2id$` and `$6$` 
 respectively,  as described in this [wiki page](https://en.wikipedia.org/wiki/Crypt_(C)).
 
+**Important Note:** When using argon2id Authelia will appear to remain using the memory allocated
+to creating the hash. This is due to how [Go](https://golang.org/) allocates memory to the heap when
+generating an argon2id hash. Go periodically garbage collects the heap, however this doesn't remove
+the memory allocation, it keeps it allocated even though it's technically unused. Under memory
+pressure the unused allocated memory will be reclaimed by the operating system, you can test
+this on linux with 
+`stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1`.
+If this is not desirable we recommend investigating the following options in order of most to least secure:
+  1. using the [LDAP authentication provider](./ldap.md)
+  2. adjusting the [memory](#memory) parameter
+  3. changing the [algorithm](#algorithm)
+
 ### Password hash algorithm tuning
  
-All algorithm tuning is supported for Argon2id. The only configuration variables that affect 
+All algorithm tuning for Argon2id is supported. The only configuration variables that affect 
 SHA512 are iterations and salt length. The configuration variables are unique to the file
 authentication provider, thus they all exist in a key under the file authentication configuration
-key called `password_hashing`. We have set what are considered as sane and recommended defaults
+key called `password`. We have set what are considered as sane and recommended defaults
 to cater for a reasonable system, if you're unsure about which settings to tune, please see the 
 parameters below, or for a more in depth understanding see the referenced documentation in
 [Argon2 links](./file.md#argon2-links).
@@ -188,4 +200,4 @@ linked documents in [Argon2 links](./file.md#argon2-links).
 
 [Go Documentation](https://godoc.org/golang.org/x/crypto/argon2)
 
-[IETF Draft](https://tools.ietf.org/id/draft-irtf-cfrg-argon2-09.html)
\ No newline at end of file
+[IETF Draft](https://tools.ietf.org/id/draft-irtf-cfrg-argon2-09.html)
diff --git a/internal/authentication/file_user_provider.go b/internal/authentication/file_user_provider.go
index 58fd82dab..b2467fdb5 100644
--- a/internal/authentication/file_user_provider.go
+++ b/internal/authentication/file_user_provider.go
@@ -118,18 +118,18 @@ func (p *FileUserProvider) UpdatePassword(username string, newPassword string) e
 	}
 
 	var algorithm string
-	if p.configuration.PasswordHashing.Algorithm == "argon2id" {
+	if p.configuration.Password.Algorithm == "argon2id" {
 		algorithm = HashingAlgorithmArgon2id
-	} else if p.configuration.PasswordHashing.Algorithm == "sha512" {
+	} else if p.configuration.Password.Algorithm == "sha512" {
 		algorithm = HashingAlgorithmSHA512
 	} else {
 		return errors.New("Invalid algorithm in configuration. It should be `argon2id` or `sha512`")
 	}
 
 	hash, err := HashPassword(
-		newPassword, "", algorithm, p.configuration.PasswordHashing.Iterations,
-		p.configuration.PasswordHashing.Memory*1024, p.configuration.PasswordHashing.Parallelism,
-		p.configuration.PasswordHashing.KeyLength, p.configuration.PasswordHashing.SaltLength)
+		newPassword, "", algorithm, p.configuration.Password.Iterations,
+		p.configuration.Password.Memory*1024, p.configuration.Password.Parallelism,
+		p.configuration.Password.KeyLength, p.configuration.Password.SaltLength)
 
 	if err != nil {
 		return err
diff --git a/internal/commands/hash.go b/internal/commands/hash.go
index 381e7d2eb..27ff6f09a 100644
--- a/internal/commands/hash.go
+++ b/internal/commands/hash.go
@@ -10,13 +10,13 @@ import (
 )
 
 func init() {
-	HashPasswordCmd.Flags().BoolP("sha512", "z", false, fmt.Sprintf("use sha512 as the algorithm (changes iterations to %d, change with -i)", schema.DefaultPasswordOptionsSHA512Configuration.Iterations))
-	HashPasswordCmd.Flags().IntP("iterations", "i", schema.DefaultPasswordOptionsConfiguration.Iterations, "set the number of hashing iterations")
+	HashPasswordCmd.Flags().BoolP("sha512", "z", false, fmt.Sprintf("use sha512 as the algorithm (changes iterations to %d, change with -i)", schema.DefaultPasswordSHA512Configuration.Iterations))
+	HashPasswordCmd.Flags().IntP("iterations", "i", schema.DefaultPasswordConfiguration.Iterations, "set the number of hashing iterations")
 	HashPasswordCmd.Flags().StringP("salt", "s", "", "set the salt string")
-	HashPasswordCmd.Flags().IntP("memory", "m", schema.DefaultPasswordOptionsConfiguration.Memory, "[argon2id] set the amount of memory param (in MB)")
-	HashPasswordCmd.Flags().IntP("parallelism", "p", schema.DefaultPasswordOptionsConfiguration.Parallelism, "[argon2id] set the parallelism param")
-	HashPasswordCmd.Flags().IntP("key-length", "k", schema.DefaultPasswordOptionsConfiguration.KeyLength, "[argon2id] set the key length param")
-	HashPasswordCmd.Flags().IntP("salt-length", "l", schema.DefaultPasswordOptionsConfiguration.SaltLength, "set the auto-generated salt length")
+	HashPasswordCmd.Flags().IntP("memory", "m", schema.DefaultPasswordConfiguration.Memory, "[argon2id] set the amount of memory param (in MB)")
+	HashPasswordCmd.Flags().IntP("parallelism", "p", schema.DefaultPasswordConfiguration.Parallelism, "[argon2id] set the parallelism param")
+	HashPasswordCmd.Flags().IntP("key-length", "k", schema.DefaultPasswordConfiguration.KeyLength, "[argon2id] set the key length param")
+	HashPasswordCmd.Flags().IntP("salt-length", "l", schema.DefaultPasswordConfiguration.SaltLength, "set the auto-generated salt length")
 }
 
 var HashPasswordCmd = &cobra.Command{
@@ -36,8 +36,8 @@ var HashPasswordCmd = &cobra.Command{
 		var algorithm string
 
 		if sha512 {
-			if iterations == schema.DefaultPasswordOptionsConfiguration.Iterations {
-				iterations = schema.DefaultPasswordOptionsSHA512Configuration.Iterations
+			if iterations == schema.DefaultPasswordConfiguration.Iterations {
+				iterations = schema.DefaultPasswordSHA512Configuration.Iterations
 			}
 			algorithm = authentication.HashingAlgorithmSHA512
 		} else {
diff --git a/internal/configuration/schema/authentication.go b/internal/configuration/schema/authentication.go
index 65e39d34c..b8b93afae 100644
--- a/internal/configuration/schema/authentication.go
+++ b/internal/configuration/schema/authentication.go
@@ -18,11 +18,11 @@ type LDAPAuthenticationBackendConfiguration struct {
 
 // FileAuthenticationBackendConfiguration represents the configuration related to file-based backend
 type FileAuthenticationBackendConfiguration struct {
-	Path            string                        `mapstructure:"path"`
-	PasswordHashing *PasswordHashingConfiguration `mapstructure:"password"`
+	Path     string                 `mapstructure:"path"`
+	Password *PasswordConfiguration `mapstructure:"password"`
 }
 
-type PasswordHashingConfiguration struct {
+type PasswordConfiguration struct {
 	Iterations  int    `mapstructure:"iterations"`
 	KeyLength   int    `mapstructure:"key_length"`
 	SaltLength  int    `mapstructure:"salt_length"`
@@ -31,8 +31,8 @@ type PasswordHashingConfiguration struct {
 	Parallelism int    `mapstructure:"parallelism"`
 }
 
-// DefaultPasswordOptionsConfiguration represents the default configuration related to Argon2id hashing
-var DefaultPasswordOptionsConfiguration = PasswordHashingConfiguration{
+// DefaultPasswordConfiguration represents the default configuration related to Argon2id hashing
+var DefaultPasswordConfiguration = PasswordConfiguration{
 	Iterations:  1,
 	KeyLength:   32,
 	SaltLength:  16,
@@ -41,8 +41,8 @@ var DefaultPasswordOptionsConfiguration = PasswordHashingConfiguration{
 	Parallelism: 8,
 }
 
-// DefaultCIPasswordOptionsConfiguration represents the default configuration related to Argon2id hashing for CI
-var DefaultCIPasswordOptionsConfiguration = PasswordHashingConfiguration{
+// DefaultCIPasswordConfiguration represents the default configuration related to Argon2id hashing for CI
+var DefaultCIPasswordConfiguration = PasswordConfiguration{
 	Iterations:  1,
 	KeyLength:   32,
 	SaltLength:  16,
@@ -51,8 +51,8 @@ var DefaultCIPasswordOptionsConfiguration = PasswordHashingConfiguration{
 	Parallelism: 8,
 }
 
-// DefaultPasswordOptionsSHA512Configuration represents the default configuration related to SHA512 hashing
-var DefaultPasswordOptionsSHA512Configuration = PasswordHashingConfiguration{
+// DefaultPasswordSHA512Configuration represents the default configuration related to SHA512 hashing
+var DefaultPasswordSHA512Configuration = PasswordConfiguration{
 	Iterations: 50000,
 	SaltLength: 16,
 	Algorithm:  "sha512",
diff --git a/internal/configuration/validator/authentication.go b/internal/configuration/validator/authentication.go
index d3f35d11c..33d73145c 100644
--- a/internal/configuration/validator/authentication.go
+++ b/internal/configuration/validator/authentication.go
@@ -15,58 +15,58 @@ func validateFileAuthenticationBackend(configuration *schema.FileAuthenticationB
 		validator.Push(errors.New("Please provide a `path` for the users database in `authentication_backend`"))
 	}
 
-	if configuration.PasswordHashing == nil {
-		configuration.PasswordHashing = &schema.DefaultPasswordOptionsConfiguration
+	if configuration.Password == nil {
+		configuration.Password = &schema.DefaultPasswordConfiguration
 	} else {
-		if configuration.PasswordHashing.Algorithm == "" {
-			configuration.PasswordHashing.Algorithm = schema.DefaultPasswordOptionsConfiguration.Algorithm
+		if configuration.Password.Algorithm == "" {
+			configuration.Password.Algorithm = schema.DefaultPasswordConfiguration.Algorithm
 		} else {
-			configuration.PasswordHashing.Algorithm = strings.ToLower(configuration.PasswordHashing.Algorithm)
-			if configuration.PasswordHashing.Algorithm != "argon2id" && configuration.PasswordHashing.Algorithm != "sha512" {
-				validator.Push(fmt.Errorf("Unknown hashing algorithm supplied, valid values are argon2id and sha512, you configured '%s'", configuration.PasswordHashing.Algorithm))
+			configuration.Password.Algorithm = strings.ToLower(configuration.Password.Algorithm)
+			if configuration.Password.Algorithm != "argon2id" && configuration.Password.Algorithm != "sha512" {
+				validator.Push(fmt.Errorf("Unknown hashing algorithm supplied, valid values are argon2id and sha512, you configured '%s'", configuration.Password.Algorithm))
 			}
 		}
 
 		// Iterations (time)
-		if configuration.PasswordHashing.Iterations == 0 {
-			if configuration.PasswordHashing.Algorithm == "argon2id" {
-				configuration.PasswordHashing.Iterations = schema.DefaultPasswordOptionsConfiguration.Iterations
+		if configuration.Password.Iterations == 0 {
+			if configuration.Password.Algorithm == "argon2id" {
+				configuration.Password.Iterations = schema.DefaultPasswordConfiguration.Iterations
 			} else {
-				configuration.PasswordHashing.Iterations = schema.DefaultPasswordOptionsSHA512Configuration.Iterations
+				configuration.Password.Iterations = schema.DefaultPasswordSHA512Configuration.Iterations
 			}
-		} else if configuration.PasswordHashing.Iterations < 1 {
-			validator.Push(fmt.Errorf("The number of iterations specified is invalid, must be 1 or more, you configured %d", configuration.PasswordHashing.Iterations))
+		} else if configuration.Password.Iterations < 1 {
+			validator.Push(fmt.Errorf("The number of iterations specified is invalid, must be 1 or more, you configured %d", configuration.Password.Iterations))
 		}
 
 		//Salt Length
-		if configuration.PasswordHashing.SaltLength == 0 {
-			configuration.PasswordHashing.SaltLength = schema.DefaultPasswordOptionsConfiguration.SaltLength
-		} else if configuration.PasswordHashing.SaltLength < 2 {
-			validator.Push(fmt.Errorf("The salt length must be 2 or more, you configured %d", configuration.PasswordHashing.SaltLength))
-		} else if configuration.PasswordHashing.SaltLength > 16 {
-			validator.Push(fmt.Errorf("The salt length must be 16 or less, you configured %d", configuration.PasswordHashing.SaltLength))
+		if configuration.Password.SaltLength == 0 {
+			configuration.Password.SaltLength = schema.DefaultPasswordConfiguration.SaltLength
+		} else if configuration.Password.SaltLength < 2 {
+			validator.Push(fmt.Errorf("The salt length must be 2 or more, you configured %d", configuration.Password.SaltLength))
+		} else if configuration.Password.SaltLength > 16 {
+			validator.Push(fmt.Errorf("The salt length must be 16 or less, you configured %d", configuration.Password.SaltLength))
 		}
 
-		if configuration.PasswordHashing.Algorithm == "argon2id" {
+		if configuration.Password.Algorithm == "argon2id" {
 			// Parallelism
-			if configuration.PasswordHashing.Parallelism == 0 {
-				configuration.PasswordHashing.Parallelism = schema.DefaultPasswordOptionsConfiguration.Parallelism
-			} else if configuration.PasswordHashing.Parallelism < 1 {
-				validator.Push(fmt.Errorf("Parallelism for argon2id must be 1 or more, you configured %d", configuration.PasswordHashing.Parallelism))
+			if configuration.Password.Parallelism == 0 {
+				configuration.Password.Parallelism = schema.DefaultPasswordConfiguration.Parallelism
+			} else if configuration.Password.Parallelism < 1 {
+				validator.Push(fmt.Errorf("Parallelism for argon2id must be 1 or more, you configured %d", configuration.Password.Parallelism))
 			}
 
 			// Memory
-			if configuration.PasswordHashing.Memory == 0 {
-				configuration.PasswordHashing.Memory = schema.DefaultPasswordOptionsConfiguration.Memory
-			} else if configuration.PasswordHashing.Memory < configuration.PasswordHashing.Parallelism*8 {
-				validator.Push(fmt.Errorf("Memory for argon2id must be %d or more (parallelism * 8), you configured memory as %d and parallelism as %d", configuration.PasswordHashing.Parallelism*8, configuration.PasswordHashing.Memory, configuration.PasswordHashing.Parallelism))
+			if configuration.Password.Memory == 0 {
+				configuration.Password.Memory = schema.DefaultPasswordConfiguration.Memory
+			} else if configuration.Password.Memory < configuration.Password.Parallelism*8 {
+				validator.Push(fmt.Errorf("Memory for argon2id must be %d or more (parallelism * 8), you configured memory as %d and parallelism as %d", configuration.Password.Parallelism*8, configuration.Password.Memory, configuration.Password.Parallelism))
 			}
 
 			// Key Length
-			if configuration.PasswordHashing.KeyLength == 0 {
-				configuration.PasswordHashing.KeyLength = schema.DefaultPasswordOptionsConfiguration.KeyLength
-			} else if configuration.PasswordHashing.KeyLength < 16 {
-				validator.Push(fmt.Errorf("Key length for argon2id must be 16, you configured %d", configuration.PasswordHashing.KeyLength))
+			if configuration.Password.KeyLength == 0 {
+				configuration.Password.KeyLength = schema.DefaultPasswordConfiguration.KeyLength
+			} else if configuration.Password.KeyLength < 16 {
+				validator.Push(fmt.Errorf("Key length for argon2id must be 16, you configured %d", configuration.Password.KeyLength))
 			}
 		}
 	}
diff --git a/internal/handlers/const.go b/internal/handlers/const.go
index b2afb2855..53c720a90 100644
--- a/internal/handlers/const.go
+++ b/internal/handlers/const.go
@@ -29,7 +29,7 @@ const (
 const operationFailedMessage = "Operation failed."
 const authenticationFailedMessage = "Authentication failed. Check your credentials."
 const userBannedMessage = "Please retry in a few minutes."
-const unableToRegisterOneTimePasswordMessage = "Unable to set up one-time passwords."
+const unableToRegisterOneTimePasswordMessage = "Unable to set up one-time passwords." //nolint:gosec
 const unableToRegisterSecurityKeyMessage = "Unable to register your security key."
 const unableToResetPasswordMessage = "Unable to reset your password."
 const mfaValidationFailedMessage = "Authentication failed, please retry later."


Test patch:
diff --git a/internal/authentication/file_user_provider_test.go b/internal/authentication/file_user_provider_test.go
index b55196b19..c60f3ee18 100644
--- a/internal/authentication/file_user_provider_test.go
+++ b/internal/authentication/file_user_provider_test.go
@@ -131,8 +131,8 @@ func TestShouldUpdatePasswordHashingAlgorithmToSHA512(t *testing.T) {
 	WithDatabase(UserDatabaseContent, func(path string) {
 		config := DefaultFileAuthenticationBackendConfiguration
 		config.Path = path
-		config.PasswordHashing.Algorithm = "sha512"
-		config.PasswordHashing.Iterations = 50000
+		config.Password.Algorithm = "sha512"
+		config.Password.Iterations = 50000
 
 		provider := NewFileUserProvider(&config)
 		assert.True(t, strings.HasPrefix(provider.database.Users["john"].HashedPassword, "{CRYPT}$argon2id$"))
@@ -223,13 +223,13 @@ func TestShouldSupportHashPasswordWithoutCRYPT(t *testing.T) {
 var (
 	DefaultFileAuthenticationBackendConfiguration = schema.FileAuthenticationBackendConfiguration{
 		Path: "",
-		PasswordHashing: &schema.PasswordHashingConfiguration{
-			Iterations:  schema.DefaultCIPasswordOptionsConfiguration.Iterations,
-			KeyLength:   schema.DefaultCIPasswordOptionsConfiguration.KeyLength,
-			SaltLength:  schema.DefaultCIPasswordOptionsConfiguration.SaltLength,
-			Algorithm:   schema.DefaultCIPasswordOptionsConfiguration.Algorithm,
-			Memory:      schema.DefaultCIPasswordOptionsConfiguration.Memory,
-			Parallelism: schema.DefaultCIPasswordOptionsConfiguration.Parallelism,
+		Password: &schema.PasswordConfiguration{
+			Iterations:  schema.DefaultCIPasswordConfiguration.Iterations,
+			KeyLength:   schema.DefaultCIPasswordConfiguration.KeyLength,
+			SaltLength:  schema.DefaultCIPasswordConfiguration.SaltLength,
+			Algorithm:   schema.DefaultCIPasswordConfiguration.Algorithm,
+			Memory:      schema.DefaultCIPasswordConfiguration.Memory,
+			Parallelism: schema.DefaultCIPasswordConfiguration.Parallelism,
 		},
 	}
 )
diff --git a/internal/authentication/password_hash_test.go b/internal/authentication/password_hash_test.go
index 39b2e5522..5220c0d2b 100644
--- a/internal/authentication/password_hash_test.go
+++ b/internal/authentication/password_hash_test.go
@@ -22,14 +22,14 @@ func TestShouldHashSHA512Password(t *testing.T) {
 	assert.Equal(t, "6", code)
 	assert.Equal(t, "aFr56HjK3DrB8t3S", salt)
 	assert.Equal(t, "zhPQiS85cgBlNhUKKE6n/AHMlpqrvYSnSL3fEVkK0yHFQ.oFFAd8D4OhPAy18K5U61Z2eBhxQXExGU/eknXlY1", hash)
-	assert.Equal(t, schema.DefaultPasswordOptionsSHA512Configuration.Iterations, parameters.GetInt("rounds", HashingDefaultSHA512Iterations))
+	assert.Equal(t, schema.DefaultPasswordSHA512Configuration.Iterations, parameters.GetInt("rounds", HashingDefaultSHA512Iterations))
 }
 
 func TestShouldHashArgon2idPassword(t *testing.T) {
 	hash, err := HashPassword("password", "BpLnfgDsc2WD8F2q", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, schema.DefaultCIPasswordOptionsConfiguration.KeyLength,
-		schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, schema.DefaultCIPasswordConfiguration.KeyLength,
+		schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.NoError(t, err)
 
@@ -39,10 +39,10 @@ func TestShouldHashArgon2idPassword(t *testing.T) {
 	assert.Equal(t, "argon2id", code)
 	assert.Equal(t, "BpLnfgDsc2WD8F2q", salt)
 	assert.Equal(t, "O126GHPeZ5fwj7OLSs7PndXsTbje76R+QW9/EGfhkJg", key)
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.Iterations, parameters.GetInt("t", HashingDefaultArgon2idTime))
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024, parameters.GetInt("m", HashingDefaultArgon2idMemory))
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.Parallelism, parameters.GetInt("p", HashingDefaultArgon2idParallelism))
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.KeyLength, parameters.GetInt("k", HashingDefaultArgon2idKeyLength))
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.Iterations, parameters.GetInt("t", HashingDefaultArgon2idTime))
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.Memory*1024, parameters.GetInt("m", HashingDefaultArgon2idMemory))
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.Parallelism, parameters.GetInt("p", HashingDefaultArgon2idParallelism))
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.KeyLength, parameters.GetInt("k", HashingDefaultArgon2idKeyLength))
 }
 
 // This checks the method of hashing (for argon2id) supports all the characters we allow in Authelia's hash function
@@ -73,9 +73,9 @@ func TestSHA512HashSaltValidValues(t *testing.T) {
 
 func TestShouldNotHashPasswordWithNonExistentAlgorithm(t *testing.T) {
 	hash, err := HashPassword("password", "BpLnfgDsc2WD8F2q", "bogus",
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, schema.DefaultCIPasswordOptionsConfiguration.KeyLength,
-		schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, schema.DefaultCIPasswordConfiguration.KeyLength,
+		schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Hashing algorithm input of 'bogus' is invalid, only values of argon2id and 6 are supported")
@@ -83,8 +83,8 @@ func TestShouldNotHashPasswordWithNonExistentAlgorithm(t *testing.T) {
 
 func TestShouldNotHashArgon2idPasswordDueToMemoryParallelismMismatch(t *testing.T) {
 	hash, err := HashPassword("password", "BpLnfgDsc2WD8F2q", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, 8, 2,
-		schema.DefaultCIPasswordOptionsConfiguration.KeyLength, schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, 8, 2,
+		schema.DefaultCIPasswordConfiguration.KeyLength, schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Memory (argon2id) input of 8 is invalid with a parallelism input of 2, it must be 16 (parallelism * 8) or higher")
@@ -92,8 +92,8 @@ func TestShouldNotHashArgon2idPasswordDueToMemoryParallelismMismatch(t *testing.
 
 func TestShouldNotHashArgon2idPasswordDueToMemoryLessThanEight(t *testing.T) {
 	hash, err := HashPassword("password", "BpLnfgDsc2WD8F2q", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, 1, schema.DefaultCIPasswordOptionsConfiguration.Parallelism,
-		schema.DefaultCIPasswordOptionsConfiguration.KeyLength, schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, 1, schema.DefaultCIPasswordConfiguration.Parallelism,
+		schema.DefaultCIPasswordConfiguration.KeyLength, schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Memory (argon2id) input of 1 is invalid, it must be 8 or higher")
@@ -101,8 +101,8 @@ func TestShouldNotHashArgon2idPasswordDueToMemoryLessThanEight(t *testing.T) {
 
 func TestShouldNotHashArgon2idPasswordDueToKeyLengthLessThanSixteen(t *testing.T) {
 	hash, err := HashPassword("password", "BpLnfgDsc2WD8F2q", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, 5, schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, 5, schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Key length (argon2id) input of 5 is invalid, it must be 16 or higher")
@@ -110,8 +110,8 @@ func TestShouldNotHashArgon2idPasswordDueToKeyLengthLessThanSixteen(t *testing.T
 
 func TestShouldNotHashArgon2idPasswordDueParallelismLessThanOne(t *testing.T) {
 	hash, err := HashPassword("password", "BpLnfgDsc2WD8F2q", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024, -1,
-		schema.DefaultCIPasswordOptionsConfiguration.KeyLength, schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024, -1,
+		schema.DefaultCIPasswordConfiguration.KeyLength, schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Parallelism (argon2id) input of -1 is invalid, it must be 1 or higher")
@@ -119,8 +119,8 @@ func TestShouldNotHashArgon2idPasswordDueParallelismLessThanOne(t *testing.T) {
 
 func TestShouldNotHashArgon2idPasswordDueIterationsLessThanOne(t *testing.T) {
 	hash, err := HashPassword("password", "BpLnfgDsc2WD8F2q", HashingAlgorithmArgon2id,
-		0, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024, schema.DefaultCIPasswordOptionsConfiguration.Parallelism,
-		schema.DefaultCIPasswordOptionsConfiguration.KeyLength, schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		0, schema.DefaultCIPasswordConfiguration.Memory*1024, schema.DefaultCIPasswordConfiguration.Parallelism,
+		schema.DefaultCIPasswordConfiguration.KeyLength, schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Iterations (argon2id) input of 0 is invalid, it must be 1 or more")
@@ -128,15 +128,15 @@ func TestShouldNotHashArgon2idPasswordDueIterationsLessThanOne(t *testing.T) {
 
 func TestShouldNotHashPasswordDueToSaltLength(t *testing.T) {
 	hash, err := HashPassword("password", "", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, schema.DefaultCIPasswordOptionsConfiguration.KeyLength, 0)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, schema.DefaultCIPasswordConfiguration.KeyLength, 0)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Salt length input of 0 is invalid, it must be 2 or higher")
 
 	hash, err = HashPassword("password", "", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, schema.DefaultCIPasswordOptionsConfiguration.KeyLength, 20)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, schema.DefaultCIPasswordConfiguration.KeyLength, 20)
 
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Salt length input of 20 is invalid, it must be 16 or lower")
@@ -144,27 +144,27 @@ func TestShouldNotHashPasswordDueToSaltLength(t *testing.T) {
 
 func TestShouldNotHashPasswordDueToSaltCharLengthTooLong(t *testing.T) {
 	hash, err := HashPassword("password", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, schema.DefaultCIPasswordOptionsConfiguration.KeyLength,
-		schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, schema.DefaultCIPasswordConfiguration.KeyLength,
+		schema.DefaultCIPasswordConfiguration.SaltLength)
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Salt input of abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 is invalid (62 characters), it must be 16 or fewer characters")
 }
 
 func TestShouldNotHashPasswordDueToSaltCharLengthTooShort(t *testing.T) {
 	hash, err := HashPassword("password", "a", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, schema.DefaultCIPasswordOptionsConfiguration.KeyLength,
-		schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, schema.DefaultCIPasswordConfiguration.KeyLength,
+		schema.DefaultCIPasswordConfiguration.SaltLength)
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Salt input of a is invalid (1 characters), it must be 2 or more characters")
 }
 
 func TestShouldNotHashPasswordWithNonBase64CharsInSalt(t *testing.T) {
 	hash, err := HashPassword("password", "abc&123", HashingAlgorithmArgon2id,
-		schema.DefaultCIPasswordOptionsConfiguration.Iterations, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024,
-		schema.DefaultCIPasswordOptionsConfiguration.Parallelism, schema.DefaultCIPasswordOptionsConfiguration.KeyLength,
-		schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+		schema.DefaultCIPasswordConfiguration.Iterations, schema.DefaultCIPasswordConfiguration.Memory*1024,
+		schema.DefaultCIPasswordConfiguration.Parallelism, schema.DefaultCIPasswordConfiguration.KeyLength,
+		schema.DefaultCIPasswordConfiguration.SaltLength)
 	assert.Equal(t, "", hash)
 	assert.EqualError(t, err, "Salt input of abc&123 is invalid, only characters [a-zA-Z0-9+/] are valid for input")
 }
@@ -223,10 +223,10 @@ func TestShouldNotParseArgon2idHashWithWrongKeyLength(t *testing.T) {
 func TestShouldParseArgon2idHash(t *testing.T) {
 	passwordHash, err := ParseHash("$argon2id$v=19$m=131072,t=1,p=8$BpLnfgDsc2WD8F2q$G4fD5nJwXHDMS+u0eEMKvU0LF23jxbSmJSxhSLTteHE")
 	assert.NoError(t, err)
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.Iterations, passwordHash.Iterations)
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.Parallelism, passwordHash.Parallelism)
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.KeyLength, passwordHash.KeyLength)
-	assert.Equal(t, schema.DefaultCIPasswordOptionsConfiguration.Memory*1024, passwordHash.Memory)
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.Iterations, passwordHash.Iterations)
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.Parallelism, passwordHash.Parallelism)
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.KeyLength, passwordHash.KeyLength)
+	assert.Equal(t, schema.DefaultCIPasswordConfiguration.Memory*1024, passwordHash.Memory)
 }
 
 func TestShouldCheckSHA512Password(t *testing.T) {
@@ -300,9 +300,9 @@ func TestNumberOfRoundsNotInt(t *testing.T) {
 
 func TestShouldCheckPasswordArgon2idHashedWithAuthelia(t *testing.T) {
 	password := "my;secure*password"
-	hash, err := HashPassword(password, "", HashingAlgorithmArgon2id, schema.DefaultCIPasswordOptionsConfiguration.Iterations,
-		schema.DefaultCIPasswordOptionsConfiguration.Memory*1024, schema.DefaultCIPasswordOptionsConfiguration.Parallelism,
-		schema.DefaultCIPasswordOptionsConfiguration.KeyLength, schema.DefaultCIPasswordOptionsConfiguration.SaltLength)
+	hash, err := HashPassword(password, "", HashingAlgorithmArgon2id, schema.DefaultCIPasswordConfiguration.Iterations,
+		schema.DefaultCIPasswordConfiguration.Memory*1024, schema.DefaultCIPasswordConfiguration.Parallelism,
+		schema.DefaultCIPasswordConfiguration.KeyLength, schema.DefaultCIPasswordConfiguration.SaltLength)
 
 	assert.NoError(t, err)
 
@@ -314,8 +314,8 @@ func TestShouldCheckPasswordArgon2idHashedWithAuthelia(t *testing.T) {
 
 func TestShouldCheckPasswordSHA512HashedWithAuthelia(t *testing.T) {
 	password := "my;secure*password"
-	hash, err := HashPassword(password, "", HashingAlgorithmSHA512, schema.DefaultPasswordOptionsSHA512Configuration.Iterations,
-		0, 0, 0, schema.DefaultPasswordOptionsSHA512Configuration.SaltLength)
+	hash, err := HashPassword(password, "", HashingAlgorithmSHA512, schema.DefaultPasswordSHA512Configuration.Iterations,
+		0, 0, 0, schema.DefaultPasswordSHA512Configuration.SaltLength)
 
 	assert.NoError(t, err)
 
diff --git a/internal/configuration/validator/authentication_test.go b/internal/configuration/validator/authentication_test.go
index e5bbd154f..3181bb955 100644
--- a/internal/configuration/validator/authentication_test.go
+++ b/internal/configuration/validator/authentication_test.go
@@ -29,15 +29,15 @@ type FileBasedAuthenticationBackend struct {
 func (suite *FileBasedAuthenticationBackend) SetupTest() {
 	suite.validator = schema.NewStructValidator()
 	suite.configuration = schema.AuthenticationBackendConfiguration{}
-	suite.configuration.File = &schema.FileAuthenticationBackendConfiguration{Path: "/a/path", PasswordHashing: &schema.PasswordHashingConfiguration{
-		Algorithm:   schema.DefaultPasswordOptionsConfiguration.Algorithm,
-		Iterations:  schema.DefaultPasswordOptionsConfiguration.Iterations,
-		Parallelism: schema.DefaultPasswordOptionsConfiguration.Parallelism,
-		Memory:      schema.DefaultPasswordOptionsConfiguration.Memory,
-		KeyLength:   schema.DefaultPasswordOptionsConfiguration.KeyLength,
-		SaltLength:  schema.DefaultPasswordOptionsConfiguration.SaltLength,
+	suite.configuration.File = &schema.FileAuthenticationBackendConfiguration{Path: "/a/path", Password: &schema.PasswordConfiguration{
+		Algorithm:   schema.DefaultPasswordConfiguration.Algorithm,
+		Iterations:  schema.DefaultPasswordConfiguration.Iterations,
+		Parallelism: schema.DefaultPasswordConfiguration.Parallelism,
+		Memory:      schema.DefaultPasswordConfiguration.Memory,
+		KeyLength:   schema.DefaultPasswordConfiguration.KeyLength,
+		SaltLength:  schema.DefaultPasswordConfiguration.SaltLength,
 	}}
-	suite.configuration.File.PasswordHashing.Algorithm = schema.DefaultPasswordOptionsConfiguration.Algorithm
+	suite.configuration.File.Password.Algorithm = schema.DefaultPasswordConfiguration.Algorithm
 }
 func (suite *FileBasedAuthenticationBackend) TestShouldValidateCompleteConfiguration() {
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
@@ -52,104 +52,104 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenNoPathProvi
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenMemoryNotMoreThanEightTimesParallelism() {
-	suite.configuration.File.PasswordHashing.Memory = 8
-	suite.configuration.File.PasswordHashing.Parallelism = 2
+	suite.configuration.File.Password.Memory = 8
+	suite.configuration.File.Password.Parallelism = 2
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 1)
 	assert.EqualError(suite.T(), suite.validator.Errors()[0], "Memory for argon2id must be 16 or more (parallelism * 8), you configured memory as 8 and parallelism as 2")
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultConfigurationWhenBlank() {
-	suite.configuration.File.PasswordHashing = &schema.PasswordHashingConfiguration{}
+	suite.configuration.File.Password = &schema.PasswordConfiguration{}
 
-	assert.Equal(suite.T(), 0, suite.configuration.File.PasswordHashing.KeyLength)
-	assert.Equal(suite.T(), 0, suite.configuration.File.PasswordHashing.Iterations)
-	assert.Equal(suite.T(), 0, suite.configuration.File.PasswordHashing.SaltLength)
-	assert.Equal(suite.T(), "", suite.configuration.File.PasswordHashing.Algorithm)
-	assert.Equal(suite.T(), 0, suite.configuration.File.PasswordHashing.Memory)
-	assert.Equal(suite.T(), 0, suite.configuration.File.PasswordHashing.Parallelism)
+	assert.Equal(suite.T(), 0, suite.configuration.File.Password.KeyLength)
+	assert.Equal(suite.T(), 0, suite.configuration.File.Password.Iterations)
+	assert.Equal(suite.T(), 0, suite.configuration.File.Password.SaltLength)
+	assert.Equal(suite.T(), "", suite.configuration.File.Password.Algorithm)
+	assert.Equal(suite.T(), 0, suite.configuration.File.Password.Memory)
+	assert.Equal(suite.T(), 0, suite.configuration.File.Password.Parallelism)
 
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 
 	assert.Len(suite.T(), suite.validator.Errors(), 0)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.KeyLength, suite.configuration.File.PasswordHashing.KeyLength)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Iterations, suite.configuration.File.PasswordHashing.Iterations)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.SaltLength, suite.configuration.File.PasswordHashing.SaltLength)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Algorithm, suite.configuration.File.PasswordHashing.Algorithm)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Memory, suite.configuration.File.PasswordHashing.Memory)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Parallelism, suite.configuration.File.PasswordHashing.Parallelism)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.KeyLength, suite.configuration.File.Password.KeyLength)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Iterations, suite.configuration.File.Password.Iterations)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.SaltLength, suite.configuration.File.Password.SaltLength)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Algorithm, suite.configuration.File.Password.Algorithm)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Memory, suite.configuration.File.Password.Memory)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Parallelism, suite.configuration.File.Password.Parallelism)
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultConfigurationWhenOnlySHA512Set() {
-	suite.configuration.File.PasswordHashing = &schema.PasswordHashingConfiguration{}
-	assert.Equal(suite.T(), "", suite.configuration.File.PasswordHashing.Algorithm)
-	suite.configuration.File.PasswordHashing.Algorithm = "sha512"
+	suite.configuration.File.Password = &schema.PasswordConfiguration{}
+	assert.Equal(suite.T(), "", suite.configuration.File.Password.Algorithm)
+	suite.configuration.File.Password.Algorithm = "sha512"
 
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 
 	assert.Len(suite.T(), suite.validator.Errors(), 0)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsSHA512Configuration.KeyLength, suite.configuration.File.PasswordHashing.KeyLength)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsSHA512Configuration.Iterations, suite.configuration.File.PasswordHashing.Iterations)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsSHA512Configuration.SaltLength, suite.configuration.File.PasswordHashing.SaltLength)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsSHA512Configuration.Algorithm, suite.configuration.File.PasswordHashing.Algorithm)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsSHA512Configuration.Memory, suite.configuration.File.PasswordHashing.Memory)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsSHA512Configuration.Parallelism, suite.configuration.File.PasswordHashing.Parallelism)
+	assert.Equal(suite.T(), schema.DefaultPasswordSHA512Configuration.KeyLength, suite.configuration.File.Password.KeyLength)
+	assert.Equal(suite.T(), schema.DefaultPasswordSHA512Configuration.Iterations, suite.configuration.File.Password.Iterations)
+	assert.Equal(suite.T(), schema.DefaultPasswordSHA512Configuration.SaltLength, suite.configuration.File.Password.SaltLength)
+	assert.Equal(suite.T(), schema.DefaultPasswordSHA512Configuration.Algorithm, suite.configuration.File.Password.Algorithm)
+	assert.Equal(suite.T(), schema.DefaultPasswordSHA512Configuration.Memory, suite.configuration.File.Password.Memory)
+	assert.Equal(suite.T(), schema.DefaultPasswordSHA512Configuration.Parallelism, suite.configuration.File.Password.Parallelism)
 }
 func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenKeyLengthTooLow() {
-	suite.configuration.File.PasswordHashing.KeyLength = 1
+	suite.configuration.File.Password.KeyLength = 1
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 1)
 	assert.EqualError(suite.T(), suite.validator.Errors()[0], "Key length for argon2id must be 16, you configured 1")
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenSaltLengthTooLow() {
-	suite.configuration.File.PasswordHashing.SaltLength = -1
+	suite.configuration.File.Password.SaltLength = -1
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 1)
 	assert.EqualError(suite.T(), suite.validator.Errors()[0], "The salt length must be 2 or more, you configured -1")
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenSaltLengthTooHigh() {
-	suite.configuration.File.PasswordHashing.SaltLength = 20
+	suite.configuration.File.Password.SaltLength = 20
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 1)
 	assert.EqualError(suite.T(), suite.validator.Errors()[0], "The salt length must be 16 or less, you configured 20")
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenBadAlgorithmDefined() {
-	suite.configuration.File.PasswordHashing.Algorithm = "bogus"
+	suite.configuration.File.Password.Algorithm = "bogus"
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 1)
 	assert.EqualError(suite.T(), suite.validator.Errors()[0], "Unknown hashing algorithm supplied, valid values are argon2id and sha512, you configured 'bogus'")
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenIterationsTooLow() {
-	suite.configuration.File.PasswordHashing.Iterations = -1
+	suite.configuration.File.Password.Iterations = -1
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 1)
 	assert.EqualError(suite.T(), suite.validator.Errors()[0], "The number of iterations specified is invalid, must be 1 or more, you configured -1")
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenParallelismTooLow() {
-	suite.configuration.File.PasswordHashing.Parallelism = -1
+	suite.configuration.File.Password.Parallelism = -1
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 1)
 	assert.EqualError(suite.T(), suite.validator.Errors()[0], "Parallelism for argon2id must be 1 or more, you configured -1")
 }
 
 func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultValues() {
-	suite.configuration.File.PasswordHashing.Algorithm = ""
-	suite.configuration.File.PasswordHashing.Iterations = 0
-	suite.configuration.File.PasswordHashing.SaltLength = 0
-	suite.configuration.File.PasswordHashing.Memory = 0
-	suite.configuration.File.PasswordHashing.Parallelism = 0
+	suite.configuration.File.Password.Algorithm = ""
+	suite.configuration.File.Password.Iterations = 0
+	suite.configuration.File.Password.SaltLength = 0
+	suite.configuration.File.Password.Memory = 0
+	suite.configuration.File.Password.Parallelism = 0
 	ValidateAuthenticationBackend(&suite.configuration, suite.validator)
 	assert.Len(suite.T(), suite.validator.Errors(), 0)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Algorithm, suite.configuration.File.PasswordHashing.Algorithm)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Iterations, suite.configuration.File.PasswordHashing.Iterations)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.SaltLength, suite.configuration.File.PasswordHashing.SaltLength)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Memory, suite.configuration.File.PasswordHashing.Memory)
-	assert.Equal(suite.T(), schema.DefaultPasswordOptionsConfiguration.Parallelism, suite.configuration.File.PasswordHashing.Parallelism)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Algorithm, suite.configuration.File.Password.Algorithm)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Iterations, suite.configuration.File.Password.Iterations)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.SaltLength, suite.configuration.File.Password.SaltLength)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Memory, suite.configuration.File.Password.Memory)
+	assert.Equal(suite.T(), schema.DefaultPasswordConfiguration.Parallelism, suite.configuration.File.Password.Parallelism)
 }
 
 func TestFileBasedAuthenticationBackend(t *testing.T) {