Skip to content

Passkey (WebAuthn PRF) unseal rung #166

Description

@lannbot

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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions