Docs menu: Wisp middleware
Wisp middleware

vestibule_wisp

Wisp request/callback routing for Vestibule, including signed session cookie handling and one-time ETS state storage.

When to use it

Use Wisp middleware when your app already routes requests with Wisp and you want the request and callback phases handled for you.

Install

Until 1.0, install Vestibule packages from GitHub using the movingvestibule-v0.0 tag. This requires Gleam 1.18 or later because companion packages use git path dependencies.

[dependencies]
vestibule = { git = "https://github.com/tylerbutler/vestibule.git", ref = "vestibule-v0.0" }
vestibule_wisp = { git = "https://github.com/tylerbutler/vestibule.git", ref = "vestibule-v0.0", path = "packages/vestibule_wisp" }
vestibule_github = { git = "https://github.com/tylerbutler/vestibule.git", ref = "vestibule-v0.0", path = "packages/vestibule_github" }

Setup

  1. Configure Wisp with a strong, stable secret key base.
  2. Initialize the shared state store once per BEAM VM.
  3. Register one or more provider strategies in a registry.
  4. Route /auth/:provider and /auth/:provider/callback to the middleware.

Usage

import gleam/http
import wisp
import vestibule/config
import vestibule/registry
import vestibule/state_store
import vestibule_wisp
import vestibule_github

let assert Ok(registry) =
  registry.new()
  |> registry.register(
    vestibule_github.strategy(),
    config.new(
      client_id: "client_id",
      redirect_uri: "http://localhost:8000/auth/github/callback",
      auth: config.ClientSecret("client_secret"),
    ),
  )

let assert Ok(store) = state_store.try_init()

case wisp.path_segments(req), req.method {
  ["auth", provider], http.Get ->
    vestibule_wisp.request_phase(
      req,
      registry,
      provider,
      store,
      authorize_options: config.authorize_options(),
    )

  ["auth", provider, "callback"], http.Get
  | ["auth", provider, "callback"], http.Post ->
    vestibule_wisp.callback_phase(req, registry, provider, store, on_success)

  _, _ ->
    wisp.not_found()
}

What Vestibule handles

  • Handles both GET and POST callbacks; Apple uses response_mode=form_post.
  • Default cookie name uses the __Host- prefix to defend against cookie tossing.
  • Cookie TTL and server-side state-store TTL share the same value.
  • Structured callback errors are available for custom handling.

What you handle

  • Custom cookie names are automatically given the __Host- prefix under the default SecureOnly cookie security.
  • Use with_cookie_security(AllowInsecure) for local development over plain HTTP, where browsers reject __Host- cookies.
  • Use callback_phase_auth_result when your app needs structured logging or custom user-facing error recovery.