vestibule_oidc
OpenID Connect discovery that auto-configures a strategy from any standards-compliant issuer URL, including self-hosted providers.
When to use it
Use OIDC discovery when you want to authenticate against any OpenID Connect provider — including self-hosted ones — by pointing at its issuer URL instead of hand-wiring endpoints.
Default scopes: openid profile email
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_oidc = { git = "https://github.com/tylerbutler/vestibule.git", ref = "vestibule-v0.0", path = "packages/vestibule_oidc" }Setup
- Register a client with your OIDC provider and copy the client ID and secret.
- Configure the redirect URI to match the one passed to config.new.
- Call discover with the provider's issuer URL to fetch its well-known configuration.
- Pair the discovered strategy with config.new holding your client credentials.
Usage
import vestibule
import vestibule/config
import vestibule_oidc
// Discover the provider's endpoints from its issuer URL.
let assert Ok(strategy) =
vestibule_oidc.discover("https://accounts.google.com")
let client_config =
config.new(
client_id: "your-client-id",
redirect_uri: "https://myapp.example.com/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,
)What Vestibule handles
- One-step discover reads /.well-known/openid-configuration and builds a Strategy.
- Issuer validation rejects discovery documents whose issuer does not match the requested URL.
- HTTPS and public-host enforcement on issuer and endpoints guards against SSRF.
- Standard OIDC claims (sub, name, email, preferred_username, picture) map to UserInfo.
- Email is only populated when the provider reports email_verified.
What you handle
- Discovery performs HTTP requests, so the strategy targets the Erlang (BEAM) runtime only.
- Store authorization_request.nonce(auth_request) and pass it as `expected_nonce` during callback handling.
- For multi-tenant apps, sanitize user-supplied issuer URLs before calling discover to prevent SSRF.