Authentication
Bonds supports multiple authentication methods, from traditional password login to modern passkeys.
Password, JWT, and Email Verification
The default authentication flow is:
- Register with email and password.
- Email Verification: A verification link is sent to the registered email address. Users must click the link to verify their account before accessing their vaults.
- If the verification email is lost or expires, users can click the resend button on the verification screen to trigger a new link.
- Email verification is also required when updating your email address from your account settings.
- Login returns a JWT token.
- Token is sent in the
Authorization: Bearer <token>header. - Tokens expire after 24 hours (configurable via
JWT_EXPIRY_HRS). - Tokens can be refreshed within 7 days (configurable via
JWT_REFRESH_HRS).
Two-Factor Authentication (TOTP)
Add an extra layer of security with TOTP-based 2FA:
- Enable: Go to Settings, Security, Enable 2FA.
- Scan QR code: Use any authenticator app (Google Authenticator, Authy, 1Password, etc.).
- Save recovery codes: 8 one-time-use recovery codes are generated. Store them safely.
- Confirm: Enter a TOTP code to activate.
Login with 2FA
When 2FA is enabled, login is a two-step process:
- Enter email and password. The server returns
requires_two_factor: trueand a temporary token. - Enter the TOTP code (or a recovery code). The server returns the full JWT.
Recovery Codes
8 random 8-character codes are generated when 2FA is enabled. Each code can only be used once. Use them if you lose access to your authenticator app.
2FA and DAV Sync
When 2FA is enabled, password-based DAV authentication is blocked. DAV clients (CardDAV/CalDAV) must use a Personal Access Token instead of your password. This follows the same security model as Google, Apple, and Fastmail. A stolen password alone cannot bypass 2FA to access your data via DAV endpoints.
To configure your DAV client after enabling 2FA:
- Go to Settings > API Tokens and create a new token.
- In your DAV client, use your email as the username and the token (starting with
bonds_) as the password.
WebAuthn / FIDO2
Bonds supports passwordless login via WebAuthn:
- Hardware keys: YubiKey, Titan Security Key, etc.
- Biometrics: Touch ID, Face ID, Windows Hello.
- Passkeys: iCloud Keychain, Android passkeys.
Setup
- Go to Settings, Security, Register a new passkey.
- Follow your browser prompt to create a credential.
- The passkey is now linked to your account.
Requirements
- HTTPS is required (except
localhostfor development). - Configure WebAuthn settings in the admin panel:
- RP ID: Your domain (e.g.,
bonds.example.com). - RP Display Name: Shown to users during authentication.
- RP Origins: Allowed origins (e.g.,
https://bonds.example.com).
- RP ID: Your domain (e.g.,
Upgrading from v0.12.5 or earlier
Passkeys registered before backup-flag persistence was added cannot recover their original backup-eligible value, so synced passkeys (iCloud Keychain, Google Password Manager, 1Password, etc.) will keep failing to log in until re-enrolled. Delete and register the passkey again under Settings, Security.
OAuth Login
Bonds supports single sign-on via:
| Provider | Configuration |
|---|---|
| GitHub | OAuth App client ID and secret |
| OAuth client ID and secret |
Configure these in the admin panel. When enabled, "Login with GitHub" or "Login with Google" buttons appear on the login page.
If the OAuth email matches an existing Bonds account, the accounts are automatically linked.
OAuth Callback Flow
GET /api/auth/:provider -> Redirect to OAuth provider
GET /api/auth/:provider/callback -> JWT -> Redirect to /auth/callback?token=xxxOIDC (OpenID Connect)
Bonds supports generic OIDC providers for enterprise SSO:
| Setting | Description |
|---|---|
| Client ID | OIDC client ID |
| Client Secret | OIDC client secret |
| Discovery URL | Provider discovery URL |
| Display Name | Button label on login page (default: "SSO") |
Configure your IdP callback URL as https://{your-bonds-url}/api/auth/{provider-name}/callback. The {provider-name} segment is the provider Name / slug configured in Bonds, not the display name shown on the login page. For example, if your Bonds URL is https://bonds.domain.com and the provider Name is nextcloud-sso, the callback URL is https://bonds.domain.com/api/auth/nextcloud-sso/callback.
Configure in the admin panel. Use the full discovery-document URL (usually https://issuer/.well-known/openid-configuration), not the issuer homepage. OIDC sign-in uses authorization code + PKCE S256, with openid email profile scopes by default; configured custom scopes are also supported.