Docs menu: Overview

Strategy-based OAuth2 authentication for Gleam

OAuth sign-in for Gleam apps, without the guesswork.

Vestibule gives Gleam applications a consistent request/callback flow, normalized auth results, PKCE, CSRF state, provider strategies, and Wisp or Mist middleware without hiding the security responsibilities your app still owns.

Search state, PKCE, provider packages

Identity provider

  1. RequestURL, state, PKCE verifier
  2. StoreBind transient callback data
  3. CallbackValidate and normalize user info

Signed-in session in your app

Build the stack in two steps.

Start with the route layer: Wisp and Mist middleware own request and callback routes, or your own router calls the core API directly. Then add a provider strategy for profile and token behavior; it never replaces request and callback handling.

Keep the callback boundary explicit.

Vestibule creates the authorization request and validates the callback. Your app still stores state and PKCE data before redirecting, then maps successful auth results to accounts.

State mismatchRestart sign-in and discard stored callback data.

Provider rejectionShow an auth error instead of asserting success.

Profile or token failureRetry the provider flow or route users to support.

Troubleshoot callback errors
import vestibule/authorization_request
import vestibule/error

// Request phase: failure here means
// misconfiguration, so assert is fine.
let options = config.authorize_options()
let assert Ok(auth_request) =
  vestibule.create_authorization_request(
    strategy,
    config: client_config,
    options: options,
  )
// Store authorization_request.state(auth_request)
// and code_verifier(auth_request), then redirect
// to authorization_request.url(auth_request).

// Callback phase: state can mismatch and
// providers can reject the user, so handle
// both branches instead of asserting.
case
  vestibule.handle_callback(
    strategy,
    client_config,
    params,
    expected_state,
    code_verifier,
    expected_nonce: option.None,
  )
{
  Ok(auth) -> sign_in(auth)
  Error(err) ->
    case error.kind(err) {
      error.StateMismatchKind -> restart_sign_in()
      _ -> show_auth_error(err)
    }
}

Secure defaults, explicit boundaries.

Vestibule creates strong state tokens, applies PKCE, validates callback state before surfacing provider details, and verifies the provider-specific data it owns. Your application still stores transient callback data, protects bearer credentials, and decides how users map to accounts.

Review caller responsibilities