Docs menu: OIDC discovery

OIDC discovery

Build a Vestibule strategy from any OpenID Connect provider's issuer URL, including self-hosted providers.

Discover a provider

vestibule_oidc.discover builds a Vestibule strategy for a standards-compliant OpenID Connect provider. Supply the provider’s issuer URL. The function reads the provider’s /.well-known/openid-configuration document and returns the strategy.

import vestibule_oidc
let assert Ok(strategy) =
vestibule_oidc.discover("https://accounts.google.com")

Use the discovered strategy with the same two-phase flow and registry. You can also use it with vestibule_wisp or vestibule_mist middleware.

Self-hosted providers

vestibule_oidc.discover also supports self-hosted providers such as Pocket ID. Supply the base URL of your instance. Then use config.new to add your client credentials to the discovered strategy.

import vestibule
import vestibule/config
import vestibule_oidc
// Discovery reads https://your-pocket-id-instance/.well-known/openid-configuration
let assert Ok(strategy) =
vestibule_oidc.discover("https://your-pocket-id-instance")
let client_config =
config.new(
client_id: "your-client-id",
redirect_uri: "http://localhost:8000/auth/oidc/callback",
auth: config.ClientSecret("your-client-secret"),
)
let options = config.authorize_options()
let assert Ok(auth_request) =
vestibule.create_authorization_request(
strategy,
config: client_config,
options: options,
)

Register a client

Register a client with your provider before you start the authorization flow:

  • Redirect URI: Use the exact URI that you pass to config.new. For example, use https://app.example.com/auth/oidc/callback. Non-local redirect URIs and OIDC issuers must use HTTPS. http://localhost and http://127.0.0.1 are permitted for local development only.

  • Scopes: Request openid email profile so that Vestibule can return the user’s ID, email address, and name. user_info.email returns a value only if the provider reports email_verified.

  • Client credentials: Copy the client ID and secret into config.new.

Nonce validation

A discovered strategy uses an OIDC nonce. Vestibule generates the nonce and adds it to the authorization request. It validates the nonce in the returned id_token during callback handling. Wisp and Mist middleware store the nonce for you. If you use core directly, store authorization_request.nonce(auth_request) and supply it as expected_nonce during callback handling.