passkeys #
ZDS supports WebAuthn passkeys for OAuth login. This is modeled after Tranquil's passkey support; passkeys are outside the official Bluesky PDS surface ZDS tracks for compatibility.
storage #
Each passkey row belongs to an account DID and stores:
- credential ID
- credential public key
- signature counter
- friendly name
- created and last-used timestamps
Challenge rows are short-lived. Registration challenges are tied to the account DID. Discoverable login challenges are tied to the OAuth request so an authenticator can identify the account by credential ID.
login behavior #
If the login hint resolves to an account with saved passkeys, the OAuth page
offers passkey login first and keeps password login available. If no passkey is
saved for the account, password login is shown directly and points the user to
/account/manage after authentication.
Discoverable passkey login is supported: the browser may return a credential without the page first choosing an account. ZDS resolves the credential ID to the stored account, verifies the assertion, updates the signature counter, and authorizes the OAuth request.
management #
Passkeys are managed from /account/manage, alongside app passwords. That
page signs in with the account password, lists saved passkeys, and supports add,
rename, and delete. Registration uses a browser WebAuthn prompt; ZDS stores only
the credential ID, public key, counter, name, and timestamps.
Deleting a passkey removes it from ZDS. The browser, OS, or password manager may still keep its copy, but it can no longer be used with this PDS.
references #
- Tranquil frontend:
frontend/src/routes/OAuthLogin.svelte,frontend/src/routes/Settings.svelte - Tranquil storage traits:
crates/tranquil-db-traits/src/user.rs - ZDS WebAuthn dependency: https://tangled.org/zzstoatzz.io/webauthn