From 2a3c00ce700fafbb44dda0c9994a454a62841edd Mon Sep 17 00:00:00 2001 From: vcwai Date: Mon, 12 Apr 2021 09:02:40 +0800 Subject: [PATCH] Create design for mfa_backup_code.rst (#402) --- designs/mfa_backup_code.rst | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 designs/mfa_backup_code.rst diff --git a/designs/mfa_backup_code.rst b/designs/mfa_backup_code.rst new file mode 100644 index 000000000..5a8243ed7 --- /dev/null +++ b/designs/mfa_backup_code.rst @@ -0,0 +1,63 @@ + +Account recovery (backup) mfa codes draft design +------------------------ +MFA requires users to have access to a working physical device, however that might not be always possible. + +Backup mfa code allows: + +- single-device accounts to be restored +- initial setup for passwordless-login + +Overview +------------------------ + +If the user has a Backup code, then they can replace the TOTP/WebAuthn challenge with it during login. For example, TOTP + password auth will be Backup code + password instead. + +To implement this, we can add Backup code as a new AuthCredential, so that it can be used in the auth process. + +To validate Backup code, we simply check if the input matches the Backup code saved in database, which should be hashed with salt (similar to how password is validated). + +The login session should only last for 5 mins with a Claim that allows users to change login credentials. + +Code Generation +------------------------ + +The Backup code could be generated by a cryptographically secure pseudorandom number generator. Attackers should not be able to guess it even if they know our source code. + +(See kanidmd/src/lib/utils.rs readable_password_from_random) + +Implementation +------------------------ + +Add a new class/object: Backup code + +A user can generate one batch of Backup codes at a time, which will be saved in the database in a non-reversible format (KDF) + - Each code in the batch can be used only once + - If the user generates a new batch of Backup codes, the last batch of codes become invalid. + +To invalidate the Backup code after usage, we should send an async message to the async task queue. Since the auth process is currently in a single transaction lock that is NOT writeable, using an async action allows the auth process to proceed in parallel and prevent opening nested transactions. **Note** that there is a small window between "use of the backup code" and the async action being processed to actually cause the invalidation, but this window is short enough that it's an acceptable compromise. + +To prevent attackers from bruteforcing these Backup code at a high rate, we need a rate limiting mechanism similar to what exists for passwords: + + * After 5 incorrect attempts the account is rate limited by an increasing time window within the API. This limit delays the response to the auth (regardless of success) + * After X attempts, the account is soft locked on the affected server only for a time window of Y increasing up to Z. + * If the attempts continue, the account is hard locked and signalled to an external system that this has occured. +(See designs/account_policy.rst#rate-limiting for details) + +Access Control +================ + +With the existing access profile infrastructure, we can decide which users/groups can self-admin the Backup code via a membership to a ``idm_account_mfa_backup_code_self_priv`` group. + +If users want to admin Backup codes for others, they have to be members of the ``idm_account_mfa_backup_code_manage_priv`` group. + +(See kanidmd/src/lib/constants/entries.rs for examples of existing groups for privileges) + + +Workflow +================ + +1. User can generate Backup code themselves if they are already authenticated (for later use) +2. User login with the Backup code when they have no access to TOTP/WebAuth token + +