Rename OIDC strategy from :rauthy to :oidc, update callback path

- Rename AshAuthentication strategy from :oidc :rauthy to :oidc :oidc;
  generated actions are now register_with_oidc / sign_in_with_oidc.
- Update config keys (:rauthy → :oidc) in dev.exs and runtime.exs.
- Update default_redirect_uri to /auth/user/oidc/callback everywhere.
- Rename Mv.Accounts helper functions accordingly.
- Update Mv.Secrets, AuthController, link_oidc_account_live and all tests.
- Update docker-compose.prod.yml, .env.example, README and docs.

IMPORTANT: OIDC providers must be updated to use the new redirect URI
/auth/user/oidc/callback instead of /auth/user/rauthy/callback.
This commit is contained in:
Moritz 2026-02-24 10:34:36 +01:00
parent c637b6b84f
commit 339d37937a
Signed by: moritz
GPG key ID: 1020A035E5DD0824
25 changed files with 134 additions and 135 deletions

View file

@ -9,7 +9,7 @@ defmodule Mv.Accounts do
## Public API
The domain exposes these main actions:
- User CRUD: `create_user/1`, `list_users/0`, `update_user/2`, `destroy_user/1`
- Authentication: `create_register_with_rauthy/1`, `read_sign_in_with_rauthy/1`
- Authentication: `create_register_with_oidc/1`, `read_sign_in_with_oidc/1`
"""
use Ash.Domain,
extensions: [AshAdmin.Domain, AshPhoenix]
@ -24,8 +24,8 @@ defmodule Mv.Accounts do
define :list_users, action: :read
define :update_user, action: :update_user
define :destroy_user, action: :destroy
define :create_register_with_rauthy, action: :register_with_rauthy
define :read_sign_in_with_rauthy, action: :sign_in_with_rauthy
define :create_register_with_oidc, action: :register_with_oidc
define :read_sign_in_with_oidc, action: :sign_in_with_oidc
end
resource Mv.Accounts.Token

View file

@ -28,7 +28,7 @@ defmodule Mv.Accounts.User do
@doc """
AshAuthentication specific: Defines the strategies we want to use for authentication.
Currently password and SSO with Rauthy as OIDC provider
Currently password and SSO via OIDC (supports any provider: Authentik, Rauthy, Keycloak, etc.)
"""
authentication do
session_identifier Application.compile_env!(:mv, :session_identifier)
@ -52,7 +52,7 @@ defmodule Mv.Accounts.User do
end
strategies do
oidc :rauthy do
oidc :oidc do
client_id Mv.Secrets
base_url Mv.Secrets
redirect_uri Mv.Secrets
@ -88,7 +88,7 @@ defmodule Mv.Accounts.User do
# Always use one of these explicit create actions instead:
# - :create_user (for manual user creation with optional member link)
# - :register_with_password (for password-based registration)
# - :register_with_rauthy (for OIDC-based registration)
# - :register_with_oidc (for OIDC-based registration)
defaults [:read]
destroy :destroy do
@ -267,7 +267,7 @@ defmodule Mv.Accounts.User do
prepare AshAuthentication.Preparations.FilterBySubject
end
read :sign_in_with_rauthy do
read :sign_in_with_oidc do
# Single record expected; required for AshAuthentication OAuth2 strategy (returns list of 0 or 1).
get? true
argument :user_info, :map, allow_nil?: false
@ -302,7 +302,7 @@ defmodule Mv.Accounts.User do
end)
end
create :register_with_rauthy do
create :register_with_oidc do
argument :user_info, :map, allow_nil?: false
argument :oauth_tokens, :map, allow_nil?: false
upsert? true

View file

@ -7,7 +7,7 @@ defmodule Mv.Secrets do
particularly for OIDC (Rauthy) authentication.
## Configuration Source
Secrets are read from the `:rauthy` key in the application configuration,
Secrets are read from the `:oidc` key in the application configuration,
which is typically set in `config/runtime.exs` from environment variables:
- `OIDC_CLIENT_ID`
- `OIDC_CLIENT_SECRET`
@ -21,7 +21,7 @@ defmodule Mv.Secrets do
use AshAuthentication.Secret
def secret_for(
[:authentication, :strategies, :rauthy, :client_id],
[:authentication, :strategies, :oidc, :client_id],
Mv.Accounts.User,
_opts,
_meth
@ -30,7 +30,7 @@ defmodule Mv.Secrets do
end
def secret_for(
[:authentication, :strategies, :rauthy, :redirect_uri],
[:authentication, :strategies, :oidc, :redirect_uri],
Mv.Accounts.User,
_opts,
_meth
@ -39,7 +39,7 @@ defmodule Mv.Secrets do
end
def secret_for(
[:authentication, :strategies, :rauthy, :client_secret],
[:authentication, :strategies, :oidc, :client_secret],
Mv.Accounts.User,
_opts,
_meth
@ -48,7 +48,7 @@ defmodule Mv.Secrets do
end
def secret_for(
[:authentication, :strategies, :rauthy, :base_url],
[:authentication, :strategies, :oidc, :base_url],
Mv.Accounts.User,
_opts,
_meth
@ -58,7 +58,7 @@ defmodule Mv.Secrets do
defp get_config(key) do
:mv
|> Application.fetch_env!(:rauthy)
|> Application.fetch_env!(:oidc)
|> Keyword.fetch!(key)
|> then(&{:ok, &1})
end

View file

@ -48,8 +48,8 @@ defmodule MvWeb.AuthController do
log_failure_safely(activity, reason)
case {activity, reason} do
{{:rauthy, _action}, reason} ->
handle_rauthy_failure(conn, reason)
{{:oidc, _action}, reason} ->
handle_oidc_failure(conn, reason)
{_, %AshAuthentication.Errors.AuthenticationFailed{caused_by: caused_by}} ->
handle_authentication_failed(conn, caused_by)
@ -61,8 +61,8 @@ defmodule MvWeb.AuthController do
end
end
# Log authentication failures safely, avoiding sensitive data for {:rauthy, _} activities
defp log_failure_safely({:rauthy, _action} = activity, reason) do
# Log authentication failures safely, avoiding sensitive data for {:oidc, _} activities
defp log_failure_safely({:oidc, _action} = activity, reason) do
# For Assent errors, use safe_assent_meta to avoid logging tokens/URLs with query params
case reason do
%Assent.ServerUnreachableError{} = err ->
@ -76,7 +76,7 @@ defmodule MvWeb.AuthController do
Logger.warning(message)
_ ->
# For other rauthy errors, log only error type, not full details
# For other OIDC errors, log only error type, not full details
error_type = get_error_type(reason)
Logger.warning(
@ -86,7 +86,7 @@ defmodule MvWeb.AuthController do
end
defp log_failure_safely(activity, reason) do
# For non-rauthy activities, safe to log full reason
# For non-OIDC activities, safe to log full reason
Logger.warning(
"Authentication failure - Activity: #{inspect(activity)}, Reason: #{inspect(reason)}"
)
@ -119,12 +119,12 @@ defmodule MvWeb.AuthController do
if Enum.empty?(parts), do: "", else: " - " <> Enum.join(parts, ", ")
end
# Handle all Rauthy (OIDC) authentication failures
defp handle_rauthy_failure(conn, %Ash.Error.Invalid{errors: errors}) do
# Handle all OIDC authentication failures
defp handle_oidc_failure(conn, %Ash.Error.Invalid{errors: errors}) do
handle_oidc_email_collision(conn, errors)
end
defp handle_rauthy_failure(conn, %AshAuthentication.Errors.AuthenticationFailed{
defp handle_oidc_failure(conn, %AshAuthentication.Errors.AuthenticationFailed{
caused_by: caused_by
}) do
case caused_by do
@ -139,7 +139,7 @@ defmodule MvWeb.AuthController do
end
# Handle Assent server unreachable errors (network/connectivity issues)
defp handle_rauthy_failure(conn, %Assent.ServerUnreachableError{} = _err) do
defp handle_oidc_failure(conn, %Assent.ServerUnreachableError{} = _err) do
# Logging already done safely in failure/3 via log_failure_safely/2
# No need to log again here to avoid duplicate logs
@ -152,7 +152,7 @@ defmodule MvWeb.AuthController do
end
# Handle Assent invalid response errors (configuration or malformed responses)
defp handle_rauthy_failure(conn, %Assent.InvalidResponseError{} = _err) do
defp handle_oidc_failure(conn, %Assent.InvalidResponseError{} = _err) do
# Logging already done safely in failure/3 via log_failure_safely/2
# No need to log again here to avoid duplicate logs
@ -165,7 +165,7 @@ defmodule MvWeb.AuthController do
end
# Catch-all clause for any other error types
defp handle_rauthy_failure(conn, _reason) do
defp handle_oidc_failure(conn, _reason) do
# Logging already done safely in failure/3 via log_failure_safely/2
# No need to log again here to avoid duplicate logs

View file

@ -84,7 +84,7 @@ defmodule MvWeb.LinkOidcAccountLive do
:info,
dgettext("auth", "Account activated! Redirecting to complete sign-in...")
)
|> Phoenix.LiveView.redirect(to: ~p"/auth/user/rauthy")
|> Phoenix.LiveView.redirect(to: ~p"/auth/user/oidc")
{:error, error} ->
Logger.warning(
@ -223,7 +223,7 @@ defmodule MvWeb.LinkOidcAccountLive do
"Your OIDC account has been successfully linked! Redirecting to complete sign-in..."
)
)
|> Phoenix.LiveView.redirect(to: ~p"/auth/user/rauthy")}
|> Phoenix.LiveView.redirect(to: ~p"/auth/user/oidc")}
{:error, error} ->
Logger.warning(