Docs menu: Core
Core package

vestibule

Core types, two-phase OAuth2 flow, PKCE, CSRF state, token refresh, OIDC discovery, and shared state store.

When to use it

Use the core package when you want direct control over request and callback phases, or when you are building your own transport integration.

Install

gleam add vestibule
gleam add vestibule_github

Setup shape

  1. Register a provider application and copy its client ID and secret.
  2. Create a config with the provider redirect URI.
  3. Store state and code_verifier server-side before redirecting.
  4. Delete state and code_verifier after a successful callback.

Usage

import gleam/dict
import vestibule
import vestibule/config
import vestibule_github

let strategy = vestibule_github.strategy()
let cfg =
  config.new(
    "client_id",
    "client_secret",
    "http://localhost:8000/auth/github/callback",
  )

let assert Ok(auth_request) = vestibule.create_authorization_request(strategy, cfg)
// Store auth_request.state and auth_request.code_verifier server-side.
// Redirect the user to auth_request.url.

let params =
  dict.from_list([
    #("state", "state from callback"),
    #("code", "authorization code from callback"),
  ])

let assert Ok(auth) =
  vestibule.handle_callback(
    strategy,
    cfg,
    params,
    "expected state from session",
    "code verifier from session",
  )

What Vestibule handles

  • PKCE is appended to every authorization URL.
  • State validation happens before provider error details are surfaced.
  • Strategies are values, not behaviours or macros.
  • Provider strategies live in focused companion packages.

Notes to keep explicit

  • Production redirect URIs and OIDC issuers must use HTTPS.
  • Redact Auth and Credentials values in logs; bearer tokens are secrets.
  • OIDC nonce validation is currently left to the consuming app when it needs id_token replay protection beyond PKCE.