# `ConduitMcp.Client.OAuth.Config`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.11.0/lib/conduit_mcp/client/oauth/config.ex#L1)

The options of the client's OAuth 2.1 support, validated into a struct.

Given to the Streamable HTTP transport as `auth: {:oauth, opts}` (or
`auth: {:client_credentials, opts}`), or built with `new!/1` for a
standalone flow with `ConduitMcp.Client.OAuth`.

    auth: {:oauth,
      redirect_uri: "http://127.0.0.1:33418/callback",
      client_metadata_url: "https://app.example.com/oauth/client.json",
      client_metadata: [client_name: "My Agent", application_type: :native],
      pre_registered: %{"https://auth.example.com" => [client_id: "abc"]},
      on_authorization_required: &MyApp.Auth.prompt/1,
      expected_issuers: ["https://auth.example.com"]}

Secrets (client secrets, private keys) are held as
`ConduitMcp.Client.Secret`s.

## Options

* `:server_url` - The MCP server's URL. Filled in by the transport; required for a
  standalone configuration passed to `ConduitMcp.Client.OAuth`. The default value is `nil`.

* `:grant` - `:authorization_code` (a user authorizes in a browser) or
  `:client_credentials` (machine to machine; set by
  `auth: {:client_credentials, opts}`). The default value is `:authorization_code`.

* `:redirect_uri` - The redirect URI registered for the client: `https`, or `http` on
  a loopback host (RFC 8252). `ConduitMcp.Client.OAuth.authorize_url/2`
  may override it (as `ConduitMcp.Client.OAuth.Loopback` does). The default value is `nil`.

* `:client_metadata_url` - The `https` URL (with a path) of the client's Client ID Metadata
  Document. When the authorization server advertises
  `client_id_metadata_document_supported`, this URL **is** the
  client id. Host the document (`ConduitMcp.Client.OAuth.CIMD.document/1`)
  at that URL. The default value is `nil`.

* `:client_metadata` (`t:keyword/0`) - Metadata sent in a dynamic client registration request. The default value is `[]`.

  * `:client_name` (`t:String.t/0`) - Shown to the user by the authorization server.

  * `:application_type` - The dynamic-registration `application_type`. Default:
    `:native` for a loopback or custom-scheme redirect URI, else `:web`.

  * `:client_uri` (`t:String.t/0`) - The client's home page.

  * `:logo_uri` (`t:String.t/0`) - The client's logo.

* `:pre_registered` - Clients registered out of band, as a map from the authorization
  server's issuer (exact string) to client options:

    * `:client_id` (`t:String.t/0`) - Required. The client id.

    * `:client_secret` - The client secret: a string, a `ConduitMcp.Client.Secret`, or
      `{:system, "VAR"}` (read from the environment when a token is
      requested, never stored).

    * `:private_key` - A private JWK (a map, or a PEM string) for `private_key_jwt` client
      authentication (RFC 7523). Needs the optional `:jose` dependency.

    * `:private_key_alg` (`t:String.t/0`) - The JWS algorithm of the client assertion. The default value is `"RS256"`.

    * `:private_key_kid` - The `kid` header of the client assertion. The default value is `nil`.

    * `:token_endpoint_auth_method` - How the client authenticates at the token endpoint. Default:
      `:private_key_jwt` with a `:private_key`, `:client_secret_basic` with a
      `:client_secret`, else `:none` (a public client).

  The default value is `%{}`.

* `:store` - The `ConduitMcp.Client.OAuth.TokenStore` as `{module, opts}`.
  Default: an in-memory `ConduitMcp.Client.OAuth.TokenStore.ETS`
  started under the client's supervisor, or, for a
  `ConduitMcp.Client.Hub` server, the hub's, shared by its servers. The default value is `nil`.

* `:on_authorization_required` - Called with a `ConduitMcp.Client.OAuth.Challenge` when the user
  must authorize (in a task, never in the connection). Start the
  flow with `ConduitMcp.Client.OAuth.authorize_url/2`. The default value is `nil`.

