Credential payloads are encrypted before storage
Passwords, notes, and 2FA setup keys are encrypted with AES-256-GCM before they are written to the database, so the app is not treating the database like a plaintext dumping ground.

Forgot Password is designed to keep client-account access in one system with stronger defaults: hashed user passwords, encrypted credential payloads, deliberate reveal flows, audit visibility, and organization boundaries checked again at the moment sensitive data is accessed.
Passwords, notes, and 2FA setup keys are encrypted with AES-256-GCM before they are written to the database, so the app is not treating the database like a plaintext dumping ground.
Account login passwords are hashed with Argon2id, which is a modern password hashing algorithm designed to make offline cracking substantially harder than older hashing approaches.
A logged-in session is not enough by itself. Users must re-enter their own account password before a stored secret is decrypted and shown.
The app encrypts credential payloads with AES-256-GCM and stores the ciphertext alongside an IV, authentication tag, and key version. That gives the app confidentiality plus an integrity check so modified ciphertext fails decryption rather than silently returning junk.
User passwords are processed with Argon2id using explicit memory and time cost settings. That matters because a password manager is only as trustworthy as the protection on the operator accounts that can unlock it.
Sessions are stored in an `httpOnly` cookie with `sameSite=lax`, an eight-hour lifetime, and `secure` enabled in production so JavaScript cannot directly read the session token.
The secret-reveal endpoint rejects `GET` requests, requires `POST`, and returns `no-store` and `no-cache` headers so browsers and intermediaries are instructed not to keep sensitive reveal responses around.
When a reveal succeeds, the UI treats plaintext as short-lived and auto-clears it after 45 seconds. That does not eliminate all operator risk, but it reduces casual exposure.
Reveal attempts are rate-limited. The current code locks users out after 5 failed reveal password checks inside a 15-minute window, based on user ID and optionally IP address.
Failed attempts are also recorded, which helps make brute-force reveal behavior noisier and easier to notice.
The app records audit events for actions like sign-in, sign-up, credential creation, successful reveals, failed reveal checks, invites, role changes, and super-admin cross-organization access.
Audit metadata is explicitly sanitized to avoid writing raw passwords, plaintext secrets, password hashes, or encrypted password fields into the log payload by mistake.
The app uses server-side cookie session handling instead of storing auth state in browser local storage, which reduces one common client-side exposure path.
The current reveal flow is built around short-lived plaintext exposure instead of persistent always-visible passwords across the interface.
The system combines encryption with re-authentication, access boundaries, logging, and rate limits because operational mistakes are often where client-account risk actually comes from.
For product or security questions, contact admin@draftroom.works.