Credentials
A credential is proof of identity. A user can hold several at once, which is what makes multi-factor authentication possible.
Credential types
Password
Passwords are hashed with Argon2, a memory-hard algorithm chosen because it makes GPU-accelerated brute forcing expensive.
Stored data:
hash_iterations. Argon2 iteration countalgorithm. Hashing algorithm identifiersalt. Unique random salt per credential
Passwords are never stored in plaintext and cannot be retrieved, only verified.
TOTP
A shared secret paired with an authenticator app such as Google Authenticator, Authy, or 1Password. The credential records the hash function (SHA-1, SHA-256, or SHA-512), the code length, usually 6 digits, the time step, usually 30 seconds, and the issuer name the app displays.
TOTP credentials are managed by the Trident module.
WebAuthn passkeys
Hardware security keys and platform authenticators: Touch ID, Windows Hello, Android biometrics. FerrisKey stores the public key and the credential metadata. The private key never leaves the user’s device.
Recovery codes
Backup codes generated when MFA is set up. Each one works exactly once in place of the normal MFA challenge, and they are hashed before storage like any other secret.
Federated
Credentials linked to an external identity provider (Google, GitHub, etc.) through the Abyss module. Stored data includes:
provider_id. External provider identifierprovider_type. Provider type (OAuth2, OIDC)
Temporary credentials
A credential can be flagged temporary. That is almost always a password, and it triggers the update_password required action: the user has to set a permanent one before getting full access.
Credential lifecycle
A user typically ends up with a password, a TOTP credential once MFA is set up, the set of recovery codes generated alongside it, and possibly one or more WebAuthn passkeys.
Each can be added, replaced, or removed on its own, either from the admin console or through the user’s self-service endpoints.