Chromium's --use-mock-keychain does not switch cookie encryption off. It answers the request for the macOS keychain password with a fixed string written into Chromium's own source, and encrypts with that. Every cookie file made under the flag opens for anyone who has the file. We measured it on our own disk on 14 September 2026, and that measurement is why Mosaic seals its store and its cookie keys itself.
What the mock keychain does to cookie encryption
On a Mac, Chromium encrypts each cookie value before it writes it to the profile's Cookies database. The password normally lives in the login keychain, in an item called Chromium Safe Storage. Chromium stretches it with PBKDF2-HMAC-SHA1 (salt saltysalt, 1003 iterations) into an AES-128-CBC key, and every encrypted value starts with the tag v10.
--use-mock-keychain leaves all of that in place. The derivation runs, the format is the same, the v10 tag is still there. The only change is the password, which is now mock_password on every machine that passes the flag. Encrypted with a key everybody knows is, for a file on a disk, the same as not encrypted.
Why our engine launches with it anyway
The first time we started a finished build of Tesseract Chrome, our own Chromium, it wrote Local State and then did nothing: no window, no DevTools port, 0% CPU. sample on the process named the cause in three seconds. The main thread was inside SecItemCopyMatching, waiting for the keychain.
That build was ad-hoc signed, so macOS treated it as an application it had never seen and put the Safe Storage item behind an access dialog. The browser waited for the answer before it had a window to show. And every launcher bundle we made was a new code identity to the keychain, so "Always Allow" granted one launch and the next one asked again. On a machine running hundreds of profiles that is not a dialog anyone can live with.
So every launch carries --use-mock-keychain, with --password-store=basic beside it as the Linux equivalent. The flag solved the dialog. It also handed every profile's cookies the same public password, and we went and measured what that meant.
Your profiles, cookies and proxies stay on your computerIn Mosaic: Local first. Profiles, cookies and proxies stay on your computer. Free holds 3 profiles. Pro is $49 a month for any number.
Mosaic is a desktop app
Email yourself the link and open it on your computer.
What one command read off our own disk
One command, no special privileges, against a real profile on the development Mac:
DECRYPTED — password "mock_password", offset 32
.dev.to _Devto_Forem_Session = "bb0cbcf3b126b691797c6126a7f3ae48"
That is a live session cookie, read off the disk in about a second. Beside it, mosaic.json, the file that held every profile, was readable by any user on the machine and carried every proxy password in plain text.
Separation was never the problem. Each profile has its own data folder, and when we compared nineteen cookie jars on one machine there was no overlap between them. What the shared password cost was confidentiality at rest: a stolen laptop folder, a copied backup, a disk pulled from a dead machine. Mosaic keeps everything on the computer, as local-first describes, and that is only worth something if the computer is a safe place for it.
What we built instead
One data key, and everything sensitive sealed under it.
- The store.
mosaic.json, proxy credentials included, is sealed with AES-256-GCM and a fresh 12-byte nonce on every write, because the store is rewritten on every edit and a reused nonce is the one way to break GCM outright. - A cookie password per profile. It is derived from the data key and the profile's id, so there is no second secret to keep in step, and a profile removed from the store takes its key with it.
- A switch to hand it over. Patch
0139-embedder-cookie-keyadds--os-crypt-passwordto the engine. It is read before the keychain is touched, so a profile carrying its own key raises no dialog and never falls back to the constant. Chromium's derivation and itsv10format are unchanged, so the patch touches two files and nothing else in Chromium needs to know.
We changed it in C++ rather than in any script a page could see, for the same reason we move fingerprint values there (why C++ and not JavaScript has the longer argument).
What it does not protect
The password reaches the engine on its command line, where ps shows it to the user who started it. That trade is deliberate. The threat this fixes is a copied folder, and a command line is never written to disk. Code already running as you could read the key out of Mosaic's memory whatever we did, and we do not claim otherwise.
The data key itself has to be kept somewhere, and that is a separate choice. At the time of writing it sits in a file only your user can read by default, or is wrapped in a password if you turn on app lock in Settings › Security. A failed decrypt throws an error. It never falls back to an empty store, because a wrong key that looks like a first run would show you a library with no profiles in it.
We had already moved per-profile downloads out of the shared folder for a related reason: what a profile leaves on disk is evidence of that profile. The engine and the patch series behind it are in why we built our own Chromium.






