Nous.Permissions (nous v0.13.3)

View Source

Tool-level permission policy engine.

Controls which tools can be used, which require user approval, and which are denied entirely. This operates at the tool level — for message-level input filtering, see Nous.Plugins.InputGuard.

Quick Start

# Use a preset policy
policy = Nous.Permissions.default_policy()

# Check tool access
Nous.Permissions.blocked?(policy, "bash")
#=> false

Nous.Permissions.requires_approval?(policy, "bash")
#=> true

Nous.Permissions.requires_approval?(policy, "file_read")
#=> false

# Filter a tool list
tools = [bash_tool, read_tool, write_tool]
allowed = Nous.Permissions.filter_tools(policy, tools)

Custom Policies

policy = %Nous.Permissions.Policy{
  mode: :default,
  deny_names: MapSet.new(["bash"]),
  deny_prefixes: ["web_"],
  approval_required: MapSet.new(["file_write", "file_edit"])
}

Summary

Functions

Checks if a tool name is blocked by the policy.

Creates a policy from keyword options.

Returns the default permission policy.

Filters a list of Nous.Tool structs, removing blocked tools.

Partitions tools into {allowed, blocked} based on the policy.

Returns a permissive policy where all tools are open.

Checks if a tool requires approval under the policy.

Returns a strict policy where all tools require approval.

Functions

blocked?(policy, tool_name)

@spec blocked?(Nous.Permissions.Policy.t(), String.t()) :: boolean()

Checks if a tool name is blocked by the policy.

Matches against deny_names (exact, case-insensitive) and deny_prefixes (prefix match, case-insensitive).

Examples

iex> policy = %Nous.Permissions.Policy{deny_names: MapSet.new(["bash"]), deny_prefixes: ["web_"]}
iex> Nous.Permissions.blocked?(policy, "bash")
true
iex> Nous.Permissions.blocked?(policy, "web_fetch")
true
iex> Nous.Permissions.blocked?(policy, "file_read")
false

build_policy(opts \\ [])

@spec build_policy(keyword()) :: Nous.Permissions.Policy.t()

Creates a policy from keyword options.

Options

  • :mode:default, :permissive, or :strict
  • :deny — list of tool names to block
  • :deny_prefixes — list of prefixes to block (e.g. ["web_"])
  • :approval_required — list of tool names requiring approval

Examples

policy = Nous.Permissions.build_policy(
  mode: :default,
  deny: ["bash"],
  deny_prefixes: ["web_"],
  approval_required: ["file_write"]
)

default_policy()

@spec default_policy() :: Nous.Permissions.Policy.t()

Returns the default permission policy.

Read and search tools are open. Write and execute tools require approval.

filter_tools(policy, tools)

@spec filter_tools(Nous.Permissions.Policy.t(), [Nous.Tool.t()]) :: [Nous.Tool.t()]

Filters a list of Nous.Tool structs, removing blocked tools.

Examples

tools = [bash_tool, read_tool, write_tool]
policy = Nous.Permissions.build_policy(deny: ["bash"])
filtered = Nous.Permissions.filter_tools(policy, tools)
# Returns [read_tool, write_tool]

partition_tools(policy, tools)

@spec partition_tools(Nous.Permissions.Policy.t(), [Nous.Tool.t()]) ::
  {[Nous.Tool.t()], [Nous.Tool.t()]}

Partitions tools into {allowed, blocked} based on the policy.

Examples

{allowed, denied} = Nous.Permissions.partition_tools(policy, tools)

permissive_policy()

@spec permissive_policy() :: Nous.Permissions.Policy.t()

Returns a permissive policy where all tools are open.

requires_approval?(policy, tool_name)

@spec requires_approval?(Nous.Permissions.Policy.t(), String.t()) :: boolean()

Checks if a tool requires approval under the policy.

Examples

iex> policy = Nous.Permissions.strict_policy()
iex> Nous.Permissions.requires_approval?(policy, "file_read")
true

iex> policy = Nous.Permissions.permissive_policy()
iex> Nous.Permissions.requires_approval?(policy, "bash")
false

strict_policy()

@spec strict_policy() :: Nous.Permissions.Policy.t()

Returns a strict policy where all tools require approval.