glasskey

Package Version Hex 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
Search Document