|
| 1 | +# Authentication Flows Documentation |
| 2 | + |
| 3 | +## Standard Auth Request Flows |
| 4 | + |
| 5 | +### Flow 1: Unauthed user requests approval from device; Approving device has a masterKey in memory |
| 6 | + |
| 7 | +1. Unauthed user clicks "Login with device" |
| 8 | +2. Navigates to /login-with-device which creates a StandardAuthRequest |
| 9 | +3. Receives approval from a device with authRequestPublicKey(masterKey) |
| 10 | +4. Decrypts masterKey |
| 11 | +5. Decrypts userKey |
| 12 | +6. Proceeds to vault |
| 13 | + |
| 14 | +### Flow 2: Unauthed user requests approval from device; Approving device does NOT have a masterKey in memory |
| 15 | + |
| 16 | +1. Unauthed user clicks "Login with device" |
| 17 | +2. Navigates to /login-with-device which creates a StandardAuthRequest |
| 18 | +3. Receives approval from a device with authRequestPublicKey(userKey) |
| 19 | +4. Decrypts userKey |
| 20 | +5. Proceeds to vault |
| 21 | + |
| 22 | +**Note:** This flow is an uncommon scenario and relates to TDE off-boarding. The following describes how a user could |
| 23 | +get into this flow: |
| 24 | + |
| 25 | +1. An SSO TD user logs into a device via an Admin auth request approval, therefore this device does NOT have a masterKey |
| 26 | + in memory |
| 27 | +2. The org admin: |
| 28 | + - Changes the member decryption options from "Trusted devices" to "Master password" AND |
| 29 | + - Turns off the "Require single sign-on authentication" policy |
| 30 | +3. On another device, the user clicks "Login with device", which they can do because the org no longer requires SSO |
| 31 | +4. The user approves from the device they had previously logged into with SSO TD, which does NOT have a masterKey in |
| 32 | + memory |
| 33 | + |
| 34 | +### Flow 3: Authed SSO TD user requests approval from device; Approving device has a masterKey in memory |
| 35 | + |
| 36 | +1. SSO TD user authenticates via SSO |
| 37 | +2. Navigates to /login-initiated |
| 38 | +3. Clicks "Approve from your other device" |
| 39 | +4. Navigates to /login-with-device which creates a StandardAuthRequest |
| 40 | +5. Receives approval from device with authRequestPublicKey(masterKey) |
| 41 | +6. Decrypts masterKey |
| 42 | +7. Decrypts userKey |
| 43 | +8. Establishes trust (if required) |
| 44 | +9. Proceeds to vault |
| 45 | + |
| 46 | +### Flow 4: Authed SSO TD user requests approval from device; Approving device does NOT have a masterKey in memory |
| 47 | + |
| 48 | +1. SSO TD user authenticates via SSO |
| 49 | +2. Navigates to /login-initiated |
| 50 | +3. Clicks "Approve from your other device" |
| 51 | +4. Navigates to /login-with-device which creates a StandardAuthRequest |
| 52 | +5. Receives approval from device with authRequestPublicKey(userKey) |
| 53 | +6. Decrypts userKey |
| 54 | +7. Establishes trust (if required) |
| 55 | +8. Proceeds to vault |
| 56 | + |
| 57 | +## Admin Auth Request Flow |
| 58 | + |
| 59 | +### Flow: Authed SSO TD user requests admin approval |
| 60 | + |
| 61 | +1. SSO TD user authenticates via SSO |
| 62 | +2. Navigates to /login-initiated |
| 63 | +3. Clicks "Request admin approval" |
| 64 | +4. Navigates to /admin-approval-requested which creates an AdminAuthRequest |
| 65 | +5. Receives approval from device with authRequestPublicKey(userKey) |
| 66 | +6. Decrypts userKey |
| 67 | +7. Establishes trust (if required) |
| 68 | +8. Proceeds to vault |
| 69 | + |
| 70 | +**Note:** TDE users are required to be enrolled in admin account recovery, which gives the admin access to the user's |
| 71 | +userKey. This is how admins are able to send over the authRequestPublicKey(userKey) to the user to allow them to unlock. |
| 72 | + |
| 73 | +## Summary Table |
| 74 | + |
| 75 | +| Flow | Auth Status | Clicks Button [active route] | Navigates to | Approving device has masterKey in memory\* | |
| 76 | +| --------------- | ----------- | --------------------------------------------------- | ------------------------- | ------------------------------------------------- | |
| 77 | +| Standard Flow 1 | unauthed | "Login with device" [/login] | /login-with-device | yes | |
| 78 | +| Standard Flow 2 | unauthed | "Login with device" [/login] | /login-with-device | no | |
| 79 | +| Standard Flow 3 | authed | "Approve from your other device" [/login-initiated] | /login-with-device | yes | |
| 80 | +| Standard Flow 4 | authed | "Approve from your other device" [/login-initiated] | /login-with-device | no | |
| 81 | +| Admin Flow | authed | "Request admin approval" [/login-initiated] | /admin-approval-requested | NA - admin requests always send encrypted userKey | |
| 82 | + |
| 83 | +**Note:** The phrase "in memory" here is important. It is possible for a user to have a master password for their |
| 84 | +account, but not have a masterKey IN MEMORY for a specific device. For example, if a user registers an account with a |
| 85 | +master password, then joins an SSO TD org, then logs in to a device via SSO and admin auth request, they are now logged |
| 86 | +into that device but that device does not have masterKey IN MEMORY. |
| 87 | + |
| 88 | +## State Management |
| 89 | + |
| 90 | +### View Cache |
| 91 | + |
| 92 | +The component uses `LoginViaAuthRequestCacheService` to manage persistent state across extension close and reopen. |
| 93 | +This cache stores: |
| 94 | + |
| 95 | +- Auth Request ID |
| 96 | +- Private Key |
| 97 | +- Access Code |
| 98 | + |
| 99 | +The cache is used to: |
| 100 | + |
| 101 | +1. Preserve authentication state during extension close |
| 102 | +2. Allow resumption of pending auth requests |
| 103 | +3. Enable processing of approved requests after extension close and reopen. |
| 104 | + |
| 105 | +### Component State Variables |
| 106 | + |
| 107 | +Key state variables maintained during the authentication process: |
| 108 | + |
| 109 | +#### Authentication Keys |
| 110 | + |
| 111 | +``` |
| 112 | +private authRequestKeyPair: { |
| 113 | + publicKey: Uint8Array | undefined; |
| 114 | + privateKey: Uint8Array | undefined; |
| 115 | +} | undefined |
| 116 | +``` |
| 117 | + |
| 118 | +- Stores the RSA key pair used for secure communication |
| 119 | +- Generated during auth request initialization |
| 120 | +- Required for decrypting approved auth responses |
| 121 | + |
| 122 | +#### Access Code |
| 123 | + |
| 124 | +``` |
| 125 | +private accessCode: string | undefined |
| 126 | +``` |
| 127 | + |
| 128 | +- 25-character generated password |
| 129 | +- Used for retrieving auth responses when user is not authenticated |
| 130 | +- Required for standard auth flows |
| 131 | + |
| 132 | +#### Authentication Status |
| 133 | + |
| 134 | +``` |
| 135 | +private authStatus: AuthenticationStatus | undefined |
| 136 | +``` |
| 137 | + |
| 138 | +- Tracks whether user is authenticated via SSO |
| 139 | +- Determines available flows and API endpoints |
| 140 | +- Affects navigation paths (`/login` vs `/login-initiated`) |
| 141 | + |
| 142 | +#### Flow Control |
| 143 | + |
| 144 | +``` |
| 145 | +protected flow = Flow.StandardAuthRequest |
| 146 | +``` |
| 147 | + |
| 148 | +- Determines current authentication flow (Standard vs Admin) |
| 149 | +- Affects UI rendering and request handling |
| 150 | +- Set based on route and authentication state |
| 151 | + |
| 152 | +### State Flow Examples |
| 153 | + |
| 154 | +#### Standard Auth Request Cache Flow |
| 155 | + |
| 156 | +1. User initiates login with device |
| 157 | +2. Component generates auth request and keys |
| 158 | +3. Cache service stores: |
| 159 | + ``` |
| 160 | + cacheLoginView( |
| 161 | + authRequestResponse.id, |
| 162 | + authRequestKeyPair.privateKey, |
| 163 | + accessCode |
| 164 | + ) |
| 165 | + ``` |
| 166 | +4. On page refresh/revisit: |
| 167 | + - Component retrieves cached view |
| 168 | + - Reestablishes connection using cached credentials |
| 169 | + - Continues monitoring for approval |
| 170 | + |
| 171 | +#### Admin Auth Request State Flow |
| 172 | + |
| 173 | +1. User requests admin approval |
| 174 | +2. Component stores admin request in `AuthRequestService`: |
| 175 | + ``` |
| 176 | + setAdminAuthRequest( |
| 177 | + new AdminAuthRequestStorable({ |
| 178 | + id: authRequestResponse.id, |
| 179 | + privateKey: authRequestKeyPair.privateKey |
| 180 | + }), |
| 181 | + userId |
| 182 | + ) |
| 183 | + ``` |
| 184 | +3. On subsequent visits: |
| 185 | + - Component checks for existing admin requests |
| 186 | + - Either resumes monitoring or starts new request |
| 187 | + - Clears state after successful approval |
| 188 | + |
| 189 | +### State Cleanup |
| 190 | + |
| 191 | +State cleanup occurs in several scenarios: |
| 192 | + |
| 193 | +- Component destruction (`ngOnDestroy`) |
| 194 | +- Successful authentication |
| 195 | +- Request denial or timeout |
| 196 | +- Manual navigation away |
| 197 | + |
| 198 | +Key cleanup actions: |
| 199 | + |
| 200 | +1. Hub connection termination |
| 201 | +2. Cache clearance |
| 202 | +3. Admin request state removal |
| 203 | +4. Key pair disposal |
0 commit comments