A2aEngine.Auth behaviour (a2a_engine v0.1.0)

Copy Markdown View Source

Behaviour for authenticating an inbound A2A request at the transport boundary.

Hosts wire an A2aEngine.Auth implementation into each transport so request dispatch can either:

  • succeed with an auth_context that downstream handlers can inspect, or
  • reject the request without touching the handler.

Built-in implementations

OAuth2 / OIDC implementations slot in later as additional modules without changing the behaviour.

request_info shape

The transport layer normalises the incoming request into a uniform map before handing it to the auth impl:

%{
  headers: %{"authorization" => "Bearer ..."},
  peer: {:tcp, {127, 0, 0, 1}} | {:beam, :"app@host"} | :local,
  transport: :http | :beam_native
}

auth_context shape

On success, the impl returns an auth_context that travels into handler calls:

%{
  scheme: :bearer | :localhost | :anonymous | atom(),
  principal: "agent_name" | nil,
  extra: %{...}   # impl-specific
}

Error kinds

On rejection, impls return {:error, :unauthenticated | :forbidden}. Transports translate to HTTP 401/403 (for HTTP) or a JSON-RPC invalid-request / internal-error envelope (for BeamNative).

Summary

Functions

Shortcut for building an auth_context with defaults filled in.

Types

auth_context()

@type auth_context() :: %{scheme: atom(), principal: String.t() | nil, extra: map()}

error()

@type error() :: :unauthenticated | :forbidden | {atom(), map()}

request_info()

@type request_info() :: %{
  headers: %{required(String.t()) => String.t()},
  peer: {:tcp, :inet.ip_address()} | {:beam, node()} | :local,
  transport: :http | :beam_native
}

Callbacks

authenticate(request_info, opts)

@callback authenticate(request_info(), opts :: keyword()) ::
  {:ok, auth_context()} | {:error, error()}

Functions

context(scheme, principal \\ nil, extra \\ %{})

@spec context(atom(), String.t() | nil, map()) :: auth_context()

Shortcut for building an auth_context with defaults filled in.