Home / Articles / The passkey opens the vault / Versions / v1.3.0
The passkey opens the vault: what changed in v1.3.0
From v1.2.0 (2026-10-11, f5bb932d6) to v1.3.0 (2026-10-11, 421ac0a12), paragraph by paragraph.
41 paragraphs added, 23 removed, 26 changed in place, 35 unchanged. About 3,002 words added and 1,356 removed. Insertions are marked like this, deletions like this; unchanged runs are folded to one line; figures appear as their file names.
← v1.2.0 · all versions · v1.4.0 →
# The passkey opens the vault: toucha top vault computed from a passkey, vaults all the way down, and a master vault for every user, with no server of ours, no account and no emailours
Summary: The missing piece of the client-side puzzle is a user who can open their own vaults on any device, in a few seconds, with nothing to remember and nothing to sign up for. This is the design.design, revised after a review of its first version. A passkey, through the WebAuthn PRF extension, gives the browser 32 bytes that only your authenticator can produce for this site, and from those bytes the browser computes the key of a small door vault, which holdsand the keyid of your mastertop vault,vault. whichThe top vault is the root of a chain we already use everywhere, vaults that hold the keys of other vaults: it holds the keys of everythingyour else,reading startingvault withand your newsroomnotes vault. There is no sign-in:vault, the pageread makeskeys you have been given, your access key, and usesyour key pairs for this site, which are generated at random and never derived from the passkey, because the passkey throughis thea browser'slock, ownnot API,an with no Google app, no OAuth and no server, and it never learns your email or your name.identity. The question I could not answer, where the encrypted vaulttop key is stored, has athe simpleanswer answer:nowhere: nowhere.it sgitis computed, and the only stored secret is the one inside the passkey, kept by whichever store you were already signed in to, Google, Apple or Microsoft, which is why the vault keystravels arewherever madethat instore does. Several passkeys give several tops, an admin and a reader, with the client,provider's soown picker as the door'sswitch; a key moves between tops by copying, and a top is retired by deleting its idvault, canafter be computed fromwhich the passkey onopens any device, before anything is fetched, and there is no chicken and egg. A recovery code makes a second door to the same master. PRF is now supported by Google Password Manager, iCloud Keychain, Windows Hello and Firefox. The unlock costs up to six key derivations, measured.nothing. The first part is the technical design and the brief for the MVP on newsroom.sgit.ai, end to end;newsroom.sgit.ai; the second is what it enables: accounts with no server and no identity,enables for thisevery other site andwe for any other.run.
!shot pk-chain.webp | images/ | The key chain. The passkey's PRF output derives a door vault,computes the doortop holdsvault's key and id; the master vault's key, and the mastertop holds the keys of everythingthe else.vaults below it and the person's key pairs; the vaults below hold the data. Nothing secret is stored anywhere to be fetched, and the vault server sees ciphertext at every step.
This is the missing piece of the puzzle. In I miss it, so it is working I described the feature I miss: the newsroom on every device, in sync, through my own encrypted vault. In No server, by design I listed identity as one of the last things that still seemed to need a server. This article joins the two, in detail. It is the second version: the first had a vault too many in the chain and a sign-in that was not needed, and a review took both out. What changed is listed at the end.
1 unchanged paragraph
I had one question I could not answer: where is the top vault key kept? The short answer, after the research, is that it is not kept anywhere. It is computed. The rest of this article is why that works, the design end to end, and what it makes possible for every other site we run.
1 unchanged paragraph, under In short {#short}
• No sign-in, no account, no email. The page makes and uses the passkey itself, through the browser's WebAuthn API: no Google app, no OAuth loop, no server. The reader's passkey provider syncs it between their devices; the site never learns who they are.
• That is a privacy feature, with a price. We cannot email the reader, and there is no "forgot password": recovery is the recovery code and a second passkey. A purchase has no identity to hang on. I think it is the right trade.
• You are already signed in, somewhere else. On a Mac you are signed in to Apple, in Chrome to Google, on Windows to Microsoft, and that is where your passkeys live. The site does not need you to sign in to it. It asks the passkey store you already use, and the vault goes wherever that store goes.
1 unchanged paragraph
• Where is the vault key stored? Nowhere. sgit vault keys are made in the client, a passphrase and a vault id. So the browser computes a door vault's key and id from the PRF bytes, opens it, and finds the master vault's key inside. No chicken and egg, no new storage, only vault APIs.
• One master vault per user. It holds the keys of your other vaults (the newsroom vault first), your access key, your key pair and the list of your doors.
• Every passkey is a door, and so is a recovery code. An iPhone and a Windows laptop with different passkeys get two doors to the same master. A 128-bit recovery code, shown once, is a third. Lose them all and no one, including us, can open it.
• Support is good enough to build on, and where the passkey lives decides what the reader gets. PRF works in Google Password Manager, iCloud Keychain (Safari 18 and macOS 15), Windows Hello (since February 2026) and Firefox. A synced provider or a hardware key gives the same newsroom on every device; a clean browser with neither gives one device plus the recovery code, and Chrome's own store returns no PRF bytes at all, so the page checks at creation and offers a ladder of alternatives.
• Where is the top key stored? Nowhere. sgit vault keys are made in the client, a passphrase and a vault id. So the browser computes the top vault's key and id from the PRF bytes, opens it, and finds every other key inside. No chicken and egg, no new storage, only vault APIs.
• The top vault is a keyring, and the pattern is one we already use. Vaults that hold the keys of other vaults, all the way down. The top holds the keys of your reading vault and your notes vault, the read keys you have been given, your access key, and your key pairs for this site.
• The passkey is a lock, not an identity. The key pairs are generated at random and stored in the top, never derived from the passkey. Change the lock and the identity is untouched.
• Several passkeys, several tops. An admin passkey on a hardware key and a reader passkey in the cloud open two different tops, chosen in the provider's own picker. Keys move between tops by copying; a top is retired by deleting its vault, after which its passkey opens nothing.
• Recovery is the top key itself, shown once and saved in a password manager. Lose the passkey and the saved key, and no one, including us, can open the vaults.
• Support is good enough to build on, and where the passkey lives decides what the reader gets. PRF works in Google Password Manager, iCloud Keychain, Windows Hello and Firefox. A synced provider or a hardware key gives the same newsroom on every device; a clean browser with neither gives one device, and Chrome's own store returns no PRF bytes at all, so the page checks at creation and offers a ladder of alternatives.
5 unchanged paragraphs, under Part one: the design {#design}
| Piece | What it gives the page | What it does not give | |---|---|---| | Sign in with Google (later, optional, on its own origin) | Continuity: a stable account id for support, a Drive backup, a reference for purchases | Any key. It is not in the MVP and not needed to open anything | | A passkey for this site | A gesture (touch, face, PIN), a signature, and with PRF, 32 bytes computed from a secret the authenticator keeps for this site and this passkey | The bytes to anyone but the page on this site that asked, after the gesture | | The passkey provider | Sync: Google Password Manager across your Chrome and Android devices, iCloud Keychain across your Apple devices, or none (a hardware key) | Anything about what the bytes are for | | sgit | Vault keys made in the client (a 24-character passphrase and an 8-character vault id), read and write keys derived from them, ciphertext on the server | A way to find a vault you have no key for | | The access key | The right to create vaults and write to them on the vault server, the thing people will buy | Any way to read a vault |
One clarification that matters. What people call "the Google passkey" is a passkey for this site, registered by this page under this site's name, which your provider stores and syncs: Google Password Manager if you use Chrome, iCloud Keychain on Apple devices. It is not the passkey you use to sign in to Google, and a website cannot get PRF bytes from that one. There is no sign-in in this flow at all: the page registers a discoverable credential with a random user handle, and the only login involved is the one you already have with your passkey provider, which syncs it. The site learns a credential id, a public key and, after your gesture, 32 bytes. Not your email, not your name, not which account syncs it.
### Where the vault key lives: nowhere {#where}
[figure pk-options.webp] The places the key could live, and how you would find each before you could open it. Deriving the door from the passkey needs nothing to be found; the stored options become backups.
Every option for storing an encrypted vault key has the same problem: you have to find the encrypted key before you can open it, so it has to live somewhere you can reach with only what you have at that moment, which is your Google sign-in and your passkey.
| Piece | What it gives the page | What it does not give | |---|---|---| | The account you are already signed in to (Apple, Google, Microsoft) | Nothing, directly. It is what syncs your passkey store between your devices, so the passkey you make on one device is on the others | Anything to the site: not your name, not your email, not that you have an account | | A passkey for this site | A gesture (touch, face, PIN), a signature, and with PRF, 32 bytes computed from a secret the authenticator keeps for this site and this passkey | The bytes to anyone but the page on this site that asked, after the gesture | | The passkey store | Where the passkey lives: Google Password Manager, iCloud Keychain, Windows Hello, a hardware key, or the browser's own profile | Anything about what the bytes are for | | sgit | Vault keys made in the client (a 24-character passphrase and an 8-character vault id), read and write keys derived from them, ciphertext on the server, and a way to delete a vault | A way to find a vault you have no key for | | The access key | The right to create vaults and write to them on the vault server, the thing people will buy | Any way to read a vault |
One clarification that matters. What people call "the Google passkey" is a passkey for this site, registered by this page under this site's name, which your store keeps and syncs: Google Password Manager if you use Chrome, iCloud Keychain on Apple devices. It is not the passkey you use to sign in to Google, and a website cannot get PRF bytes from that one. There is no sign-in to the site at all: the page registers a discoverable credential with a user handle it chose, and the only login involved is the one you already have with your platform, which syncs the store. The site learns a credential id, a public key and, after your gesture, 32 bytes. Not your email, not your name, not which account syncs it.
That is also why the vault travels. If you are signed in to Apple on your iPhone, your iPad and your Mac, the passkey you make on one is on the others, and so is the vault it opens. If you make it in a clean browser with no store signed in, it stays on that device, which also works, for that device. The choice of store is the choice of where the vault goes, and the reader made it long before they met this site.
### Where the top key lives: nowhere {#where}
[figure pk-options.webp] The places the key could live, and how you would find each before you could open it. Deriving the top vault from the passkey needs nothing to be found; the stored options become backups.
Every option for storing an encrypted vault key has the same problem: you have to find the encrypted key before you can open it, so it has to live somewhere you can reach with only what you have at that moment, which is your passkey.
2 unchanged paragraphs
• GoogleA Drive's app-data folder: this is the "application data" I had in mind. It is a private, hiddencloud folder per app in the user's own Drive,account, reachedsuch with the as Google drive.appdata scope, whichlistsDrive's asapp-data recommendedfolder: and non-sensitive. Itit works from the browser, with the user present for each token.token, Itand it needs Googlea sign-in,sign-in to that account, which thethis MVPdesign does not have,have. and it only helps if what it holds is wrapped under something other than the passkey: wrapped under the recovery code,If it is aever secondused, copyit is an availability backup of thean recoveryencrypted door, useful if the vault server loses data, and no help for a lost key. A later availability backup,copy, not the main path.
2 unchanged paragraphs
And then the option that needs none of it. sgit vault keys are generated in the client: a random passphrase and a random vault id, and sgit init accepts a key it is given. So instead of generating athe doortop vault's key at random and storing it, the browser computes it from the PRF bytes: the passphrase, and the vault id, with HKDF. On any device where the passkey is available, the same gesture gives the same bytes, the same door id and the same door key. The browser knows where to look and how to open it before it has fetched anything. The door holds one thing, the master vault's key, which is random and made once. The master holds everything else.
SoIn the answerfirst toversion myof question:this design, the computed vault was a "door" that held the key of a separate master vault. The review asked where the requirement for that extra step was, and in our case it is not stored,there. The computed vault is the top of the chain. What it holds is derived; the master key is stored, inside a vault that only the passkey can find; and Google's app-data folder can keep a backup copy, encrypted, for the day something goes wrong.keyring.
2 unchanged paragraphs
1. The PRF input is a fixed, public value: SHA-256("newsroom.sgit.ai/door/v1").SHA-256("newsroom.sgit.ai/top/v1"). An input is not a secret; only the authenticator can turn it into the 32 bytes.
2. The door seed is HKDF-SHA256(ikm = PRF bytes, salt = SHA-256("newsroom.sgit.ai"), info = ."sgit/top/v1")"sgit/door/v1").
3. The door's passphrase and the vault id are two more HKDF outputs from the seed. sgit accepts any printable ASCII passphrase up to 256 characters, so the passphrase is the hex of 32 bytes (info = ".../passphrase"), keeping all 256 bits. The vault id has to be lowercase letters and digits, 4 to 24 of them, so 8 characters are drawn from a third output (info = ".../id") with rejection sampling, so that no character is favoured.
4. The .../top/persona/v1`. Two inputs give two unrelated outputs and two tops. That separates what is in doortop vault key is the sgit vault key made of those two, and from there, sgit's own derivation gives the read and write keys, exactly as the command line does: PBKDF2-HMAC-SHA256 at 600,000 iterations, once for the read key and once for the write key. That is the cost of this design. Door,The mastertop and newsroomthe reading vault need up to sixfour derivations; measured in headless Chromium on a four-core machine, one takes about 105 ms and six run together about 640 ms, and a phone is several times slower, so a cold unlock can spend a second or two to four seconds deriving keys before it fetches anything. The brief measures it on a phone, derives each vault's keys once per session, runs them in a worker, and derives a write key only when there is something to write.
5. TheA recoverysecond doorcompartment from the same passkey is the same,same derivation with thea recoverydifferent codeinput, say placememory ofat once; it does not separate authority, because whoever can use the PRFpasskey bytes:gets 26both. charactersAuthority ofis base32, 128 bits, madeseparated by thea pagesecond andpasskey, shown once. It is long so that it needs no password stretching, as in the secrets.sgit.ai keyring design.below.
6. Collisions are not a practical worry with 36⁸ possible ids, but the page checks: a derived id that already holds something it cannot open is skipped, with a counter in the HKDF info.
1 unchanged paragraph
### What is in each vault {#layout}
• A door vault: one file, the master vault's key, and what kind of door it is (which passkey, or the recovery code).
• The master vault: the keys of your other vaults, by site; your access key; your key pair (the public key in the clear, the private key as a JWK); the list of your doors, so a lost passkey's door can be retired; and your Google account id, so the page can tell you if you have signed in as someone else.
• The newsroom vault: one log per device, appended, never edited: pages read and how far, ratings, personas, the reading list, notes, receipts by payment reference. Every device computes the same state from all the logs, as described in I miss it.
### What is in the top vault {#layout}
The top is a keyring: one small file of named entries, rarely written, and nothing else. The pattern is the one we already use everywhere, vaults that hold the keys of other vaults, so the only new thing here is where the top key comes from.
• The keys of the vaults below it, by site and purpose: the reading vault first, then the notes-to-the-agent vault, then whatever an agent creates for the reader. Each is an ordinary vault with its own random key, so a read key to one of them can be handed to an agent or a person without exposing anything above it. Depth is the blast radius control.
• Read keys the reader has been given, to vaults that belong to someone else.
• The access key. A read-only clone needs no token, so after the unlock the browser reads the top with nothing but the derived read key, and finds the access key inside. The reader pastes it once, on the first device; every other device gets it from the top.
• The key pairs for this site. At least a signing pair and an encryption pair, as RFC 0001 separates them, and plausibly one per persona, so that what the CISO persona signs is not linkable to what the personal one signs. Each entry has a label, a purpose, a created date and a status. The public halves are published wherever the newsroom and the agent need them.
The key pairs are generated at random and stored. They are never derived from the passkey, and this is a decision, not an omission. A derived key pair cannot be rotated without changing the passkey, and you want several of them. More important, the passkey is a lock, not an identity: it opens the top and does nothing else. Everything that represents the person survives any change of lock, a new passkey, a second one, a hardware key, a recovery, a derivation bump. Rotate a lock and the identity is untouched; rotate an identity and the locks do not care. The trade-off against a non-extractable Web Crypto key is real and worth stating: a non-extractable key is stronger on one device, but it is one device, and an identity that has to be the same on the phone, the iPad and the iMac has to travel. An encrypted vault that only the passkey opens is the right vehicle for it. The private keys exist in browser memory only while the top is open.
Below the top, the reading vault holds one log per device, appended, never edited: pages read and how far, ratings, personas, the reading list, notes, receipts by payment reference. Every device computes the same state from all the logs, as described in I miss it.
### Several passkeys, several tops {#several}
A site can hold any number of passkeys for one person. Each passkey has its own PRF secret, so each computes its own top, and two passkeys are two independent trees. The facts that make this work, and the one that trips people up:
• The store dedupes by user handle. When a passkey is created, the site gives it a user id and a display name. iCloud Keychain and Google Password Manager treat a new passkey with the same user id for the same site as a replacement for the old one. So two passkeys that must coexist get two user ids and two names, "Dinis · admin" and "Dinis · reader". That is the whole trick.
• The picker is the switch. When the page asks for an assertion without naming a credential, the store shows its own sheet listing the passkeys it holds for this site, and the person picks one. That sheet is the interface for choosing which top to open; we do not build it. If the page remembers a credential id and a label in local storage, which are not secret, it can offer "Unlock admin" and ask for that passkey by id, with the sheet as the fallback.
• Two stores in one browser. In Chrome on a Mac the sheet offers both iCloud Keychain and Google Password Manager, plus a phone by QR and a hardware key, so one person can have a reader passkey in one store and an admin passkey in the other and switch between them on the same site in the same browser. Safari offers iCloud Keychain, hardware keys and a phone, not Google's store. Which of those paths returns PRF bytes in which browser is the thing the brief tests on a real machine rather than takes from a table.
The scenario this is for is separation of authority. An admin top holds what the desk needs: access keys, the write side of the newsroom's vaults, the publishing key pair. A reader top holds the reading vault, the notes vault and the persona key pairs. The admin passkey lives on a hardware key in a drawer, or in a different store from the reader one, so that the keys that can publish are not available every time the keys that can read are. The page shows which top is open, with a lock button that clears memory, and opens one top per tab by default.
Moving keys between tops. A top is a small file of entries, so a move is: unlock A, copy the entry into B, delete it from A. The catch is history. Vaults keep their versions, so an entry deleted from A is still in A's past for anyone who can open A. The rule: keys that move for security reasons get rotated, which for a vault key means sgit rekey, a new vault with a new id and the content re-pushed, and the references in every top updated; keys that move for tidiness do not; and a top being deleted takes its history with it.
Retiring a top. sgit can delete a vault from the server, sgit vault delete-on-remote, which needs the write key and a typed confirmation, and the vault's own files are gone. So the order is: move or rotate what the top held; delete the top's vault with its write key; delete the saved copy of its key from the password manager; then delete the passkey in the store's own settings, because a site cannot delete a passkey, only the person can. The coupling runs both ways and is worth noticing. Once the vault is deleted, the passkey still computes the same key, and the key opens nothing: a passkey whose vault is gone is inert. And once the passkey is deleted, the vault's ciphertext, if any survived, has no key. Deleting either side retires the pair. That is another reason to compute the top from the passkey rather than store its key: the lifecycle of the key is the lifecycle of the vault.
Changing the derivation is the same operation as adding a passkey: a new input gives a new top from the same passkey, the entries are copied across, the old top is retired. Nothing below the top moves.
1 unchanged paragraph
!shot pk-flows.webp | images/ | The first run, a new device, and addinga second passkey, a passkeymove orand recovering.a retirement. Every step runs in the browser, against the user's passkey providerstore for the gesture, and the vault server for ciphertext.
First run. Create a passkey for the site with prf enabled;enabled, named for its role; if the authenticator cannot do PRF, the page says which kinds can and offers another. Touch it: the PRF bytes give the door. Generate the master key, the newsroom vault key, a key pair and a recovery code.top. Paste the access key. CreateGenerate the door,reading thevault's master, the newsroom vaultkey and the recoverykey door.pairs. Create the top and the reading vault. Move the reading account from the browser's storage into the newsroomreading vault. Show the recoverytop codevault key once, behind "I have writtensaved it down".in my password manager".
A new device. Touch the passkey, synced to this device or used from a phone by QR. The PRF bytes give the same door,top, the doortop gives the master, the master gives the newsroomreading vault. Reading needs no access key; the access key comes out of the master,top, so this device can write as well. Merge this browser's reading into its own log.
A second provider.passkey.** AnCreate iPhoneit with iClouda Keychaindifferent user handle and aname, Windowsin laptopanother withstore Windows Hello have different passkeys. While unlockedor on one,a registerhardware key. It computes its own top. Copy into it the other:entries itsit PRFshould byteshold, makeand anothing second door to the same master.else.
Lost a passkey. TypePaste the recoverysaved code;top itvault deriveskey; the recoverytop door;opens; registercreate a new passkey;passkey, which computes a new top; copy the entries across; retire the old doortop in the master'sorder list.above.
Signing out and locking. Keys exist only in the page's memory: cleared on sign-out,lock, after a period of inactivity, and when the page is closed. The browser's own copy of the reading account stays as it is today.
1 unchanged paragraph
• What each party sees. The vault server: ciphertext, sizes, times and ids that look random. Google: nothing, in the MVP. Your passkey provider: that a credential exists for this site. Only this page, in your browser, after your gesture, holds the PRF bytes and the keys.
• The origin loads no third-party scripts, on any page. Storage is per origin, so a script on a sign-in page could read what the account page keeps. If sign-in with Google is added later, it runs on an origin of its own and hands back an account id; the newsroom's pages load only code from the reader repository, with the vault code vendored into it rather than loaded from the vault web app or tools.sgraph.ai.
• What each party sees. The vault server: ciphertext, sizes, times and ids that look random. Your platform account: that a passkey exists for this site, under the name you gave it, and a secret it never sees used. Not which key pairs exist, not what they signed, not which personas they belong to. Only this page, in your browser, after your gesture, holds the PRF bytes and the keys.
• Whoever can use the passkey can reach everything below its top. That is exactly the passkey's protection, the biometric, the device and the store, and nothing in our stack adds to it or weakens it. A second passkey for the admin top is how the reach is split.
• The origin loads no third-party scripts, on any page. Storage is per origin, so a script on any page of the site could read what the account page keeps. The newsroom's pages load only code from the reader repository, with the vault code vendored into it rather than loaded from the vault web app or tools.sgraph.ai.
2 unchanged paragraphs
• Losing everything is final. Every passkey and the recoverysaved codekey gone means no one can open the vaults. That is the property that makes the design worth having, and the first run says so before it shows the code.key.
• Availability is not secrecy. The vault server could delete or roll back ciphertext. It cannot read it. The local copy and the Drive backup covercovers the first; nothing is needed for the second.
• Agents do not have passkeys. An agent that should read part of a user's data gets a read key for one vault, given by the user from the master,top, never the mastertop itself.
3 unchanged paragraphs
The page checks prf.enabled when it creates the passkey, and never guesses: if it is false, it says so and offers another authenticator or the recovery code.authenticator.
3 unchanged paragraphs
| Where the passkey lives | Needs | Travels? | PRF | What the reader gets |
|---|---|---|---|---|
| Google Password Manager (Chrome signed in, Android) | A Google account | Yes, to every device signed in to it | Yes | The same newsroom everywhere |
| iCloud Keychain (Safari, iPhone, iPad, Mac) | An Apple ID | Yes, across Apple devices | Yes, Safari 18 and macOS 15 | The same newsroom on every Apple device |
| Windows Hello (Windows 11) | The device; a Microsoft account to sync | Device-bound, unless synced | Yes, since February 2026 | This PC, or every PC on the account |
| A hardware key (YubiKey and others) | The key, and its PIN | Yes, wherever the key is plugged in | Yes, through hmac-secret; not with YubiKeys in Safari | No account anywhere; a few dozen passkeys per key |
| Your phone, by QR (the hybrid flow) | A passkey on the phone, in its own providerstore | Yes, one scan at a time | Where the phone's providerstore does | A clean laptop opens with the phone beside it |
| Chrome's own profile store (a clean Chrome, no provider)store signed in) | Nothing | No: this browser, on this computer | No, in 2026 tests | Signs, returns no bytes: the doortop cannot be derived |
So the rule, in one line: the same newsroom on every device needs a synced providerstore or a hardware key in your pocket. A clean browser with neither gives you this device, plus the recoverysaved code.key. A passkey made there still works, as a passkey; it is stored by the device, tied to that browser profile on that computer, and deleted with it. The catch for this design is the last row: Chrome's own store, used when there is no provider (a clean Chrome on Linux, or on a Mac with iCloud Keychain off), signs but returns no PRF bytes in 2026 tests, so the doortop cannot be derived there at all.
Two things follow. The page learns which case it is in at creation, from prf.enabled, and never guesses. And when PRF is off, it offers a ladder, in this order: sign in to a provider,store, so the passkey syncs from now on; use your phone by QR, one scan at a time; plug in a hardware key; or stay on this device, where the browser's own copy keeps working and the recoverysaved codekey is the way back. That is a real limitation of PRF today, not of the design, and the article would be dishonest without it. One caveat on the Chrome-profile row: it comes from a vendor's published tests, so the brief includes a five-minute check on a clean profile before anyone depends on it.
1 unchanged paragraph
*For the session that runs newsroom.sgit.ai. Written by the sgit.ai site session for Dinis Cruz, 11 October 2026.2026, and revised the same day. Dinis decides what ships, and is the first user.*
1. NoSigned sign-in.in where you already are. The first screen is the passkey.passkey, Googleand the page says in one line that the passkey lives in the store you already use and goes where it goes. No sign-in isto athe latersite, phase,no onOAuth, itsno ownemail, origin,in andthe onlyMVP foror whatin itthe is good for: continuity for support, a Drive backup, a reference for purchases.plan.
2. The passkey: create with rp.id = newsroom.sgit.ai, a resident key, user verification required, extensions.prf;extensions.prf, a user handle and display name chosen for the role; get with the fixed PRF input; check prf.enabled. When it is false, the ladder: sign in to a provider,store, your phone by QR, a hardware key, or this device only with the recovery code,only, each explained in one line.
3. The derivation in part one, with test vectors shared with the sgit command line.
4. The vaults: door,the master,top, newsroomcomputed, and recoverythe door,reading vault below it, created with the access key, using the browser code that already reads and writes vaults, taken from the vault web app and tools.sgraph.ai and vendored into the reader repository. The top holds the reading vault's key, the access key and the key pairs; nothing else goes in it.
5. The identity: generate a signing pair and an encryption pair at random on first run, store them in the top with a label, a purpose, a date and a status, and publish the public halves where the share page and the subscribe lane need them. Never derive a key pair from the passkey.
6. The move: the reading account from the browser's storage into the newsroomreading vault, as the first device's log.
6.7. The right-hand side: once open, show the vault:top: theits master'sentries listby of vaultsname and doors,purpose, and the newsroomreading vault's contents, so the user can see what is kept and where.where, with a lock button, and the name of the passkey that opened it.
7.8. Several passkeys: a second passkey with its own handle and name computes its own top; a move screen that is a copy with a sentence about history; a retire screen that walks the order in part one, deletes the vault with delete-on-remote, and ends by sending the person to their store's settings to delete the passkey.
9. Tests: Chromium's virtual authenticator with PRF in the build (secrets.sgit.ai found it works in Chromium 141); the first run, a new devicedevice, a second passkey and thea recovery code,retirement, end to end; a clean Chrome profile with no provider,store, to confirm what its own store returns for prf.enabled and that the ladder appears; two stores in one Chrome on a Mac, to confirm which return PRF bytes; two devices editing offline and agreeing; a synthetic reader who has never heard of a vault key.
8.10. Not in the MVP: Googleany sign-in,sign-in to the Drivesite, a cloud backup, sharing across sites, anything on a server of ours.
2 unchanged paragraphs, under Part two: what this enables {#enables}
Once these dots are connected, we have something we did not have before: an end-to-end path from a login with a second factorgesture to a vault, entirely in the browser, on commodity pieces. And just about every site and project we build needs exactly that.
2 unchanged paragraphs
• One master, many vaults. The newsroom vault is the first. The same master can hold the key to secrets.sgit.ai's keyring, a RiskMandate customer's policies, the memory of an agent the user runs, or the notes a reader sends to the newsroom.
• Sharing without shared secrets. The key pair in the master is what RFC 0001 needs: give someone a vault key by encrypting it to their public key, with no secret sent in a chat.
• One account across sites. Two ways, later. A key hub, such as secrets.sgit.ai, holds the master and hands a site only the key to its own vault, after the user approves it in a pop-up, the way a wallet connects to a site. Or, across different domains, WebAuthn's Related Origin Requests let one passkey work on a list of related sites, in Chrome and Safari today.
• For anyone else. None of this is specific to us. Any static site, on any host, could use Google sign-in, a passkey with PRF and a vault, and give its users the same thing. I would like it to become a small, open component, the way SG Meter is for reading.
• One top, many vaults. The reading vault is the first. The same top can hold the key to secrets.sgit.ai's keyring, a RiskMandate customer's policies, the memory of an agent the user runs, or the notes a reader sends to the newsroom.
• Sharing without shared secrets. The key pairs in the top are what RFC 0001 needs: give someone a vault key by encrypting it to their public key, with no secret sent in a chat.
• One account across sites. Two ways, later. A key hub, such as secrets.sgit.ai, holds the top and hands a site only the key to its own vault, after the user approves it in a pop-up, the way a wallet connects to a site. Or, across different domains, WebAuthn's Related Origin Requests let one passkey work on a list of related sites, in Chrome and Safari today.
• For anyone else. None of this is specific to us. Any static site, on any host, could use a passkey with PRF and a vault, and give its users the same thing. I would like it to become a small, open component, the way SG Meter is for reading.
If a site ever needs a stronger statement of who the user is, for a purchase that must be refunded to a person or a support case that must find them, a sign-in with Google or Apple can be added on an origin of its own, handing back an account id and nothing else. With no back end to hold that id, I am not sure we will ever need it, and the design does not depend on it.
3 unchanged paragraphs, under What this does not claim {#limits}
• The support table is a snapshot. It is from vendor documentation and published tests in 2026, and some of it, Firefox and Microsoft's own password manager in particular, is still moving.
• Deriving the door is a choice with a cost. A door is lost with its passkey; the recovery code and a second passkey are what cover it.
• The support table is a snapshot. It is from vendor documentation and published tests in 2026, and some of it, Firefox and Microsoft's own password manager in particular, is still moving. Which stores return PRF bytes inside which browser on a Mac is tested in the brief, not asserted here.
• Computing the top is a choice with a cost. A top is lost with its passkey; the saved key and a second passkey are what cover it.
• What changed from the first version. The door vault is gone: the computed vault is the top, and the master vault became its first child. Sign-in with Google is no longer a later phase of the design; it is a line at the end about something we may never need. The key pairs are stated to be random, not derived. Several passkeys, moves between tops and retiring a top are new, as is the role of sgit's delete.
2 unchanged paragraphs, under Where this comes from {#sources}
A voice memo of mine, recorded on 11 October 2026, asking for the design and for research into what a passkey gives a website and where an encrypted vault key could be kept;kept, and a review conversation the same day that removed the door vault and the sign-in and added several passkeys; written by this site's agent in the voice of this site. The argument and the editorial responsibility are mine. The design builds on secrets.sgit.ai's published design (how it works, the keyring format, passkeys, WebAuthn and PRF and keys), and on how sgit generates and parses vault keys in the client (generate_vault_key and parse_vault_keyparse_vault_key), indeletes a vault (sgit vault delete-on-remote) and rotates a key (sgit rekey), read from the sgit command line);line's source; the unlock cost was measured with WebCrypto PBKDF2 in headless Chromium on 11 October 2026. The research: Corbado, Passkeys and WebAuthn PRF for end-to-end encryption (2026) and WebAuthn L3 support in credential managers; Yubico, Developer's guide to PRF; Mozilla, support for the WebAuthn PRF extension; Chromium, intent to ship the PRF extension; web.dev, passkey reuse across sites with Related Origin Requests; Google, choosing Google Drive API scopes and authorising for the web.Requests](https://web.dev/articles/webauthn-related-origin-requests). Related articles: I miss it, so it is working, No server, by design, Where the vault keys live, RFC 0001 and How to run synthetic users.