Threat model π‘οΈ
This page describes what SigNote is designed to protect against, where the trade-offs are, and what it explicitly does not promise. Understanding the model helps you make informed decisions about what to store and at what tier.
What SigNote protects
Server compromise
If an attacker gains full read access to the database, they get:
- β Notes tier 1 β plaintext (fully readable)
- π Secrets and Seals titles β plaintext (readable, by design)
- π Secrets and Seals bodies β ciphertext only (not readable without the MEK)
- π
serverShareβ present in the database, but useless withoutdeviceShare
Without the user's passphrase, serverShare alone cannot reconstruct the MEK. The attacker would need to brute-force the passphrase against the PBKDF2 derivation β 600,000 iterations of SHA-256 makes this expensive.
β See Encryption for key architecture details.
Client-side sessionStorage read
If an attacker can read the browser's sessionStorage (e.g. via XSS), they get deviceShare. But without serverShare from the server, they still can't reconstruct the MEK.
Note: SigNote sanitises rendered HTML (via DOMPurify) to reduce XSS surface area in note content.
Active session memory
During an unlocked session, the MEK exists in memory as a non-extractable CryptoKey object. JavaScript code on the page cannot read the raw key bytes β but other scripts running in the same origin could potentially interact with the Web Crypto API using that key.
This is the inherent trade-off of any client-side encryption model: the key must exist in memory for encryption and decryption to happen.
Lock events
| Event | What's cleared | Passphrase to re-unlock? |
|---|---|---|
| Tab hidden (soft lock) | MEK (memory) | No β deviceShare kept in sessionStorage |
| Inactivity 5 min (hard lock) | MEK (memory) + deviceShare (sessionStorage) | Yes |
| Sleep / resume gap >30s (hard lock) | MEK (memory) + deviceShare (sessionStorage) | Yes |
| Explicit Lock button (hard lock) | MEK (memory) + deviceShare (sessionStorage) | Yes |
| Tab close | deviceShare (sessionStorage) β MEK already gone with the tab | Yes (new tab) |
| Sign-out | MEK (memory) + deviceShare (sessionStorage) | Yes |
After a hard lock or sign-out, encrypted notes are inaccessible until the passphrase is entered again. After a soft lock, returning to the tab re-unlocks silently using the retained deviceShare.
SIWE domain binding
Sign-In with Ethereum validates the domain embedded in the signed message against the server's configured NEXTAUTH_URL. A valid signature from evil-signote.com will be rejected when submitted to the real app's API.
This prevents a class of phishing attacks where an attacker captures a SIWE signature from a lookalike site and replays it.
Account linking security
If you link several authentication methods β passkeys, an email address, Google, or a wallet β to the same account:
- Every linked method can sign in and reach the same account and encrypted notes
- Your encryption remains tied to your passphrase, not to the authentication method
- If one method is compromised, an attacker can sign in as you
Security implications:
- Your account is only as secure as the weakest method attached to it. Link a method only if you trust it as much as the others
- An emailed code is only as strong as the mailbox it lands in; a passkey or wallet, as strong as the device or keys that hold it
- Use strong passphrases to protect your encrypted notes
- Remove methods you no longer use
- If you suspect one method is compromised, unlink it and change your encryption passphrase
Encryption is independent of sign-in, so compromising a sign-in method does not automatically grant access to encrypted notes β an attacker would still need your passphrase to decrypt Secrets and Seals.
Known trade-offs and limitations
Tier 1 notes are intentionally unencrypted
Notes are stored as plaintext. This enables full-text search across titles and bodies, which is the point. If you store sensitive information there, it's visible to anyone with database access.
Use Secrets or Seals for anything you wouldn't want read from the database.
Titles are always plaintext
Across all three tiers, note titles are stored unencrypted. This enables search and navigation. If your titles themselves contain sensitive information, be aware they're visible to the server.
Passphrase strength matters
The security of your encrypted notes depends on your passphrase. If someone has your serverShare (from the database) and can guess or brute-force your passphrase, they can reconstruct the MEK.
Choose a long, unique passphrase. The minimum is 8 characters. More is better.
Recovery requires a recovery file
SigNote cannot reset your encryption passphrase. A recovery file created while you still have access can reconstruct the same MEK and let you choose a new passphrase. Without either the current passphrase or that recovery file, encrypted data is permanently inaccessible. Keep the recovery file somewhere separate and protected.
An abandoned key change retains a second copy for seven days
Changing your encryption keys stages a complete re-encrypted copy of your Secrets, Seals, version history, Authenticator credentials and encrypted attachments on the server before it activates anything. That staged copy is what makes activation atomic and cancellation free.
Finishing or cancelling disposes of the losing copy straight away β the superseded ciphertext is dropped and its storage objects are queued for deletion, drained by a daily job. Walking away does not. The operation is held open so you can resume it, and it is only discarded after seven days without progress.
So an abandoned key change leaves a second encrypted copy of your encrypted tiers on the server for up to a week. It is encrypted under a key that exists nowhere but the passphrase you chose and the recovery file you saved, and the server can no more read it than it can read the original. It is still a second copy, and it is still there after you close the tab. Cancel a key change you have decided against rather than abandoning it.
Your vault also stays frozen β no writes from any session β for as long as that operation is open, which is its own reason to finish or cancel rather than leave.
sessionStorage persists during the browser session
Between page reloads in the same tab, deviceShare stays in sessionStorage. This means you don't have to re-enter your passphrase on every refresh, but it also means deviceShare is present in the browser for the entire tab session.
Closing the tab clears it automatically.
Authenticator on a trusted device
Trusting a device stores a non-extractable otpVaultKey and an encrypted credential cache in IndexedDB. This is what lets TOTP codes work after a restart, during a network outage, or after the web session expires. It does not keep the MEK or decrypted Secrets in memory.
The browser's profile becomes the local security boundary. Someone who can use that unlocked browser profileβor malicious JavaScript or an extension running in itβcan ask the stored key to decrypt Authenticator credentials even though the raw key cannot be exported. Use the visit-only option on shared devices, and use Profile β Authenticator β Forget this device when the device should no longer retain offline access.
Remote encryption-profile reset invalidates trusted Authenticator keys the next time the device synchronizes. A device that stays permanently offline cannot be erased remotely. Browser storage can also be evicted, especially in private browsing and on iOS when the site is not installed; the encryption passphrase can enroll the device again.
The desktop app loads the hosted site and does not currently provide full cold-start offline support. An already open Authenticator window can continue generating codes from its local cache, but opening the desktop app without a network connection is not guaranteed to work.
What SigNote does not protect against
- An attacker who has both your
serverShareand your passphrase - An attacker with full access to your device during an active, unlocked session
- A compromised browser extension with access to
sessionStorageand network requests - Malicious JavaScript or an extension using a trusted device's persisted Authenticator key
- Side-channel attacks on the Web Crypto API implementation
- Metadata: note count, creation time, title length, and access patterns are visible to the server
- The existence and size of ciphertext retained by an abandoned key change, for up to seven days (see above)
Summary
SigNote's encryption is designed so that neither the server alone nor the client alone is sufficient to decrypt your notes. The passphrase never leaves your device, and the MEK never leaves your browser. If you use strong passphrases and understand the tier model, your encrypted notes are well-protected against database-level compromise.
As with any cryptography-heavy application, treat this as evolving software and review the implementation carefully before relying on it for real-world sensitive data.
β Source code: github.com/irondsd/signote
β Full encryption details: Encryption
β Per-tier details: Secrets, Seals
β Replacing the keys themselves: Changing your keys