Home / Explanations, in context

Learn: the parts, explained in context

Status, from /shipped/: shipped v0.1.12 Learn pages: passkeys, WebAuthn and PRF; keys from PRF to plaintext; GCP from this site's side; each term defined once in data/terms.json and linked from its first use on every content page; flow diagrams drawn by the build as inline SVG with a text twin · shipped v0.1.12 The passkey lab on /learn/passkeys/: create lab passkeys in this browser under this host's RP ID, ask for PRF bytes, derive the wrapping key, wrap a lab KEK, encrypt a lab body, unlock again with the same or a second passkey, and watch what is stored where; headless in the build against Chromium's virtual authenticator with PRF · proposed Passkey with WebAuthn PRF derives the keyring wrapping key; RP ID secrets.sgit.ai

The design pages say what this site does. These pages say what the words mean, here, for this site, and nowhere more general than that: what a passkey is when it is the thing that unlocks your keyring, what the PRF bytes are, where each key comes from and goes, and what Google Cloud sees. Every term below is linked from the first place it appears on any page of the site, and the reader's column lists the terms a page uses.

The pages

PageAnswersTry it
Passkeys, WebAuthn and PRFWhat a passkey is and is not here; the two WebAuthn calls, drawn; what your authenticator, your browser, this site and Google each store; why one site, one RP ID; what happens with two passkeysThe passkey lab: create a lab passkey in this browser, ask it for PRF bytes, derive the wrapping key, wrap and unwrap a lab KEK, add a second passkey, and watch what is stored where
Keys: from PRF to plaintextIs there a passphrase (no); the PRF salt; HKDF; the wrapping keys; the KEK; AES-256-GCM; the recovery code and why it is long; what is in memory, whenThe lab's steps 3 and 4 run this chain on real WebCrypto, with the bytes shown
GCP, from this site's sideWhat the project is for; Identity Platform and the uid; the bucket and the Security Rules; Terraform and Workload Identity Federation; what Google sees and cannot seeThe admin checklist on /admin/, once a project exists (needs a human; see needs.md)

The glossary

One entry per term, in this site's context. The data is data/terms.json; the build links the first occurrence of each term on every content page and sets the definition as the link's hover text, so a definition is written once.

AES-256-GCM also: AES-GCM
The authenticated cipher the browser provides; every wrap and the body use it, so a wrong key or a tampered byte fails loudly instead of decrypting to garbage.
authenticator also: authenticators, platform authenticator
Whatever holds the passkey's private key and PRF secret: Google Password Manager, iCloud Keychain, Windows Hello or a hardware key; it never hands the secret out, only results computed with it.
bucket also: Cloud Storage, Cloud Storage for Firebase
The Cloud Storage bucket where users/{uid}/keyring.json and meta.json live, versioned, reachable from the browser directly with the login's token.
credential id also: credentialId, allowCredentials
The public identifier of one passkey, stored in meta.json so the page can list your devices and ask the authenticator for that passkey by name.
Firebase uid also: users/{uid}
The login's stable id for a user; it names the user's prefix in the bucket and appears in the rules, and it is not a secret.
GCP also: Google Cloud, GCP project
The Google Cloud project that holds the login and the bucket for one environment; it sees who signed in and stores ciphertext, and can open none of it.
gesture also: passkey gesture
The touch, face, PIN or tap your authenticator asks for before it computes anything; one gesture per unlock, and nothing happens without it.
HKDF also: HKDF-SHA256
The standard key-derivation function the browser provides; turns 32 PRF bytes (or the recovery code) plus a salt and a label into a wrapping key, deterministically.
Identity Platform also: Firebase Auth
Google's login service, used through the vendored Firebase Auth SDK; the login decides which bucket paths you may touch and nothing else.
KEK also: keyring key
The keyring's one real key: 32 random bytes that encrypt the body, themselves stored only wrapped, once per unlock method.
keyring also: keyring.json
The one encrypted file per user in the bucket: the PRF salt, the wrapped copies of the KEK, and the encrypted body with the entries; version 1 is specified on its own page.
meta.json
The small public file next to the keyring in the bucket: the user handle, each passkey's credential id, public key and name, and the keyring revision; nothing secret.
passkey also: passkeys
A WebAuthn credential your authenticator keeps and syncs; here it is the thing that unlocks your keyring, not a login.
passphrase also: master password
There is none. Nothing you type unlocks the keyring; the passkey's PRF output and the machine-made recovery code are the only unlock methods, by design.
PRF also: PRF extension, hmac-secret
The WebAuthn extension that makes the authenticator return 32 secret bytes for a given input, the same bytes every time for the same passkey, origin and input; those bytes are what derives the wrapping key.
PRF salt also: prfSalt, prf.eval
32 random public bytes fixed for the keyring's life, given to every passkey as the PRF input; stored in keyring.json in the clear, because it is an input, not a secret.
recovery code
26 characters of base32, 128 random bits, shown once at first run: the one unlock method that lives in your head or on paper, and the only way back in when every passkey is gone.
RP ID also: relying-party identifier, rpId
The host a passkey is scoped to; here exactly secrets.sgit.ai (localhost when testing), never sgit.ai, so no sibling site can ask for the gesture.
Security Rules also: storage.rules
The rules file Google enforces in front of the bucket: a signed-in user may read and write only their own prefix, with size limits; the whole access control of the MVP.
Terraform
The infrastructure description in infra/terraform/ that creates each environment's project, login, bucket and rules, applied by GitHub Actions; it can delete and reconfigure, and cannot read.
user handle also: user.id
The 32 random bytes a passkey is registered under; not your email and not the Firebase uid, so the authenticator learns nothing about the account.
WebAuthn
The browser API (navigator.credentials) that creates a passkey and later asks your authenticator to prove it still has it; the only API this site uses to talk to the authenticator.
Workload Identity Federation also: WIF
How GitHub Actions gets a GCP identity without a stored key: the pipeline presents its own token and GCP trusts it for this one repository and branch.
wrapping key also: WK, WK_passkey, WK_recovery
An AES key derived from one unlock method (a passkey's PRF output, or the recovery code) whose only job is to encrypt the KEK; a different one per passkey.

How these pages are made

The diagrams are drawn by the build from data/diagrams/ into the page as inline SVG that uses the theme's colours, with the same diagram as text underneath for copying and for the markdown twin; no library, no script. The lab is a web component in the house shape, components/passkey-lab/, and it talks to nothing but your authenticator: no Google, no bucket, no network. What it keeps in this browser is listed on its page, and the gate checks that list on every release.