Raxol.AgentClientProtocol.Ext.AttachPolicy behaviour (Raxol Agent Client Protocol v0.1.0)

Copy Markdown View Source

Fail-closed attach admission behaviour.

An attach grants read access to a session's full durable record stream — history from an offset plus the live tail (one decision gates both). Records carry prompts, tool output, file contents; admission is security-core.

A policy module implements authorize_attach/1. It is never trusted to be well-behaved: every invocation is wrapped by Raxol.AgentClientProtocol.Ext.AttachPolicy.Runner (the SOLE funnel), which isolates it in a Task.Supervisor.async_nolink task with a bounded Task.yield + Task.shutdown(:brutal_kill), so a hostile policy can neither block nor crash the bus, and every non-{:ok, %Grant{}} outcome denies.

ctx (attach context)

transport is a REQUIRED key (its value MAY be nil). It is sourced ONLY from Connection-side knowledge, NEVER from a peer-asserted field — a peer does not get to claim kind: :process. LocalNode (the default) consults it and denies a nil transport; Token ignores it.

The default policy

Unconfigured ⇒ LocalNode (deny-by-default). There is no AllowAll module in this package — the absent module is the guarantee.

Summary

Types

Attach context. A grow-only map — a policy MUST tolerate unknown keys and pattern-match only what it needs.

Callbacks

Authorize an attach. A plain, pure-ish function on the policy module, wrapped by the Runner. MUST return a well-formed %Grant{} inside {:ok, _} to admit; anything else (incl. {:error, _}, a raise, a hang) denies.

Functions

The configured attach policy, or LocalNode when unconfigured. Never an allow-all.

Types

ctx()

@type ctx() :: %{
  session_id: String.t(),
  actor: map() | nil,
  surface: atom(),
  capability: binary() | nil,
  from_offset: non_neg_integer(),
  transport: %{kind: atom(), peer: term()} | nil
}

Attach context. A grow-only map — a policy MUST tolerate unknown keys and pattern-match only what it needs.

Callbacks

authorize_attach(ctx)

@callback authorize_attach(ctx()) ::
  {:ok, Raxol.AgentClientProtocol.Ext.AttachPolicy.Grant.t()}
  | {:error, reason :: term()}

Authorize an attach. A plain, pure-ish function on the policy module, wrapped by the Runner. MUST return a well-formed %Grant{} inside {:ok, _} to admit; anything else (incl. {:error, _}, a raise, a hang) denies.

Functions

default_policy()

@spec default_policy() :: module()

The configured attach policy, or LocalNode when unconfigured. Never an allow-all.