Lightning.Policies.Decision (Lightning v2.20.1)

Copy Markdown View Source

The order every %Scope{} policy decides in, so each policy supplies only its token grant and its rule. project/4 decides actions on a project and instance/4 actions with no project.

The order keeps refusals from leaking. A caller without the grant hears {:error, {:insufficient_scope, grant}} before anything about the target. A caller the rule refuses who has no standing on the project hears {:error, :no_standing}, before the MFA check, so it learns nothing about the project, not even that it exists. Only a caller every other check allows learns {:error, :scheduled_for_deletion}.

allowed? is computed before the call, so it reads only facts already on the scope and subject. A rule that needs another project's facts loads that project's scope through Lightning.Scope, outside allowed? and only after Decision has answered for the subject's own project. :see_credential does this for a credential's linked projects, and the sandbox rules for a sandbox's root project.

A :before_target subject asks only about the grant, so true for it is not permission. Only Lightning.Policies.Permissions.permit/3 passes it, so that LightningWeb.Plugs.AuthorizeAction can refuse a missing grant before anything is loaded.

Summary

Types

The refusal of a caller whose token lacks grant, the one grant the refusing check needed.

Functions

Decides an action with no project, answering allowed? once one of grants is held.

Decides an action on a project. grants is one token grant or a list, any one of which is enough; holding none, the answer is {:error, {:insufficient_scope, grant}} naming the first. A refused caller with no standing on the project hears {:error, :no_standing}, and {:error, :scheduled_for_deletion} comes only to a caller every other check allows.

Types

answer()

@type answer() ::
  boolean()
  | {:error, insufficient_scope() | :no_standing | :scheduled_for_deletion}

grants()

@type grants() :: String.t() | [String.t(), ...]

insufficient_scope()

@type insufficient_scope() :: {:insufficient_scope, grant :: String.t()}

The refusal of a caller whose token lacks grant, the one grant the refusing check needed.

Functions

instance(scope, subject, grants, allowed?)

@spec instance(Lightning.Scope.t(), term(), grants(), boolean()) :: answer()

Decides an action with no project, answering allowed? once one of grants is held.

project(scope, subject, grants, allowed?)

@spec project(Lightning.Scope.t(), term(), grants(), boolean()) :: answer()

Decides an action on a project. grants is one token grant or a list, any one of which is enough; holding none, the answer is {:error, {:insufficient_scope, grant}} naming the first. A refused caller with no standing on the project hears {:error, :no_standing}, and {:error, :scheduled_for_deletion} comes only to a caller every other check allows.