The explainable record of a verdict.
Every request Limen evaluates produces exactly one decision. It carries the
action, whether the action was enforced, the stage that produced it, every
rule that matched together with the values it observed, the decide
clause that picked the action with the values it observed, the facts the
application stated about the request (see Limen.put_facts/2), and every
signal collected for it. explain/1 renders it for humans.
Actions
:allow- the request continues.:challenge- the client must solve a proof-of-work challenge (params.difficultyleading zero bits, from 1 to 32; 1 costs nothing and only shows that the client runs the challenge's script, see the tuning guide).:throttle-429 Too Many Requests(params.retry_afterseconds).:deny-403 Forbidden;params.banseconds, when set, also bans the client prefix.:tarpit- nothing is sent forparams.delaymilliseconds, then403 Forbidden. A tarpit never bans.:maze- the client gets a slow, endless maze page (seeLimen.Maze) instead of the application;params.banseconds, when set, also flags the client prefix so every later request goes to the maze too.
Stages
The stage names the step of the pipeline that settled the decision:
:off, :endpoint (a Limen challenge endpoint), :trap (a honeypot, see
Limen.Trap), :trust (a policy's trust rule), :ban, :limit,
:pass, :rule (an allow, deny or maze rule short-circuited),
:decide (the score thresholds), or :socket (a WebSocket or LiveView
connection check).
Summary
Functions
Renders a decision as human-readable lines.
Normalises the value returned by a policy's decide block into an action
and its parameters.
Types
@type action() :: :allow | :challenge | :throttle | :deny | :tarpit | :maze
@type mode() :: :dry_run | :enforce
@type stage() ::
:off
| :endpoint
| :trap
| :trust
| :ban
| :limit
| :pass
| :rule
| :decide
| :socket
@type t() :: %Limen.Decision{ action: action(), at: integer(), clause: String.t() | nil, clause_observed: [{String.t(), term()}], duration: non_neg_integer(), enforced: boolean(), errors: [term()], evidence: map(), facts: map(), identity: map(), instance: atom() | nil, matches: [Limen.Decision.Match.t()], method: String.t() | nil, mode: mode(), params: map(), path: String.t() | nil, policy: module() | nil, route: String.t() | nil, score: integer(), signals: map(), stage: stage() }