Rulestead.Admin.Policy behaviour (rulestead v1.0.0)

Copy Markdown View Source

Host-owned authorization seam for the mounted admin and governed actions.

Rulestead does not ship an auth stack. You implement this behaviour in your application and pass it to RulesteadAdmin.Router.rulestead_admin/2 (and it is consulted for governed runtime mutations). Each call is explicit about who (actor), what (action), which resource, and which environment — there is no implicit role inference.

defmodule MyApp.RulesteadPolicy do
  @behaviour Rulestead.Admin.Policy

  @impl true
  def can?(actor, action, _resource, _environment_key) do
    action in Rulestead.Admin.Policy.viewer_actions() or admin?(actor)
  end
end

Canonical role model

Actions map to the Viewer / Editor / Admin model. The action catalogs are introspectable via the read-only role-vocabulary helpers: viewer_actions/0, editor_actions/0, admin_actions/0, and governance_actions/0.

Callbacks

can?/4 is required. change_request_required?/4 and allow_self_approval?/4 are optional and default to safe (governed) behavior.

Summary

Callbacks

Optional callback. Returns true if actor is permitted to approve their own change request for action.

Required callback. Returns true if actor is permitted to perform action on resource in environment_key.

Optional callback. Returns true if the given action requires a change request (human approval) before being applied.

Functions

Role-vocabulary / introspection helper (read-only catalog).

Role-vocabulary / introspection helper (read-only catalog).

Role-vocabulary / introspection helper (read-only catalog).

Role-vocabulary / introspection helper (read-only catalog).

Types

action()

@type action() ::
  governance_action()
  | viewer_action()
  | editor_action()
  | admin_action()
  | atom()

actor()

@type actor() :: term()

admin_action()

@type admin_action() ::
  :approve_change_request
  | :reject_change_request
  | :execute_change_request
  | :cancel_schedule
  | :requeue_schedule
  | :recover_schedule
  | :rollback_audit
  | :export_audit
  | :manage_webhooks
  | :manage_settings

editor_action()

@type editor_action() ::
  :create_flag
  | :update_flag
  | :archive_flag
  | :save_draft
  | :apply_audience_mutation
  | :submit_change_request
  | :cancel_own_change_request
  | :create_schedule

environment_key()

@type environment_key() :: String.t() | atom() | nil

governance_action()

@type governance_action() ::
  :publish_ruleset
  | :advance_rollout
  | :engage_kill_switch
  | :release_kill_switch
  | :promote_environment

resource()

@type resource() :: term()

viewer_action()

@type viewer_action() ::
  :read_flags
  | :read_rulesets
  | :read_rollouts
  | :simulate_flag
  | :explain_flag
  | :list_audit_events
  | :read_change_requests
  | :read_schedules
  | :list_webhook_records
  | :fetch_webhook_record
  | :read_diagnostics
  | :compare_environments
  | :preview_audience_impact
  | :list_audience_dependencies

Callbacks

allow_self_approval?(actor, action, resource, environment_key)

(optional)
@callback allow_self_approval?(
  actor :: term(),
  action :: governance_action(),
  resource :: term(),
  environment_key :: String.t() | atom() | nil
) :: boolean()

Optional callback. Returns true if actor is permitted to approve their own change request for action.

Called only when a change request exists and the submitter is the same actor attempting to approve it. When not implemented, the default behavior is false — the submitter cannot approve their own request. Return true to allow self-approval (e.g. for admin users who are trusted to approve their own governed actions).

can?(actor, action, resource, environment_key)

@callback can?(
  actor :: actor(),
  action :: action(),
  resource :: resource(),
  environment_key :: environment_key()
) :: boolean()

Required callback. Returns true if actor is permitted to perform action on resource in environment_key.

Called by the mounted admin and by governed runtime mutations. Each argument is explicit — there is no implicit role inference from the actor's shape.

Implement this callback to map your application's identity and permission model onto Rulestead's action vocabulary. The action catalogs (viewer_actions/0, editor_actions/0, admin_actions/0, governance_actions/0) are available as read-only helpers for building your implementation.

change_request_required?(actor, action, resource, environment_key)

(optional)
@callback change_request_required?(
  actor :: term(),
  action :: governance_action(),
  resource :: term(),
  environment_key :: String.t() | atom() | nil
) :: boolean()

Optional callback. Returns true if the given action requires a change request (human approval) before being applied.

Called only for governance_action/0 atoms. When not implemented, the default behavior is false — no change request required. Return true for governance actions that must go through an approval workflow before taking effect (e.g. requiring approval before publishing a ruleset to production).

Functions

admin_actions()

@spec admin_actions() :: [admin_action()]

Role-vocabulary / introspection helper (read-only catalog).

Returns the list of admin_action/0 atoms representing administrative operations available to the Admin role (10 atoms). Includes approval and rejection of change requests, schedule management, audit export, webhooks, and settings. These include the review side of the change-request workflow.

Use this catalog in can?/4 to define Admin-level access without hard-coding the full atom list.

editor_actions()

@spec editor_actions() :: [editor_action()]

Role-vocabulary / introspection helper (read-only catalog).

Returns the list of editor_action/0 atoms representing authoring operations available to the Editor role (8 atoms). Includes actions such as :create_flag, :update_flag, :archive_flag, :save_draft, and :submit_change_request.

Use this catalog in can?/4 to define Editor-level access without hard-coding the full atom list.

governance_actions()

@spec governance_actions() :: [governance_action()]

Role-vocabulary / introspection helper (read-only catalog).

Returns the list of governance_action/0 atoms representing high-impact mutations that typically require change-request approval:

  • :publish_ruleset
  • :advance_rollout
  • :engage_kill_switch
  • :release_kill_switch
  • :promote_environment

Use this catalog in your can?/4 and change_request_required?/4 implementations to guard these actions without hard-coding the atom list. This is a read-only catalog — calling it has no side effects.

viewer_actions()

@spec viewer_actions() :: [viewer_action()]

Role-vocabulary / introspection helper (read-only catalog).

Returns the list of viewer_action/0 atoms representing read-only or safe simulation actions available to the Viewer role (14 atoms). Includes actions such as :read_flags, :simulate_flag, :explain_flag, :read_diagnostics, and related read-only operations.

Use this catalog in can?/4 to define Viewer-level access without hard-coding the full atom list.