Parc.PolicyDecider behaviour (parc v0.1.0)

Copy Markdown View Source

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 satisfies requirements (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

obligation()

@type obligation() :: term()

reason()

@type reason() :: term()

requirement()

@type requirement() :: term()

response()

@type response() ::
  {:allow, [obligation()]}
  | {:deny, [reason()]}
  | {:challenge, [requirement()]}
  | {:error, reason()}

Callbacks

decide(t)

@callback decide(Parc.Request.t()) :: response()