Docs menu: vestibule

vestibule

Vestibule — a strategy-based authentication library for Gleam.

vestibule

Vestibule — a strategy-based authentication library for Gleam.

Provides a consistent interface across OAuth2 identity providers using a two-phase flow: redirect to provider, then handle callback. All flows use PKCE (Proof Key for Code Exchange) for enhanced security.

Functions

create_authorization_request

Phase 1: Generate the authorization URL to redirect the user to.

Returns an AuthorizationRequest containing the URL, CSRF state, and PKCE code verifier. The caller must store both the state and code_verifier in their session for use during the callback phase.

PKCE parameters (code_challenge and code_challenge_method=S256) are automatically appended to the authorization URL.

State expiration: This library generates the state token but does not enforce expiration. If you need time-based expiration, store a timestamp alongside the state when saving it to your session and check it before calling handle_callback.

pub fn create_authorization_request(
  strategy.Strategy(a),
  config: config.ClientConfig,
  options: config.AuthorizeOptions
) -> Result(authorization_request.AuthorizationRequest, error.AuthError(a))

handle_callback

Phase 2: Handle the OAuth callback from the provider.

Validates the state parameter, exchanges the authorization code for credentials (including the PKCE code verifier), validates the OIDC nonce against the returned id_token (when the strategy uses one), and fetches normalized user information.

expected_nonce is the OIDC nonce stored during the request phase, or None for plain OAuth2 strategies. When the strategy uses a nonce and an expected value is present, the nonce claim in the id_token artifact must match or the callback fails with an AuthError of kind InvalidNonceKind.

Caller responsibilities: This function checks that the callback state matches expected_state, but does not enforce single-use or expiration. Callers should delete the stored state after a successful call to prevent replay attacks. The wisp middleware’s uset.take provides one-time-use semantics automatically. For time-based expiration, check the timestamp you stored alongside the state before calling this function.

pub fn handle_callback(
  strategy.Strategy(a),
  config: config.ClientConfig,
  callback_params: dict.Dict(String, String),
  expected_state: String,
  code_verifier: String,
  expected_nonce: option.Option(String)
) -> Result(auth.Auth, error.AuthError(a))

refresh_token

Refresh an access token using a refresh token.

Delegates to the provider strategy so refresh semantics remain provider-owned.

pub fn refresh_token(
  strategy.Strategy(a),
  config: config.ClientConfig,
  refresh_token: String
) -> Result(credentials.Credentials, error.AuthError(a))