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

Copy Markdown View Source

The DEFAULT deny-by-default attach policy.

Grants iff the attach arrives over a transport that implies OS-level co-residency; denies everything else — including a nil / absent transport (fail-closed: if the Connection didn't say where the peer is, we do not guess).

authorize_attach(ctx):
  case ctx.transport do
    %{kind: :process} -> {:ok, grant(via: :local_node)}   # in-BEAM paired transport
    %{kind: :stdio}   -> {:ok, grant(via: :local_node)}   # pipe to a co-resident process
    _other_or_nil     -> {:error, :not_local}             # tcp, websocket, unknown, ABSENT
  end

ctx.transport is Connection-sourced only and NEVER peer-asserted, so a network peer cannot present as kind: :process to steal a local grant. LocalNode never reads ctx.capability (a token sent here is ignored, not an error — stock-client compatibility).

Every LocalNode grant carries the same actor, %{"id" => "local", "kind" => "local_node"}. A ctx.actor is not used: under this policy nothing authenticates it, and a handler may have taken it from the peer.

Why this is not a hole: anyone who can present a co-resident transport can already read the journal files directly; the token would add zero security against that principal. LocalNode refuses a network listener transport, which is the actual attacker.