Account
Authentication & 2FA
Signing in proves who you are to the service. It is deliberately separate from the passphrase that encrypts your files, so the server can authenticate you without ever being able to read your data.
Password vs. passphrase
zcrypt uses two different secrets, and keeping them straight is the single most important thing to understand about your account.
These are not the same secret
Your account password authenticates you to the service. It is sent to the server (over TLS), where it is verified against a bcrypt hash. Resetting it is routine.
Your vault passphrase encrypts your files. It is used only on your device to derive your encryption keys and is never sent to the server. Because we never see it, we can never reset it for you. See Account recovery.
Everything on this page is about the first secret: how you sign in. For how the second secret protects your data, see Key management.
Signing up
Create an account with an email address, a username, and a password. Passwords are hashed with bcrypt before storage: the server never keeps your password in plaintext. To be accepted, a password must meet a basic complexity bar:
- •At least 8 characters
- •At least one uppercase letter
- •At least one digit
- •At least one special character (anything that isn't a letter or number)
- •No longer than 72 bytes, bcrypt's input limit (72 plain letters, fewer with accents or emoji)
zcrypt also checks your chosen password against the HaveIBeenPwned breach corpus using a k-anonymity range query: only the first five characters of a SHA-1 hash leave your session, never the password itself. If the password has appeared in a known breach, you get a warning with the breach count and can choose a stronger one or proceed anyway. The same check runs when you set a new password during a reset.
Email verification
When email is configured for your instance, signing up sends a verification link to your address. Verifying your email protects you in one concrete way: a verified email is required before an OAuth provider with the same address can be auto-linked to your account, so nobody can attach their Google or GitHub identity to an email you have not proven you control. You can request a fresh verification link if the first one expires.
Magic-link login
Prefer not to type a password? Request a magic link and zcrypt emails you a one-time sign-in link. Opening it logs you in and, if your email wasn't verified yet, verifies it at the same time. Magic links are single-use and short-lived, so an old link in your inbox can't be replayed later.
Resetting your password
Forgot your account password? Request a reset and follow the link emailed to you to choose a new one. New passwords must pass the same complexity and breach checks as sign-up. Completing a reset is a hard security boundary:
- •Your token version is bumped, which invalidates every existing access token immediately.
- •All refresh tokens are deleted, so every signed-in device is forced to log in again.
A password reset does not touch your files
Resetting your account password restores access to the service. It does not, and cannot, decrypt your vault. Your files stay sealed under your vault passphrase, which the reset flow never sees.Sessions & tokens
After you sign in, zcrypt issues two tokens. A short-lived access token (a signed JWT) authorizes your API requests, and a longer-lived refresh token is exchanged silently in the background for a fresh access token so you stay signed in without re-entering your password.
| Token | Lifetime | Purpose |
|---|---|---|
| Access token (JWT) | 15 minutes | Authorizes each API request |
| Refresh token | 7 days | Silently mints new access tokens |
Refresh tokens are stored only as hashes on the server and are rotated on every use, so a captured refresh token has a short useful life. Access-token JWTs are signed with HS256 and pin their type, so a token minted for one purpose (for example the mid-login 2FA step) can never be replayed as a full session token.
Log out everywhere, instantly
Each JWT carries a token version. Bumping your token version invalidates every outstanding access token at once and clears your refresh tokens, an instant “sign out of all sessions”. A password reset does exactly this for you.Two-factor (TOTP)
For a second layer on sign-in, enable time-based one-time-password (TOTP) two-factor authentication. It works with any standard authenticator app. Google Authenticator, 1Password, Aegis, Authy, and others: using the usual 6-digit, 30-second codes.
- Start setup in your account settings. zcrypt generates a secret and an otpauth:// URI you scan as a QR code (or enter by hand).
- Enter a current 6-digit code from your authenticator to confirm the secret synced correctly. Only then is 2FA switched on.
- From then on, signing in asks for a code. Your password is checked first; only on success does the server hand back a short-lived temporary token to complete the 2FA step.
When you enable 2FA, zcrypt also issues a set of one-time backup codes. Save them somewhere safe, if you lose your authenticator, a backup code gets you back in. Each code works once, and you can regenerate a fresh set at any time, which invalidates the old ones.
To turn 2FA off, you must confirm both your current password and a valid code, so a stranger who briefly has your unlocked session still can't strip the second factor. Code validation allows a one-step time window on either side to tolerate minor clock drift between your phone and the server.