Backplane.McpProtocol.Client.Authorization (backplane_mcp_protocol v0.5.0)

Copy Markdown

HTTP client authorization helpers for the modern MCP protocol.

These helpers model authorization-server binding and client registration decisions. They do not add OAuth behavior to stdio transports.

Summary

Functions

Returns the exact authorization-server/client identifier credential key.

Adds the OIDC Dynamic Client Registration application_type field.

Selects the highest-priority registration mechanism supported by both peers.

Validates a present RFC 9207 authorization-response issuer byte for byte.

Validates an RFC 9207 authorization-response issuer using authorization-server metadata.

Types

registration_selection()

@type registration_selection() ::
  {:pre_registered, term()}
  | {:client_id_metadata_document, String.t()}
  | {:dynamic_client_registration, String.t()}

Functions

credential_key(issuer, client_id)

@spec credential_key(String.t(), String.t()) :: {String.t(), String.t()}

Returns the exact authorization-server/client identifier credential key.

Neither component is URI-normalized or case-folded. The issuer should be the value already validated by validate_issuer/2 or validate_issuer/3.

registration_metadata(metadata, application_type)

@spec registration_metadata(map(), :native | :web | String.t()) :: map()

Adds the OIDC Dynamic Client Registration application_type field.

Native desktop, mobile, CLI, and localhost clients should pass :native; remotely hosted browser applications should pass :web.

select_registration(metadata, opts)

@spec select_registration(
  map(),
  keyword()
) :: {:ok, registration_selection()} | {:error, :registration_unavailable}

Selects the highest-priority registration mechanism supported by both peers.

Options are considered in MCP's required priority order:

  • :pre_registered — existing authorization-server-specific client data
  • :client_id_metadata_document — the client's HTTPS metadata document ID
  • :dynamic_client_registration — whether deprecated DCR is enabled

validate_issuer(expected, returned)

@spec validate_issuer(String.t(), String.t() | nil) ::
  :ok | {:error, :issuer_mismatch | :issuer_metadata_required}

Validates a present RFC 9207 authorization-response issuer byte for byte.

When the response omits iss, use validate_issuer/3 with the authorization-server metadata so the advertised support flag can be honored. The two-argument form returns :issuer_metadata_required for an omitted issuer instead of guessing whether the parameter was required.

validate_issuer(expected, returned, metadata)

@spec validate_issuer(String.t(), String.t() | nil, map()) ::
  :ok | {:error, :issuer_mismatch | :missing_issuer}

Validates an RFC 9207 authorization-response issuer using authorization-server metadata.

A present iss always has to match the expected issuer exactly. A missing iss is rejected only when the server advertises authorization_response_iss_parameter_supported.