# `ExMCP.Authorization`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/authorization.ex#L1)

MCP Authorization support for OAuth 2.1 with PKCE.

This is a cleaned-up version of the Authorization module that delegates
to focused, single-responsibility modules:

- `ExMCP.Authorization.OAuthFlow` - OAuth flow implementations
- `ExMCP.Authorization.PKCE` - PKCE security implementation
- `ExMCP.Authorization.HTTPClient` - HTTP communication
- `ExMCP.Authorization.Validator` - Parameter validation

This module serves as a facade, maintaining the same public API while
leveraging the decomposed architecture for better maintainability.

# `authorization_config`

```elixir
@type authorization_config() :: %{
  optional(:issuer) =&gt; String.t(),
  client_id: String.t(),
  client_secret: String.t() | nil,
  authorization_endpoint: String.t(),
  token_endpoint: String.t(),
  redirect_uri: String.t(),
  scopes: [String.t()],
  additional_params: map() | nil,
  resource: String.t() | [String.t()] | nil
}
```

# `server_metadata`

```elixir
@type server_metadata() :: %{
  authorization_endpoint: String.t(),
  token_endpoint: String.t(),
  registration_endpoint: String.t() | nil,
  scopes_supported: [String.t()],
  response_types_supported: [String.t()],
  grant_types_supported: [String.t()],
  code_challenge_methods_supported: [String.t()]
}
```

# `token_response`

```elixir
@type token_response() :: %{
  access_token: String.t(),
  token_type: String.t(),
  expires_in: integer() | nil,
  refresh_token: String.t() | nil,
  scope: String.t() | nil
}
```

# `client_credentials_flow`

```elixir
@spec client_credentials_flow(map()) :: {:ok, token_response()} | {:error, term()}
```

Performs OAuth 2.1 client credentials flow.

Delegates to `ExMCP.Authorization.OAuthFlow.client_credentials_flow/1`

# `discover_server_metadata`

```elixir
@spec discover_server_metadata(String.t()) ::
  {:ok, server_metadata()} | {:error, term()}
```

Discovers server metadata from the authorization server.

Uses HTTPClient for the actual HTTP request and metadata parsing.

# `exchange_code_for_token`

```elixir
@spec exchange_code_for_token(map()) :: {:ok, token_response()} | {:error, term()}
```

Exchanges an authorization code for an access token using PKCE.

Pass either `transaction_id: transaction.transaction_id` or
`transaction: transaction` so redemption is single-use and bound to the
callback's exact redirect URI.

# `generate_pkce_challenge`

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

Generates PKCE code challenge parameters.

Delegates to the PKCE module.

# `refresh_token`

```elixir
@spec refresh_token(String.t(), String.t(), String.t(), String.t() | nil) ::
  {:ok, token_response()} | {:error, term()}
```

Refreshes an access token using a refresh token.

Delegates to `ExMCP.Authorization.OAuthFlow.refresh_token/4`

# `start_authorization_flow`

```elixir
@spec start_authorization_flow(authorization_config()) ::
  {:ok, String.t(), map()} | {:error, term()}
```

Starts an OAuth 2.1 authorization code flow with PKCE.

Delegates to `ExMCP.Authorization.OAuthFlow.start_authorization_flow/1`
with the same interface and behavior. State and PKCE values are generated by
ExMCP; reserved OAuth fields cannot be overridden through `additional_params`.

# `token_request`

```elixir
@spec token_request(map()) :: {:ok, map()} | {:error, any()}
```

Makes a token request to the authorization server.

Used internally by TokenManager for refresh operations.
Delegates to HTTPClient for the actual request.

# `validate_authorization_response`

```elixir
@spec validate_authorization_response(map(), map()) ::
  {:ok, String.t()} | {:error, term()}
```

Validates an authorization callback before its code is redeemed.

Pass the transaction returned by `start_authorization_flow/1`. This atomically
consumes its recorded `state` and, when the response contains the RFC 9207
`iss` parameter, enforces exact equality with the recorded issuer.

# `validate_token`

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

Validates an access token with the authorization server.

Uses HTTPClient for the introspection request.

# `verify_pkce_challenge`

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

Verifies a PKCE code challenge.

Delegates to the PKCE module.

---

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