Security Design and Threat Model
Last verified against the implementation: September 17, 2026 — release 1.0.0
Soix Notes is a closed-source product that makes a privacy claim. That combination deserves scrutiny, so this document is written to be checked rather than believed. It states what is protected, what is not, what an attacker in each position can learn, and which parts you have to take on trust.
Where a claim can be tested from outside the application, the test is written out so you can run it.
1. Two things you can verify yourself, without source code
These are the load-bearing claims. Both are falsifiable in about ten minutes, and if either were untrue the test would show it immediately.
There is no Soix server
Point any network monitor at the app — Wireshark, Fiddler, or the Windows firewall with outbound logging. Use it normally: create a vault, write notes, search, sync.
You will see traffic to the cloud provider you configured, and to Microsoft's sign-in endpoints if you connected OneDrive. You will not see any Soix domain. There is no account to create, no licence check, no telemetry endpoint, and no crash reporting service. Links you click in the app open in your system browser, which is a separate process.
Stronger version of the same test: block the app's outbound network access entirely. Everything except sync keeps working — creating and editing notes, attachments, search, reminders, import and export. Sync is the only feature that needs the network, and it is off until you turn it on.
Your notes can leave whenever you want
There are two export routes, and they are for different purposes.
Export raw data gives you a folder tree you can browse
in Windows Explorer: your notebook hierarchy as nested directories, one
directory per note, every attachment restored as an ordinary file under
its original name, and a meta.json per note holding its
full metadata and the complete notebook path it came from. This route
is lossless and re-importable.
The body format differs by note type, and it is worth knowing which you
will get: Markdown and to-do notes export as .md, web
clips as .html, and
rich text notes export as body.json — a
structured representation of the document, not prose. That format is
open and parseable, but it is not what you want if the goal is to open
the note in another editor tomorrow.
Export as HTML is the route for that. It produces documents any browser or word processor opens, with attachments alongside.
Between the two: your content leaves in open formats, by your own action, and no Soix tool is needed to read the result.
Export is per notebook. Every note belongs to a notebook — the field is non-nullable in the data model, so there is no unfiled area and no hidden bucket — which means exporting each top-level notebook covers everything you have. A notebook export includes the notes in all of its sub-notebooks.
Four things worth knowing, because an export that surprises you is not an escape hatch:
- The archive is plaintext. Exporting takes your notes out from under encryption. Put the result somewhere you are willing to have it.
- If the note list is filtered by a search term, the export covers the filtered list. Clear the search box first.
- Notes in the trash are not included. Export them from the trash view if you want them.
- An empty notebook produces no directory, since directories are created per note.
The exporter returns the name of any attachment it could not decrypt or could not find, rather than dropping it silently. If that list is not empty, something is wrong and you are told which file.
There is no single "export the entire vault" button today; you export notebook by notebook. That is a convenience gap, and it is on the roadmap.
2. What the encryption actually is
Parameters are given so they can be judged, and so that a change in them is visible as a change to this document.
Your passphrase never leaves your device and is never stored. It is stretched into a key-encryption key (KEK):
| Key derivation | Argon2id (RFC 9106) |
| Memory | 64 MiB |
| Iterations | 3 |
| Parallelism | 4 |
| Output | 32 bytes |
| Salt | 32 random bytes, generated per vault, stored in the vault header |
A random 32-byte master key (MEK) is generated when the vault is created. The KEK encrypts the MEK; it never encrypts your content directly. This is what lets you change your passphrase without re-encrypting the vault: only the wrapped MEK is replaced.
Content keys are derived from the MEK with HKDF-SHA256 using separate
info strings, so a key used for one purpose cannot be substituted for
another: content/v1, index/v1,
search/v1, mac/v1.
Every object — note body, metadata manifest, attachment, search index — is encrypted with AES-256-GCM, a fresh random 12-byte nonce per object, and a 16-byte authentication tag. The additional authenticated data binds each ciphertext to its identity: format magic, cipher id, flags, the object's 16-byte UUID, and an object-type byte. A ciphertext therefore cannot be moved to another note, or replayed as a different kind of object, without the decryption failing.
The vault header is covered by HMAC-SHA256 under the KEK, compared in constant time. Editing the header — including the stored KDF parameters, which is the interesting attack — makes the vault fail to open rather than open weakly.
Recovery key. At vault creation you are given a 12-word BIP39 mnemonic, generated at 128-bit strength. Its seed is run through HKDF-SHA256, salted with the vault id, to derive a second key that wraps its own copy of the same MEK. This is what makes a forgotten passphrase survivable.
Three consequences, all worth stating before you ask. The recovery path uses HKDF rather than Argon2id, and that is not an oversight: Argon2 exists to stretch low-entropy human input, while the mnemonic already carries 128 bits of real randomness, which is beyond brute force regardless of how cheap each guess is. Because it wraps the same master key, the mnemonic is exactly as powerful as your passphrase — see §5.
And the one that surprises people: changing your passphrase does not invalidate the mnemonic. Changing the passphrase re-wraps only the passphrase copy of the master key, under a fresh salt. The recovery copy is left exactly as it was, by design, because otherwise every passphrase change would also invalidate the piece of paper in your drawer. The consequence is that if your mnemonic is exposed, no action inside the app takes it out of circulation. Treat it with the same care you would treat the vault itself.
What is not uploaded. The search index stays local and is rebuilt on demand. Local sync bookkeeping and conflict backups stay local. Only the vault header, encrypted metadata, encrypted note bodies, and encrypted attachments are sent to your cloud.
3. What your cloud provider can still see
Encryption protects the contents of your notes, not the fact that they exist. With sync on, the provider you chose can observe, from the shape of the stored files alone:
- How many notes you have, and how many notebooks.
- The approximate size of each file, including each attachment individually — which reveals which notes contain images or media, and roughly how much.
- When each file was last modified.
- Which note changed, and when. Each note is stored as its own folder, so an observer watching over time gets a per-note activity timeline: which document you worked on, on which days, and for how long a stretch. This is the item people most often miss, and it is the one that says the most about you.
- That a folder structure exists. Names do not reveal titles: each note is a folder named by a random identifier, and file names are fixed structural names. Note titles, notebook names, and tags are inside the encrypted metadata.
- When you created the vault. The header carries a plaintext creation timestamp alongside the KDF parameters. It is the smallest item on this list, and it is here because the list is meant to be complete rather than flattering.
This is inherent to file-based end-to-end encrypted sync, not specific to Soix Notes. Any design that stores one encrypted file per item has the same shape. Designs that hide it exist, and they hide it by sending everything to a server of their own and padding or batching it there — which removes the metadata from your cloud provider by giving it to that server instead.
Keeping the vault local only avoids all of it. The app is fully usable with no cloud connection, and sync stays off until you turn it on.
4. Who can do what
| Position | Can read your notes? | Can learn | Can do |
|---|---|---|---|
| Your cloud provider (or anyone who reads the stored files) | No | Everything in §3 | Delete or withhold files; roll back to an older copy. Cannot forge a note — the AEAD tags and header HMAC would fail. |
| Someone who compromises your cloud account | Not without your passphrase or recovery mnemonic | Everything in §3 | The above, plus take the vault header away and attack your passphrase offline (§5). |
| Someone with your machine while the vault is unlocked | Yes | Everything | Everything you can. Encryption at rest does not help here. Lock the vault, and lock your computer. |
| Someone with your machine while the vault is locked | Not without your passphrase or recovery mnemonic | File count, sizes, timestamps — the same shape as §3, locally | Offline attack on your passphrase (§5). |
| A tampered or malicious build | Yes, if you run it | Everything | This is the real residual risk of closed source. See §6. |
| Me, the developer | No, unless you send me something | Nothing. I receive no data; there is no server to receive it. | Ship a future version that behaves differently. See §6. |
Two things this table is deliberate about. Local disk encryption is not claimed: the vault file is encrypted, but an attacker with your unlocked session does not need the vault file. And an attacker who can withhold or roll back your cloud files can cause you to lose recent work — integrity protection stops forgery, not deletion. Keep a backup that is not the sync copy.
5. The passphrase is the whole thing
The vault header is uploaded to your cloud. It contains the KDF salt, the KDF parameters, the MEK wrapped under your passphrase-derived key, and a second copy of the same MEK wrapped under your recovery key (§2).
Anyone who obtains that header can attack your passphrase offline, at their own pace, on their own hardware, with no rate limit from me and no way for you to notice.
Each guess costs one Argon2id evaluation at 64 MiB, t=3, p=4. What that buys depends entirely on your passphrase, so here is the whole grid. Columns are guesses per second, so this table does not go stale as hardware improves — what changes is how much hardware a column costs. Times are for an average hit, half the keyspace.
| Passphrase | 103 /s | 105 /s | 107 /s |
|---|---|---|---|
| Reused, and in a breach corpus | instant | instant | instant |
| Human-chosen, 8–10 characters | ~6 days | ~2 hours | ~1 minute |
| 4 random words | 60,000 years | 600 years | 6 years |
| 5 random words | 440M years | 4M years | 44,000 years |
| 6 random words | beyond reach | beyond reach | beyond reach |
To anchor the columns as of September 2026: each guess has to move about 192 MiB through memory (three passes over 64 MiB), so an attacker's rate is capped by memory bandwidth, not by clock speed. One high-end consumer GPU of this era — roughly 1 TB/s — lands near the 103 column in practice. The 105 column is a rack of about a hundred of them. The 107 column is a state.
The KDF is doing real work: on that same GPU, a single round of SHA-256 runs about ten million times faster. In entropy terms these settings are worth roughly 24 bits — about two random words, handed to you for free. What they cannot do is manufacture the other fifty. Every order of magnitude in this table beyond that comes from your passphrase, not from me.
Five random words, generated rather than invented, puts your vault out of reach of anyone who is not a state, and keeps it there for longer than these ciphers are likely to last. Four is defensible today and thinning. Anything you thought of yourself is in the top two rows.
This is not a peculiarity of Soix Notes. Every design that puts an encrypted container on storage you do not control has this property, including KeePass databases on a cloud drive and Cryptomator vaults.
What follows from it:
- Use a long passphrase, generated or a multi-word phrase. Length beats complexity.
- Never reuse it. Reuse turns any unrelated breach into a breach of your notes.
- Store the recovery mnemonic offline, on paper or in a password manager. It wraps the same master key, so it is a second full-strength key to your vault. Do not put it in the cloud folder you sync to, and do not store it in Soix Notes — a recovery key inside the thing it recovers is not a recovery key.
6. Why trust a closed-source app
The honest answer is not "trust me". It is that the design is arranged so there is less you need to trust me about, and that the parts you cannot check are bounded.
What you can check without source code, in descending order of strength:
- No Soix server — testable with a network monitor, and falsifiable (§1).
- Your notes are ordinary files in a folder you chose, and any notebook can be exported to open formats readable without a Soix tool (§1). You are not locked in, and you do not need my cooperation to leave.
- The app works fully offline. A product that phones home for permission cannot do this.
- Distribution is through the Microsoft Store. The package is signed by Microsoft, its declared capabilities are enforced by Windows, and the package contents can be unpacked and inspected by anyone who wants to check what ships in it.
What you cannot check, stated plainly: you cannot confirm that the binary you run implements the design described here. There is no reproducible build and no published source. If I am lying in this document, or if I ship a future version that quietly changes behaviour, nothing here would stop it.
What limits that risk is the shape of the failure, not a promise. There is no server continuously receiving data, so there is no channel for a slow, silent exfiltration that you would never notice — outbound traffic to anywhere other than your own cloud is visible to anyone who looks. And because your notes stay as files you control and can export, the worst case is a compromise you can detect and walk away from, not a dataset already sitting on someone else's infrastructure.
That is a real limitation, not a resolved one. If auditable source is a requirement for you, it is a requirement this product does not meet, and an open-source alternative is the right choice.
7. How this compares
The point of this section is that the metadata exposure in §3 is a property of the design category, not a defect unique to this product.
| Design | Whose server sees your metadata | Works with no account | Encrypted content |
|---|---|---|---|
| Soix Notes — encrypted files on a cloud you own | The cloud provider you chose | Yes | Yes |
| Cryptomator, or a KeePass database on a cloud drive | The cloud provider you chose | Yes | Yes |
| Server-based end-to-end encrypted notes (Standard Notes, Joplin with E2EE on its own sync target) | That product's server | No | Yes |
| Mainstream cloud notes (Evernote, OneNote, Notion) | That product's server | No | No — the provider can read note contents |
Reading the table: moving the metadata off your cloud provider generally means moving it onto someone else's server, along with an account. This product's choice is to have no server at all and accept that the provider you already trust with your files can see file-shaped metadata.
8. Reporting a security problem
Email support@soix.app. Do not open a public issue for anything security-sensitive, and never attach real vault files, archives, or recovery material.
9. When this document has to change
The claims above are tied to a specific implementation. If the key derivation, cipher, remote layout, or what gets uploaded changes, this document is re-verified against the code before the release ships, not after. A threat model that has drifted from the implementation is worse than none, because readers will have tested the old version and found it honest.
Document history
| Date | Change |
|---|---|
| 2026-09-17 | First published. Relative to the internal draft of 09-15: §5 gained the offline attack difficulty table and the note that the header also carries a recovery-wrapped copy of the master key; §2 gained the statement that changing your passphrase does not invalidate the recovery mnemonic; and §3 gained item 6, the plaintext vault creation timestamp. |