The decision point (PDP) of a PARC authorization. A decider receives a fully
enriched Parc.Request and returns one of:
{:allow, obligations}: permitted, with a list of obligations the caller is expected to honor (e.g.{:redact, :email},{:limit, 4});[]for a plain allow;{:deny, reasons}: denied, with a list of reasons explaining the denial (e.g.:two_factor_required);[]for a plain deny;{:challenge, requirements}: not yet authorized until the principal satisfiesrequirements(e.g.:step_up_auth,:accept_terms);{:error, reason}: the decider could not reach a verdict (a backend failure, distinct from a deny).
Obligations are decision-time directives the caller honors on a permit (XACML's
term); reasons explain a denial; requirements name what the principal must satisfy
to proceed. The lists aggregate when several rules contribute. The adapter maps
{:allow, _} to a passing check, treats {:deny, _} and {:challenge, _} as a
failing one (a challenge is not yet authorized), and propagates {:error, _} as
a check error.
The decider is the authorizer; the backend (RBAC, ABAC/ReBAC, Cedar, OPA, ...) is
wired per environment by the policy module, swappable without touching any
resource. A decider depends only on Parc.*, never on the host policy
framework.
Summary
Types
@type obligation() :: term()
@type reason() :: term()
@type requirement() :: term()
@type response() :: {:allow, [obligation()]} | {:deny, [reason()]} | {:challenge, [requirement()]} | {:error, reason()}
Callbacks
@callback decide(Parc.Request.t()) :: response()