Accrue.Auth behaviour (accrue v0.3.0)

Copy Markdown View Source

Behaviour + facade for host-app auth integration (AUTH-01, AUTH-02).

Accrue does NOT own authentication. The host application (using Sigra, phx.gen.auth, Ueberauth, or any custom solution) implements this behaviour and wires it via config :accrue, :auth_adapter, MyApp.Auth. Accrue.Admin (Phase 7) and any callers that need current_user reach through this facade.

Default adapter (Accrue.Auth.Default)

Phase 1 ships a dev-permissive default (Accrue.Auth.Default) that returns a stubbed %{id: "dev"} in :dev / :test and refuses to boot in :prod (D-40). Plan 06 will call Accrue.Auth.Default.boot_check!/0 from Accrue.Application.start/2 so production deploys can never run with no auth in place.

Contract

  • current_user/1 — lookup the user from a %Plug.Conn{} or any arbitrary map. Returns the user struct/map or nil.
  • require_admin_plug/0 — returns a plug function that raises on non-admins. Admin UI mounts this at the router level.
  • user_schema/0 — returns the host's user Ecto schema module (or nil if not applicable). Used by the admin UI for joins / previews.
  • log_audit/2 — emit an audit record for a user action. Default is a no-op; hosts may persist or forward to a SIEM.
  • actor_id/1 — extract the canonical actor id string from a user struct/map. Used by Accrue.Events.record/1 when auto-stamping actor context.
  • step_up_challenge/2 — optional destructive-action challenge hook for admin step-up flows.
  • verify_step_up/3 — optional destructive-action verification hook paired with step_up_challenge/2.

Summary

Functions

Delegates to the configured adapter's actor_id/1.

Returns whether user should be treated as an admin.

Delegates to the configured adapter's current_user/1.

Delegates to the configured adapter's log_audit/2.

Delegates to the configured adapter's require_admin_plug/0.

Delegates to the configured adapter's optional step_up_challenge/2.

Delegates to the configured adapter's user_schema/0.

Delegates to the configured adapter's optional verify_step_up/3.

Types

conn()

@type conn() :: Plug.Conn.t() | map()

user()

@type user() :: map() | struct()

Callbacks

actor_id(user)

@callback actor_id(user()) :: String.t() | nil

current_user(conn)

@callback current_user(conn()) :: user() | nil

log_audit(user, map)

@callback log_audit(user(), map()) :: :ok

require_admin_plug()

@callback require_admin_plug() :: (conn(), keyword() -> conn())

step_up_challenge(user, map)

(optional)
@callback step_up_challenge(user(), map()) :: map()

user_schema()

@callback user_schema() :: module() | nil

verify_step_up(user, map, map)

(optional)
@callback verify_step_up(user(), map(), map()) :: :ok | {:error, term()}

Functions

actor_id(user)

@spec actor_id(user()) :: String.t() | nil

Delegates to the configured adapter's actor_id/1.

admin?(user)

@spec admin?(user() | nil) :: boolean()

Returns whether user should be treated as an admin.

Adapters may expose a dedicated admin?/1 helper; otherwise Accrue falls back to conservative host-shape heuristics (role, is_admin, admin).

current_user(conn)

@spec current_user(conn()) :: user() | nil

Delegates to the configured adapter's current_user/1.

log_audit(user, event)

@spec log_audit(user(), map()) :: :ok

Delegates to the configured adapter's log_audit/2.

require_admin_plug()

@spec require_admin_plug() :: (conn(), keyword() -> conn())

Delegates to the configured adapter's require_admin_plug/0.

step_up_challenge(user, action)

@spec step_up_challenge(user(), map()) :: map()

Delegates to the configured adapter's optional step_up_challenge/2.

user_schema()

@spec user_schema() :: module() | nil

Delegates to the configured adapter's user_schema/0.

verify_step_up(user, params, action)

@spec verify_step_up(user(), map(), map()) :: :ok | {:error, term()}

Delegates to the configured adapter's optional verify_step_up/3.