Parked from M5. The passphrase-free way to unseal a device that rests under a passphrase-class seal.
Shape (from the archived design record, archive/v0:runtime/PERSISTENCE.md §"The PRF rung", rulings settled 2026-08-22 and still good): the user enrolls a passkey for the device; unsealing asserts it with the WebAuthn PRF extension; KEK = HKDF-SHA-256(PRF output, stored salt, info = version ‖ device id); the KEK wraps the DEK exactly as the passphrase rung does. Nothing at rest is guessable: the secret lives in the authenticator, which demands user presence + verification per ceremony.
Where it lands in the rebooted tree
internal.wit device.rest gains passkey; keep/unseal gain the passkey arm.
- The ceremony splits along capabilities like OAuth did:
navigator.credentials is a window capability → shell.passkey-enroll(rp-id, challenge) -> credential-id + transports + prf-output and shell.passkey-assert(credential-id, transports, prf-input) -> prf-output; the kernel owns the salts, HKDF, wrap/unwrap (pure Rust, hkdf + the existing AES-GCM/KW), the PrfWrap record beside dek-wrapped.
- Pin
userVerification: "required" at enrollment and every assert (hmac-secret keeps two per-credential secrets, with/without UV).
- e2e: Playwright's CDP virtual authenticator serves hmac-secret/PRF (the archive's spike measured it); scenario: keep with passkey → reload → sealed → assert → open.
Not this issue: recovery when the authenticator is gone (#167).
Parked from M5. The passphrase-free way to unseal a device that rests under a passphrase-class seal.
Shape (from the archived design record,
archive/v0:runtime/PERSISTENCE.md§"The PRF rung", rulings settled 2026-08-22 and still good): the user enrolls a passkey for the device; unsealing asserts it with the WebAuthn PRF extension; KEK = HKDF-SHA-256(PRF output, stored salt, info = version ‖ device id); the KEK wraps the DEK exactly as the passphrase rung does. Nothing at rest is guessable: the secret lives in the authenticator, which demands user presence + verification per ceremony.Where it lands in the rebooted tree
internal.witdevice.restgainspasskey;keep/unsealgain the passkey arm.navigator.credentialsis a window capability →shell.passkey-enroll(rp-id, challenge) -> credential-id + transports + prf-outputandshell.passkey-assert(credential-id, transports, prf-input) -> prf-output; the kernel owns the salts, HKDF, wrap/unwrap (pure Rust,hkdf+ the existing AES-GCM/KW), thePrfWraprecord besidedek-wrapped.userVerification: "required"at enrollment and every assert (hmac-secret keeps two per-credential secrets, with/without UV).Not this issue: recovery when the authenticator is gone (#167).