glasskey

Package VersionHex Docs

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

ErrorMeaning
NotSupportedWebAuthn unavailable or requested constraints unsupported
NotAllowedUser cancelled or timed out
AbortedOperation was aborted
SecurityErrorSecurity policy violation (e.g., non-HTTPS origin)
InvalidStateAuthenticator state conflict (e.g., credential already registered)
UnknownError(msg)Unexpected browser error