Application policy contract for canvas commands.
Runtime authorization verifies LivePanels invariants such as payload shape, actor role, item ownership, leases, and declared capabilities. A configured policy module can reject otherwise valid commands with application rules and attach decision metadata to accepted commands.
Configure a policy on the canvas runtime:
on_mount {LivePanels.Canvas, pubsub: MyApp.PubSub, policy: MyApp.CanvasPolicy}Policy modules implement authorize/1:
defmodule MyApp.CanvasPolicy do
@behaviour LivePanels.Canvas.Policy
@impl true
def authorize(%LivePanels.Canvas.Policy.Request{action: :remove_item} = request) do
if MyApp.Workflows.locked?(request.canvas_id, request.item_ids, request.actor) do
{:error, :workflow_locked}
else
:ok
end
end
def authorize(_request), do: :ok
endReturning :ok accepts the command. Returning {:ok, metadata} accepts the
command and stores metadata under :policy in command metadata. Returning
{:error, reason} or {:halt, reason} rejects the command.
Policy callbacks run in the reducer/coordinator command path behind a timeout
boundary. Configure timeout_ms: when command acceptance checks need a
different bound:
on_mount {LivePanels.Canvas,
pubsub: MyApp.PubSub,
policy: {MyApp.CanvasPolicy, timeout_ms: 2_000}}A timeout rejects the LivePanels command. Policy callbacks should be bounded acceptance checks, not application write transactions or side-effect hooks.
Summary
Types
@type t() :: %LivePanels.Canvas.Policy{ module: module() | nil, opts: map(), timeout_ms: timeout_ms() }
@type timeout_ms() :: pos_integer() | :infinity
Callbacks
@callback authorize(LivePanels.Canvas.Policy.Request.t()) :: result()