nova_auth_oidc behaviour (nova_auth_oidc v0.2.1)

View Source

Behaviour for OIDC authentication configuration. Implementing modules define OIDC providers, scopes, and callbacks. Configuration is cached in persistent_term for fast repeated access.

Example

-module(my_oidc_config).
-behaviour(nova_auth_oidc).
-export([config/0]).

config() ->
    #{providers => #{
          authentik => #{
              issuer => ~"https://auth.example.com/application/o/myapp",
              client_id => os:getenv("AUTHENTIK_CLIENT_ID"),
              client_secret => os:getenv("AUTHENTIK_CLIENT_SECRET")
          }
      },
      base_url => ~"https://myapp.example.com",
      claims_mapping => #{
          ~"sub" => id,
          ~"email" => email,
          ~"groups" => roles
      }}.

Provider discovery/JWKS trust options

On OTP 28+, each provider's oidcc_provider_configuration_worker already verifies TLS (verify_peer against the OS trust store) by default when it fetches the discovery document and JWKS. To pin an explicit CA bundle or other TLS options instead of relying on that default, set provider_configuration_opts in config/0:

provider_configuration_opts => #{request_opts => #{ssl => my_tls_opts()}}

Treat this key as a trust anchor, not just a TLS knob: its type is oidcc_provider_configuration:opts(), which besides request_opts also carries quirks - allow_unsafe_http (downgrades discovery to plaintext), document_overrides (can override jwks_uri/token_endpoint from the discovery document itself), and issuer_regex (relaxes issuer matching). Build it from static code, never from operator- or env-supplied data - a value that can be edited outside a release effectively controls where tokens are trusted from.

This applies to every provider ensure_providers/1 starts; there is no per-provider override.

Summary

Functions

Return the merged OIDC configuration for Mod, caching in persistent_term.

Return a single config value for Key from the OIDC module Mod.

Start all provider configuration workers for the given auth module. Call this from your application's start/2. Idempotent.

Evict the cached configuration for Mod from persistent_term.

Return configuration for a specific provider.

Return the registered name for a provider's configuration worker.

Build the callback redirect URI for a provider.

Types

provider_config()

-type provider_config() ::
          #{issuer := binary(),
            client_id := binary(),
            client_secret := binary(),
            scopes => [binary()],
            extra_params => #{binary() => binary()}}.

Callbacks

config()

-callback config() ->
                    #{providers := #{atom() => provider_config()},
                      base_url => binary(),
                      auth_path_prefix => binary(),
                      scopes => [binary()],
                      on_success => {redirect, binary()},
                      on_failure => {status, integer()} | {redirect, binary()},
                      claims_mapping => #{binary() => atom()} | {module(), atom()},
                      provider_configuration_opts => oidcc_provider_configuration:opts()}.

Functions

config(Mod)

-spec config(module()) -> map().

Return the merged OIDC configuration for Mod, caching in persistent_term.

config(Mod, Key)

-spec config(module(), atom()) -> term().

Return a single config value for Key from the OIDC module Mod.

ensure_providers(Mod)

-spec ensure_providers(module()) -> ok.

Start all provider configuration workers for the given auth module. Call this from your application's start/2. Idempotent.

invalidate_cache(Mod)

-spec invalidate_cache(module()) -> boolean().

Evict the cached configuration for Mod from persistent_term.

provider_config(Mod, Provider)

-spec provider_config(module(), atom()) -> {ok, provider_config()} | {error, not_found}.

Return configuration for a specific provider.

provider_worker_name(Mod, Provider)

-spec provider_worker_name(module(), atom()) -> atom().

Return the registered name for a provider's configuration worker.

redirect_uri(Mod, Provider)

-spec redirect_uri(module(), atom()) -> binary().

Build the callback redirect URI for a provider.