glasskey
Browser WebAuthn/FIDO2 bindings for Gleam.
Wraps the browser's navigator.credentials API to perform registration and authentication ceremonies. Produces JSON compatible with glasslock for server-side verification.
Installation
gleam add glasskey
Usage
registration_options_decoder() and authentication_options_decoder() are decoders that parse the options JSON glasslock produces. Compose them into whatever shape your server wraps them in, then pass the decoded value to the matching ceremony starter:
import gleam/json
import glasskey
let options_json = todo as "GET /api/register/begin"
let assert Ok(options) =
json.parse(options_json, glasskey.registration_options_decoder())
Registration
import glasskey
import gleam/javascript/promise
use result <- promise.await(glasskey.start_registration(options))
case result {
Ok(response_json) -> todo as "POST response_json to server for verification"
Error(glasskey.NotSupported) -> todo as "WebAuthn or requested constraints not supported"
Error(glasskey.NotAllowed) -> todo as "user cancelled"
Error(e) -> todo as "other error"
}
Authentication
use result <- promise.await(glasskey.start_authentication(options))
case result {
Ok(response_json) -> todo as "POST response_json to server for verification"
Error(e) -> todo as "handle error"
}
Conditional Authentication (autofill UI)
For passkey suggestions in the browser's autofill dropdown instead of a modal prompt. Requires an <input autocomplete="username webauthn"> element on the page.
case glasskey.start_conditional_authentication(options) {
Ok(glasskey.ConditionalAuthentication(result:, abort:)) -> {
// `abort` cancels the pending ceremony
use response <- promise.await(result)
case response {
Ok(response_json) -> todo as "POST response_json to server for verification"
Error(e) -> todo as "handle error"
}
}
Error(e) -> todo as "handle error"
}
Capability Detection
import glasskey
import gleam/javascript/promise
// Synchronous check
case glasskey.supports_webauthn() {
True -> todo as "WebAuthn is available"
False -> todo as "fall back to password auth"
}
// Check for platform authenticator (Touch ID, Windows Hello, etc.)
use available <- promise.await(glasskey.supports_platform_authenticator())
// Check for autofill/conditional mediation support
use available <- promise.await(glasskey.supports_webauthn_autofill())
Error Types
| Error | Meaning |
|---|---|
NotSupported | WebAuthn unavailable or requested constraints unsupported |
NotAllowed | User cancelled or timed out |
Aborted | Operation was aborted |
SecurityError | Security policy violation (e.g., non-HTTPS origin) |
InvalidState | Authenticator state conflict (e.g., credential already registered) |
UnknownError(msg) | Unexpected browser error |