Raxol.Agent.PermissionHook (Raxol Agent v2.6.0)

Copy Markdown View Source

Runtime permission enforcement for agent commands.

Implements CommandHook to check commands against a permission policy before execution. Supports a hierarchical permission mode with per-command-type requirements and an optional prompter for interactive escalation.

Permission Modes (ordered least to most permissive)

  • :read_only -- no side effects allowed
  • :send_only -- inter-agent messaging only
  • :workspace_write -- file writes within workspace
  • :full_access -- shell, system, network
  • :allow -- everything permitted

Usage

# Create a policy
policy = PermissionHook.policy(:workspace_write)

# Use as a command hook
defmodule MyAgent do
  use Raxol.Agent

  def command_hooks do
    [PermissionHook.new(:workspace_write)]
  end
end

Custom Prompter

For interactive permission escalation (terminal prompt, SSH, LiveView):

policy = PermissionHook.policy(:read_only,
  prompter: fn command, _context ->
    # Ask user for permission
    IO.gets("Allow #{command.type}? [y/n] ") |> String.trim() == "y"
  end
)

Summary

Functions

Check whether a directive is authorized under the given policy.

Check if mode a is at least as permissive as mode b.

Set the active permission policy for the current process.

Create a permission policy struct.

Returns the minimum permission mode required for a command type.

Set the active policy for the current process.

Types

effect()

@type effect() :: Raxol.Agent.Directive.t()

mode()

@type mode() :: :read_only | :send_only | :workspace_write | :full_access | :allow

prompter()

@type prompter() :: (directive_type :: atom(), map() -> boolean())

t()

@type t() :: %Raxol.Agent.PermissionHook{
  denied_types: MapSet.t(atom()),
  mode: mode(),
  prompter: prompter() | nil
}

Functions

authorize(directive, policy, context)

@spec authorize(effect(), t(), map()) :: :allow | {:deny, String.t()}

Check whether a directive is authorized under the given policy.

mode_permits?(active, required)

@spec mode_permits?(mode(), mode()) :: boolean()

Check if mode a is at least as permissive as mode b.

new(mode, opts \\ [])

@spec new(
  mode(),
  keyword()
) :: module()

Set the active permission policy for the current process.

Returns the module name for use in command_hooks/0 lists. The policy is stored in the process dictionary, so each agent process maintains its own independent policy.

policy(mode, opts \\ [])

@spec policy(
  mode(),
  keyword()
) :: t()

Create a permission policy struct.

required_mode(command_type)

@spec required_mode(atom()) :: mode()

Returns the minimum permission mode required for a command type.

set_policy(policy)

@spec set_policy(t()) :: :ok

Set the active policy for the current process.