* `:max_step_up_attempts` (`t:non_neg_integer/0`) - Step-up authorizations allowed per resource and scope set. The default value is `2`.

* `:refresh_skew` (`t:non_neg_integer/0`) - Seconds before expiry at which an access token is refreshed. The default value is `30`.

* `:expected_issuers` - When a list, the authorization server the server names must be
  one of these issuers (exact match). `nil` accepts any. The default value is `nil`.

* `:principal` (`t:term/0`) - The identity tokens are stored under, part of every token-store
  key: the end user or tenant this client acts for. The default value is `nil`.

* `:scopes` (list of `t:String.t/0`) - Scopes to request when neither the server's challenge nor its
  metadata names any (always requested by `:client_credentials`). The default value is `[]`.

* `:client_id` - `:client_credentials` only. The default value is `nil`.

* `:client_secret` - `:client_credentials` only; see `:pre_registered`.

* `:private_key` - `:client_credentials` only; see `:pre_registered`.

* `:private_key_alg` (`t:String.t/0`) - See `:pre_registered`. The default value is `"RS256"`.

* `:private_key_kid` - See `:pre_registered`. The default value is `nil`.

* `:token_endpoint_auth_method` - `:client_credentials` only; see `:pre_registered`.

* `:allow_insecure_oauth` (`t:boolean/0`) - Development and tests only: admit plain `http` metadata and
  authorization-server URLs on loopback hosts. The default value is `false`.

* `:allow_private` (list of `t:term/0`) - CIDRs the URL policy admits for OAuth requests although they are
  private (see `ConduitMcp.Client.URLPolicy`). The default value is `[]`.

* `:resolver` - The DNS resolver for the URL policy (see `ConduitMcp.Client.URLPolicy`). The default value is `nil`.

* `:transport_opts` - TLS options for OAuth requests (Mint `:transport_opts`, for example `cacerts:`). Certificates are always verified: `verify:` other than `:verify_peer`, and `verify_fun:`, are refused. The default value is `[]`.

* `:request_timeout` (`t:pos_integer/0`) - Milliseconds for each OAuth HTTP request. The default value is `10000`.

* `:clock` - Returns the current Unix time in seconds (tests). Default: the system clock. The default value is `nil`.

# `client_credentials`

```elixir
@type client_credentials() :: %{
  client_id: String.t(),
  auth_method:
    :none | :client_secret_basic | :client_secret_post | :private_key_jwt,
  secret: ConduitMcp.Client.Secret.t() | {:system, String.t()} | nil,
  private_key: ConduitMcp.Client.Secret.t() | nil,
  alg: String.t(),
  kid: String.t() | nil
}
```

A client identity: the id, how it authenticates at the token endpoint,
and its credentials.

# `t`

```elixir
@type t() :: %ConduitMcp.Client.OAuth.Config{
  allow_insecure_oauth: boolean(),
  allow_private: [term()],
  client: term(),
  client_metadata: keyword(),
  client_metadata_url: String.t() | nil,
  clock: (-&gt; integer()) | nil,
  credentials: client_credentials() | nil,
  expected_issuers: [String.t()] | nil,
  grant: :authorization_code | :client_credentials,
  max_step_up_attempts: non_neg_integer(),
  on_authorization_required: (term() -&gt; term()) | nil,
  pre_registered: %{optional(String.t()) =&gt; client_credentials()},
  principal: term(),
  redirect_uri: String.t() | nil,
  refresh_skew: non_neg_integer(),
  request_timeout: pos_integer(),
  resolver: ConduitMcp.Client.URLPolicy.resolver() | nil,
  scopes: [String.t()],
  server_id: term(),
  server_url: String.t() | nil,
  store: {module(), keyword()} | nil,
  transport_opts: keyword()
}
```

# `new`

```elixir
@spec new(keyword() | t()) :: {:ok, t()} | {:error, String.t()}
```

Validates `opts` into a config. Returns `{:error, message}` on an
invalid option.

# `new!`

```elixir
@spec new!(keyword() | t()) :: t()
```

Like `new/1`, raising `ArgumentError`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
