AttestoMCP.Server.UrlElicitation (attesto_mcp_server v2.8.0)

Copy Markdown View Source

Helpers for staging, resolving, and consuming URL elicitation approval records.

A link with mode: "url" must carry the operation the human is approving by its opaque staged-record ID rather than as a bare route. The staged record is bound to the calling subject hash, contains the exact fields that the action will execute with, is single-use with a short TTL, renders an explicit dead end when expired, consumed, or foreign, and is periodically swept.

The raw principal binding is never persisted in the store; only its deterministic SHA-256 digest is stored.

Summary

Functions

Atomically consumes a staged URL elicitation record upon confirmation.

Resolves a staged URL elicitation record for display on an approval page.

Stages a URL elicitation record before returning an interactive mode: "url" request.

Computes the deterministic SHA-256 hex digest for a principal binding.

Types

handler_context()

@type handler_context() :: map()

resolve_result()

@type resolve_result() ::
  {:ok, staged_content()}
  | {:error, :not_found | :foreign | :consumed | :expired | :store_unavailable}

server()

@type server() :: pid() | atom()

stage_error()

@type stage_error() ::
  {:error,
   :principal_binding_required
   | :invalid_action
   | :invalid_fields
   | :invalid_ttl
   | :store_unavailable}

stage_result()

@type stage_result() :: {:ok, %{id: String.t(), expires_at_ms: non_neg_integer()}}

staged_content()

@type staged_content() :: %{
  action: String.t(),
  fields: map(),
  expires_at_ms: non_neg_integer()
}

Functions

consume_url_elicitation(server, id, principal_binding)

@spec consume_url_elicitation(server(), String.t(), term()) :: resolve_result()

Atomically consumes a staged URL elicitation record upon confirmation.

Can be consumed at most once. Returns {:error, :foreign} if the subject does not match, {:error, :consumed} if already consumed, and {:error, :expired} if expired. Malformed or unknown IDs return {:error, :not_found}.

resolve_url_elicitation(server, id, principal_binding)

@spec resolve_url_elicitation(server(), String.t(), term()) :: resolve_result()

Resolves a staged URL elicitation record for display on an approval page.

Returns {:error, :foreign} if the principal binding does not match the staged subject hash before revealing any action or field content. Returns {:error, :consumed} if already consumed, or {:error, :expired} if expired. Malformed or unknown IDs return {:error, :not_found}.

stage_url_elicitation(server, context, action, fields, opts \\ [])

@spec stage_url_elicitation(server(), handler_context(), String.t(), map(), keyword()) ::
  stage_result() | stage_error()

Stages a URL elicitation record before returning an interactive mode: "url" request.

The context must contain a non-nil :principal_binding. The action must be a non-empty string of at most 256 bytes. Fields must be a JSON object within the server's max_json_bytes budget.

subject_hash(principal_binding)

@spec subject_hash(term()) :: String.t()

Computes the deterministic SHA-256 hex digest for a principal binding.

Only this hash is stored by the URL elicitation store; the raw binding is never persisted in the store record.