# `ExMCP.Security.Validation`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/security/validation.ex#L1)

Handles request and response validation, including transport layer security configurations.

This module is responsible for various validation tasks to ensure that
incoming requests and security configurations meet the required policies.

# `auth_method`

```elixir
@type auth_method() ::
  {:bearer, token :: String.t()}
  | {:api_key, key :: String.t(), opts :: keyword()}
  | {:basic, username :: String.t(), password :: String.t()}
  | {:custom, headers :: [{String.t(), String.t()}]}
  | {:oauth2, map()}
```

# `security_config`

```elixir
@type security_config() :: %{
  optional(:auth) =&gt; auth_method(),
  optional(:headers) =&gt; [{String.t(), String.t()}],
  optional(:validate_origin) =&gt; boolean(),
  optional(:allowed_origins) =&gt; [String.t()],
  optional(:cors) =&gt; map(),
  optional(:tls) =&gt; map()
}
```

Security configuration map for transport-level security.

Supports bearer tokens, API keys, basic auth, OAuth 2.1, custom headers,
origin validation, CORS, and TLS configuration.

# `enforce_https_requirement`

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

Enforces HTTPS requirement for non-localhost URLs.

# `validate_certificate_pinning_config`

```elixir
@spec validate_certificate_pinning_config(map()) :: :ok | {:error, atom()}
```

Validates certificate pinning configuration.

# `validate_cipher_suites`

```elixir
@spec validate_cipher_suites(map() | nil) :: :ok | {:error, atom()}
```

Validates cipher suite configuration.

# `validate_config`

```elixir
@spec validate_config(security_config()) :: :ok | {:error, term()}
```

Validates security configuration.

# `validate_localhost_binding`

```elixir
@spec validate_localhost_binding(map()) ::
  :ok | {:error, :public_binding_requires_security}
```

Validates that a server binding is localhost-only for security.

Accepts the shapes `:gen_tcp`/`:inet` understand: binaries (`"127.0.0.1"`),
charlists (`~c"127.0.0.1"`), address tuples (`{127, 0, 0, 1}`,
`{0, 0, 0, 0, 0, 0, 0, 1}`) and the `:loopback` atom. A configured binding
of any other shape is rejected rather than silently accepted — a
`{0, 0, 0, 0}` tuple binds every interface just as `"0.0.0.0"` does.

A config with no `:binding` key at all is not a binding decision and passes.

## Examples

    iex> ExMCP.Security.Validation.validate_localhost_binding(%{binding: "127.0.0.1"})
    :ok

    iex> ExMCP.Security.Validation.validate_localhost_binding(%{binding: "localhost"})
    :ok

    iex> ExMCP.Security.Validation.validate_localhost_binding(%{binding: {127, 0, 0, 1}})
    :ok

    iex> ExMCP.Security.Validation.validate_localhost_binding(%{binding: "0.0.0.0"})
    {:error, :public_binding_requires_security}

    iex> ExMCP.Security.Validation.validate_localhost_binding(%{binding: {0, 0, 0, 0}})
    {:error, :public_binding_requires_security}

# `validate_mtls_config`

```elixir
@spec validate_mtls_config(map()) :: :ok | {:error, atom()}
```

Validates mutual TLS configuration.

# `validate_origin`

```elixir
@spec validate_origin(String.t() | nil, [String.t()] | :any) ::
  :ok | {:error, :origin_not_allowed}
```

Validates origin header against allowed origins.

## Examples

    iex> ExMCP.Security.Validation.validate_origin("https://example.com", ["https://example.com"])
    :ok

    iex> ExMCP.Security.Validation.validate_origin("https://evil.com", ["https://example.com"])
    {:error, :origin_not_allowed}

# `validate_request`

```elixir
@spec validate_request([{String.t(), String.t()}], security_config()) ::
  :ok | {:error, atom()}
```

Validates an HTTP request for security compliance.

This function implements comprehensive security validation including:
- Origin header validation (DNS rebinding protection)
- Required security headers validation
- HTTPS enforcement for non-localhost

## Examples

    headers = [{"origin", "https://example.com"}, {"host", "api.example.com"}]
    config = %{validate_origin: true, allowed_origins: ["https://example.com"]}

    :ok = ExMCP.Security.Validation.validate_request(headers, config)

# `validate_security_requirements`

```elixir
@spec validate_security_requirements(security_config()) :: :ok | {:error, term()}
```

Validates that security configuration meets MCP specification requirements.

# `validate_tls_config`

```elixir
@spec validate_tls_config(map()) :: :ok | {:error, atom()}
```

Validates TLS/SSL configuration.

## Examples

    config = %{
      verify: :verify_peer,
      versions: [:"tlsv1.2", :"tlsv1.3"],
      ciphers: ["ECDHE-RSA-AES256-GCM-SHA384"]
    }

    :ok = ExMCP.Security.Validation.validate_tls_config(config)

# `validate_transport_security`

```elixir
@spec validate_transport_security(map()) :: :ok | {:error, atom()}
```

Validates transport security configuration.

---

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