Current section
Files
Jump to
Current section
Files
README.md
# glasskey
[](https://hex.pm/packages/glasskey)
[](https://hexdocs.pm/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](https://hex.pm/packages/glasslock) for server-side verification.
## Installation
```sh
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:
```gleam
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
```gleam
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
```gleam
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.
```gleam
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
```gleam
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 |