OapiCodemode.Credentials behaviour (oapi_codemode v0.2.1)

Copy Markdown View Source

Host-implemented credential resolution, library-implemented attachment.

The host resolves what to attach (per request — so token refresh is the host's problem and stale tokens self-heal on the next call). The spec's securityScheme dictates how it is attached. Credential values never enter the sandbox or the transcript.

Summary

Types

Where the request is going, resolved before credential attachment.

Callbacks

Resolve a credential for one request. context is the opaque identity map the host passed into the execute handler (tenant, user, org).

Functions

Turn a resolved credential into headers and query params for one request.

Types

credential()

@type credential() ::
  {:bearer, String.t()}
  | {:basic, String.t(), String.t()}
  | {:api_key, String.t()}
  | :none

request_info()

@type request_info() :: %{
  method: String.t(),
  base_url: String.t(),
  host: String.t() | nil,
  path: String.t()
}

Where the request is going, resolved before credential attachment.

path is the OpenAPI path template — path params are not substituted (e.g. "/pets/{id}", not "/pets/42"). base_url may itself include a path prefix (e.g. "https://api.example.com/v1"); the full wire path is base_url's path segment concatenated with the substituted path, not path alone. method is always lowercase ("get", not "GET").

Callbacks

resolve(api_name, scheme, request, context)

@callback resolve(
  api_name :: String.t(),
  scheme :: map() | nil,
  request :: request_info(),
  context :: map()
) :: {:ok, credential()} | {:error, term()}

Resolve a credential for one request. context is the opaque identity map the host passed into the execute handler (tenant, user, org).

Error contract: a binary {:error, message} crosses back to the sandbox/model verbatim — hosts must keep secrets out of binary error messages. Any non-binary {:error, reason} (e.g. {:expired, token}) is logged in full and replaced with a fixed, redacted string before it reaches the sandbox.

Functions

attach(scheme, credential)

@spec attach(map() | nil, credential()) ::
  {:ok, %{headers: [{String.t(), String.t()}], query: map()}}
  | {:error, String.t()}

Turn a resolved credential into headers and query params for one request.

Credential values are screened for non-printable bytes first: a secret with a stray newline (the classic env-var-with-trailing-\n) would otherwise reach Mint, whose invalid_header_value error embeds the raw value in its message and leaks it into whatever logs that message. Errors from here never echo the credential.