Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions 021-multi-factor-authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Multi Factor Authentication

- Implementation Owner: @TorstenDittmann
- Start Date: 12-06-2023
- Target Date: 01-07-2023
- Appwrite Issue:
- [#2725](https://github.com/appwrite/appwrite/issues/2752)
- [#5240](https://github.com/appwrite/appwrite/issues/5240)

## Summary

[summary]: #summary

Single factor authentication poses a security risk to user accounts. If a user's password is compromised, their account can be easily accessed by an attacker. To mitigate this risk, I propose adding Multi Factor Authentication (MFA) to Appwrite's Accounts Service.

## Problem Statement (Step 1)

[problem-statement]: #problem-statement

**What problem are you trying to solve?**

Appwrite currently only supports single factor authentication. This presents a security risk as it leaves user accounts vulnerable to attacks such as password guessing and phishing. To address this, I propose implementing Multi Factor Authentication (MFA) in Appwrite's Accounts Service.

## Design proposal (Step 2)

[design-proposal]: #design-proposal

### Flow

Scenario: User **Walter** has 2FA on his account enabled.

- Walter attempts to create a session using his e-mail and password
- Appwrite identifies that he has MFA enabled
- Appwrite creates a challenge
- Appwrite returns an exception with the type `mfa_required`, challenge token and user id, indicating to the user that MFA is needed to continue
- Walter's application retrieves the list of available providers with the user id
- Walter's application initiates the MFA challenge with the token and a provider of choice
- Walter chooses TOTP, enters the current authentication key to verifiy the challenge
- The challenge was successful and a session is created

It is important to point out, that the attempt to create a session when MFA is enabled will throw an exception - making the developer aware of additional steps.

The exception will contain the informations needed to create and verify a challenge.

### API Endpoints

I propose the following endpoints for MFA implementation:

#### Account Service
- `PATCH: /v1/account/mfa` enables/disables MFA for the account
- `POST: /v1/account/mfa/:provider` adds TOTP/HOTP authenticator to account
- `PUT: /v1/account/mfa/:provider` verifies added TOTP/HOTP authenticator
- `DELETE: /v1/account/mfa/:provider` removes TOTP/HOTP authenticator from account
- `GET: /v1/account/mfa/providers`: returns a list of available MFA providers
- `POST: /v1/account/mfa/challenge`: initiates a MFA challenge with the provider of choice and returns a challenge
- `PUT: /v1/account/mfa/challenge`: verifies a MFA challenge and generates a session

#### User Service
- `PATCH: /v1/user/mfa`: enables/disables disables MFA for the user
- `GET: /v1/user/mfa/providers`: returns a list of available MFA providers
- `DELETE: /v1/user/mfa/totp`: removes TOTP authenticator from user
- `DELETE: /v1/user/mfa/hotp`: removes HOTP authenticator from user

#### Project Service
- `PATCH: /v1/projects/:projectId/mfa`: enables/disables disables MFA for the project
- `PATCH: /v1/projects/:projectId/mfa/:provider` enable/disable available providers to be used for MFA

Obviously all crucial/sensitive endpoints will be covered by rate limits.

### Data Structure

For my proposal I need to add a new internal collection called `challenges` with following data structure (excluding default `$` attributes):
- `token` secret to be used for identification, similiar to the `secret` of the tokens collections
- `provider` the provider used for the challenge (TOTP, HOTP, SMS, E-Mail, etc)
- `session` the session that will be created when the challenge is completed

Additionally we need to add new properties to the `user` collection:
- `mfa` boolean to whether MFA is enabled or not
- `totp` boolean to whether a TOTP device is active
- `totpSecret` the secret key to be used with a TOTP authentication app
- `totpBackup` array of backup codes that can each used once
- `hotp` boolean to whether a HOTP device is active
- `hotpSecret` the secret key to be used with a HOTP authentication app
- `hotpBackup` array of backup codes that can each used once

### Supporting Libraries

Following libraries can be used as dependency or inspiration:

- https://github.com/Spomky-Labs/otphp
- https://github.com/lfkeitel/php-totp

### Algorithms

- https://en.wikipedia.org/wiki/Time-based_one-time_password
- https://en.wikipedia.org/wiki/HMAC-based_one-time_password

### Breaking Changes

No breaking changes will be introduced on the API. But a few data structure changes will have to be migrated.

### Reliability (Tests & Benchmarks)

#### Scaling

This should already be scalable out-of-the-box with existing Appwrite scalability.

#### Benchmarks

Due to the nature of this feature, I don't expect any complications with performance. Of course this will be manually checked during migration.

#### Tests (UI, Unit, E2E)

- Unit Tests with highest Coverage possible
- E2E Tests covering:
- all new endpoints
- all challenges tested for endpoints creating a session

### Documentation & Content

We probably need a new Section in the Documentation explainig the steps to implement MFA.

### Prior art

[prior-art]: #prior-art

I investigate existing MFA implementations and best practices to inform our design proposal. Specifically, I will review MFA implementation in other authentication services, such as Auth0 and Okta.

Also existing RFC's for TOTP are a helpful resource ([RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238)).

Additionally, this feature is planned in a way - that we can extend the MFA to be used with more than 2 factors in the future.

### Unresolved questions

[unresolved-questions]: #unresolved-questions

- A team wide setting that MFA is required
- We might wanna think about adding additional roles for users with MFA

### Future possibilities

[future-possibilities]: #future-possibilities

Right now this RFC only covers a challenge adding a second factor, in the future we can extend with even more factors need in total and also different factors than TOTP, E-Mail and SMS. Something like Captcha, HOTP, wabauthn and co.