"Forget" only removes the vault from this picker — the files on disk are untouched. For OPFS-backed vaults, the data stays in browser storage until site data is cleared.
Choose a master password and a name for this device. There is no recovery — back up regularly.
This vault hasn't been used in this browser before. Enter the master password to register.
Sync is handled by your transport (cloud folder, Syncthing, Git, QR, or manual export). Tijori merges new device log files automatically on unlock.
Each device that has ever written to this vault appears below. Revoking a device invalidates all its future events.
Export a backup or import from another password manager.
Quick confirmation that you still remember your master password. If you forget it, your vault becomes unrecoverable — this catches it before it's terminal.
Choose a vault stored in this browser.
Show this screen to the receiving device. The sequence loops — the other device can start scanning at any frame.
Results live in memory only and are discarded when you close this dialog. No data is sent to any breach-check service.
Re-enter your master password, then touch your hardware key when prompted. Both factors will be required to unlock the vault.
You'll need to touch each registered hardware key once during this operation, because each key's wrap blob is regenerated against the new password.
Tijori (तिजोरी, "strongbox") is a browser-native password manager. Your vault is a folder on your disk. Sync is your choice of transport. Nothing leaves the folder except what you explicitly export.
Tijori is a sibling of Rotor (TOTP). They share the same crypto primitives.
Click Create new vault, pick an empty folder, set a device name and master password. The vault is ready.
Click + Add in the vault view. Choose Login, Card, or Note. The entry is encrypted and appended to your device's log stream immediately.
Click ⎘ on any login row to copy its password. The clipboard self-clears after the configured timeout.
Type in the search box to filter entries live. Press / to focus search from anywhere. Esc clears and closes modals.
You can keep more than one vault — personal / work / family. The welcome screen lists all vaults Tijori knows about. Use the ⋯ menu next to a row to rename it, set it as the default (opens automatically on launch), or forget it (removes from the list without touching the files on disk).
Click Open vault to add an existing vault from another folder; it'll be added to the list automatically.
Settings → Vault → Run vault audit checks for reused or weak passwords, missing 2FA, aging entries, and other hygiene issues. Everything is computed in memory and never sent anywhere — there is no breach-check service.
Tijori can use any FIDO2 / WebAuthn authenticator as a second factor: YubiKeys, Touch ID, Windows Hello, iCloud passkeys, Android passkeys.
Both the master password and the hardware key are required to unlock — losing either alone keeps the vault safe; losing both is the only way in.
To bind a key: Settings → Security → Bind a hardware key. You'll be prompted for your master password (this is normal — we re-derive the encryption material) and then asked to touch your key.
Always bind a backup key. A single key with no fallback can lock you out permanently if the key is lost or breaks. Tijori reminds you until you've either bound two keys or explicitly enabled password-only fallback.
Synced passkeys (iCloud, Google) work with Tijori but exist in cloud-synced form. If you want a strictly device-bound second factor, use a dedicated hardware key like a YubiKey.
Requires Chrome 116+, Edge 116+, or Safari 18+. Firefox: not yet.
Vaults created in v1.1+ use Argon2id (m=64MB, t=3, p=4) — a memory-hard function designed to resist GPU and ASIC attacks.
Vaults created before v1.1 use PBKDF2-SHA-256 at 600,000 iterations (still strong, but older). They auto-upgrade to Argon2id on next save.
When a hardware key is bound, the password-derived key is XOR-mixed with a 32-byte secret derived from the key (via WebAuthn PRF), then HKDF-expanded into the wrap key. The vault's master secret is wrapped per bound key. Adding or removing keys never re-encrypts your data — only the wrap blobs change.
Verify the implementation: every line is in index.html. Read it.
Tijori makes zero network requests after the page loads. This is enforced by Content-Security-Policy: connect-src 'none'.
Open DevTools → Network panel and watch. Reload Tijori. After the initial document, nothing else fetches. Any attempted XHR, fetch, WebSocket, sendBeacon, or EventSource would appear in the console as a CSP violation.
This includes WebAuthn: calls into your authenticator (YubiKey, Touch ID, etc.) are browser-to-device APIs, not network calls. Nothing leaves your machine.
No analytics. No telemetry. No "anonymous usage stats." No bug reporting service. If something breaks, file an issue on GitHub.
The vault is unrecoverable. We never see your password and never store it anywhere. By design, there is no recovery.
Back up your password the same way you back up your vault — a sealed envelope in a safe, a hardware password manager, written on paper somewhere only you know.
Use one of your other bound keys, or your password-only fallback if you enabled it. Then go to Settings → Security and remove the lost key from the vault. Register a replacement.
If you bound only one key, with no password-only fallback, and that key is gone, the vault is unrecoverable. This is why Tijori nags you to bind two keys.
Your vault is yours. Tijori can hand it off to any KeePass-compatible client, to any password manager via CSV, or stay self-contained with the encrypted archive. None of these require Tijori on the other end.
Settings → Data → Export to KeePass (.kdbx). Produces a KDBX4 file (ChaCha20 + Argon2id) — readable by KeePassXC (desktop), KeePassium (iOS), KeePassDX (Android), Strongbox (iOS/Mac), KeeWeb, MacPass, and any other KeePass-compatible client.
You'll be asked for an export password, which is separate from your Tijori master password. The exported file is independent — re-exporting later does not update old exports.
Structure: four groups (Logins, Cards, Notes, Codes). Cards use card_number / card_expiry custom fields. TOTP codes use the otp custom field with a full otpauth:// URI — KeePassXC and Strongbox auto-detect this and rotate codes natively.
This is a one-way snapshot. Tijori has no "import-from-edited-.kdbx" flow that would merge changes back.
Recommended pattern: keep Tijori on a desktop as the canonical editor, and use KeePassium / Strongbox / KeePassDX as read clients on mobile.
Settings → Data → Export as CSV. Lowest-common-denominator format, importable by Bitwarden, 1Password, Apple Passwords, Dashlane, NordPass, etc.
CSV is plaintext — every password is readable by anyone with the file. Use this only for migration, then delete the file. For backups or long-term storage, use the encrypted archive or KeePass .kdbx export.
Lossy: cards and notes are flattened into the Notes column with a structural prefix. TOTP secrets are emitted as full otpauth:// URIs in the login_totp column (Bitwarden's convention).
Settings → Data → Export encrypted archive. Tijori's own format — a JSON wrapper around the meta + every device's event stream. Import back into Tijori on another device via Import → Tijori archive.
This is the right format for "I want to move my Tijori vault to a new device by file." For "I want to read this vault in another app," use the KeePass export.
Each device writes only its own log file (tijori-events-<deviceId>.jsonl). Sync is the act of making all devices see all files. Tijori merges them on every unlock — deterministically, regardless of order.
Put the vault folder inside iCloud Drive, Dropbox, Google Drive, etc. Each device running Tijori points at its local copy. The cloud provider syncs files; Tijori merges on unlock.
Point Syncthing at the vault folder across devices. P2P, no cloud vendor.
Commit and push. Each device's log stream is a separate file, so git merge never conflicts on event logs (only if two devices edit the same file directly, which Tijori never does).
On the source device: Settings → Data → Send vault via QR. A sequence of QR codes loops on screen. On the receiving device: Import → QR sequence — point the camera at the screen. All frames are collected automatically; order doesn't matter. Fully offline, no cables.
Use Settings → Data → Export encrypted archive to pack the vault. Import it on another device via Import → Tijori archive.
Open the vault folder from the second browser. Tijori detects the new device, asks for the master password, emits a device_registered event, and merges.
tijori-meta.json — plaintext: KDF params, device roster.tijori-events-<deviceId>.jsonl — one file per device. Append-only, SHA-256 hash-chained.{"seq":1,"prev_hash":"genesis","ts":"…","device_id":"…","event_type":"entry_created","payload_ct":"…","nonce":"…"}
master_secret wrapped per bound key with HKDF over (pw_key XOR prf_secret).Union all events, sort by (ts, device_id), apply in order. Per-field last-writer-wins — each field carries its own timestamp, so two devices editing different fields of the same entry both win their field.