vestibule
Vestibule — demo-ready OAuth sign-in for Gleam.
vestibule
Vestibule — demo-ready OAuth sign-in 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).
Warning: vestibule has not been security audited and must not be considered secure. It is intended for demos and prototypes that need real OAuth flows — do not use it in production.
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,
expected_nonce must be Some and the nonce claim in the id_token
artifact must match it; a missing expected nonce, missing id_token,
missing claim, or mismatch all fail with an AuthError of kind
InvalidNonceKind. The check never falls open.
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(credential.Credentials, error.AuthError(a))