bitwarden/server
Auth: master password, 2FA, login-with-device, passkeys, TDE
Active contributors: auth team.
Purpose
Authentication covers everything that gets a user to a valid access token. Bitwarden supports many login flows in parallel:
- Master-password — the classic flow. Email + master-password hash → JWT.
- Two-factor (TOTP / Email / Duo / WebAuthn / YubiKey) — second factor on top of master-password.
- Login With Device / Auth Request — a logged-in device approves a pending request from a new device.
- Login With Passkey (WebAuthn PRF) — passwordless via a FIDO2 authenticator's PRF extension.
- Trusted Device Encryption (TDE) — admin-approval / device-key flow for SSO-managed orgs that don't want users to know a master password.
- SSO (SAML / OIDC) — corporate IdP redirect (see sso-saml.md).
- API keys —
client_credentialsfor org-bearer / installation / SCIM tokens. - Emergency Access — designate someone who can request access to your vault.
Where the code lives
| Concern | Path |
|---|---|
| IdentityServer wiring | src/Identity/, src/Core/Auth/IdentityServer/ |
| Master-password validation | src/Core/Services/Implementations/UserService.cs (CheckPasswordAsync) |
| 2FA token providers | src/Core/Auth/Identity/TokenProviders/ |
| Auth requests | src/Core/Auth/Entities/AuthRequest.cs, src/Core/Auth/Services/AuthRequestService.cs |
| WebAuthn login | src/Core/Auth/UserFeatures/WebAuthnLogin/ |
| TDE (Trusted Device Encryption) | src/Core/Auth/UserFeatures/DeviceTrust/ |
| Master-password commands | src/Core/Auth/UserFeatures/UserMasterPassword/ |
| Registration | src/Core/Auth/UserFeatures/Registration/ |
| TDE off-boarding | src/Core/Auth/UserFeatures/TdeOffboardingPassword/ |
| Emergency Access | src/Core/Auth/Entities/EmergencyAccess.cs, src/Core/Auth/Services/IEmergencyAccessService.cs |
| Send-access (special scope) | src/Core/Auth/UserFeatures/SendAccess/ |
Master-password login
sequenceDiagram
participant Client
participant Identity
participant Db
Client->>Client: derive master key (Argon2/PBKDF2)
Client->>Client: derive masterPasswordHash (PBKDF2 over master key)
Client->>Identity: POST /connect/token (grant=password,<br/>email, masterPasswordHash, captchaToken?)
Identity->>Db: ResourceOwnerPasswordValidator → IUserService.CheckPasswordAsync
Identity-->>Client: 200 access_token + refresh_token + userDecryptionOptionsUserService.CheckPasswordAsync uses ASP.NET Core Identity's password hasher (PBKDF2 with the per-user PasswordHasherOptions). The new master password is also hashed once on the client (Argon2id default; PBKDF2 legacy) and only the hash crosses the wire.
Two-factor
BaseRequestValidator invokes TwoFactorAuthenticationValidator after the credential check. Providers in src/Core/Auth/Identity/TokenProviders/:
| Provider | Token / Secret | Notes |
|---|---|---|
AuthenticatorTokenProvider |
TOTP (RFC 6238) | Client-side enrolment via QR code. |
EmailTokenProvider |
6-digit code over email | Default fallback for non-premium users. |
DuoTokenProvider / OrganizationDuoTokenProvider |
Duo Universal Prompt | Per-user and per-org variants. |
WebAuthnTokenProvider |
FIDO2 authenticator (second factor mode) | |
YubicoOtpTokenProvider |
Yubico OTP via Yubico cloud | |
RememberTokenProvider |
"Remember this device" cookie | 30-day suppression of 2FA. |
Org-level TwoFactorAuthenticationPolicy (src/Core/AdminConsole/OrganizationFeatures/Policies/) can require 2FA for everyone in an org.
Login with device (auth requests)
A pending login on Device B emits an AuthRequest row. Device A (already logged in) sees a push notification, approves, and the response includes a wrapped user key. Device B then completes the auth_request extension grant and receives a JWT.
Code: src/Core/Auth/Entities/AuthRequest.cs, src/Core/Auth/Services/AuthRequestService.cs, src/Core/Auth/IdentityServer/RequestValidators/AuthRequestExtensionGrantValidator.cs.
Login with passkey (WebAuthn PRF)
The flow is similar to login with device but the PRF blob produced by the FIDO2 authenticator is used to decrypt the user key. src/Core/Auth/UserFeatures/WebAuthnLogin/ houses the commands; WebAuthnLoginGrantValidator handles the grant exchange.
Trusted Device Encryption (TDE)
For SSO-only orgs that want passwordless onboarding, TDE has another logged-in device approve newly-trusted devices. DeviceTrust/ contains the commands. The user key is wrapped to the device's public key and stored on the Device row.
Emergency Access
EmergencyAccess lets a user designate someone who can request access to their vault. Two grant types:
- View — read-only access after a configurable wait period.
- Takeover — full access, the grantee resets the master password.
Pending requests fire push + email notifications via IEmergencyAccessService.
Master-password service
PR #7530 (2026-04-22) introduced a dedicated IMasterPasswordService (src/Core/Auth/UserFeatures/UserMasterPassword/) that consolidates set / change / reset / validate operations previously scattered across UserService. New code should call this service rather than the legacy UserService.ChangePasswordAsync.
Entry points for modification
- New 2FA provider → see systems/identity-server.
- New grant type → custom
IExtensionGrantValidatorinsrc/Core/Auth/IdentityServer/RequestValidators/. - Tighten password policy →
UserService.CheckPasswordAsyncand theMasterPasswordPolicyDatainsrc/Core/AdminConsole/Models/Data/. - Change captcha behaviour →
HCaptchaTokenableinsrc/Core/Auth/Models/Business/Tokenables/plus the related validator.
For SSO see sso-saml.md. For key rotation (driven by master-password change) see key-management.md.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.