# `HTTPower.Sanitizer`
[🔗](https://github.com/mdepolli/httpower/blob/v0.24.0/lib/httpower/sanitizer.ex#L1)

PCI-compliant sanitization of HTTP headers and bodies.

Redacts sensitive data — credit card numbers (Luhn-validated), CVV/CVC codes,
authorization tokens, API keys, passwords, and other configured fields — from
request/response headers and bodies.

This module is the single source of truth for sanitization. It is used both by
`HTTPower.Client` (to sanitize telemetry metadata at the emission boundary, so
every telemetry consumer receives redacted data) and by `HTTPower.Logger` (to
sanitize what it writes to the log).

## Configuration

    config :httpower, :sanitization,
      sanitize_headers: ["authorization", "api-key", "x-api-key"],
      sanitize_body_fields: ["password", "credit_card", "cvv"]

Configured lists are merged with the built-in defaults (see
`default_sanitize_headers/0` and `default_sanitize_body_fields/0`).

## Body handling

Binary JSON bodies are parsed and sanitized structurally (recursing through
nested objects and arrays, matching by field name), then re-encoded as compact
JSON. Non-JSON binary bodies (e.g. form-encoded) fall back to regex-based
redaction. Map bodies are sanitized structurally.

# `default_sanitize_body_fields`

```elixir
@spec default_sanitize_body_fields() :: [String.t()]
```

Returns the built-in list of body field names redacted by default.

# `default_sanitize_headers`

```elixir
@spec default_sanitize_headers() :: [String.t()]
```

Returns the built-in list of header names redacted by default.

# `sanitize_body`

```elixir
@spec sanitize_body(String.t() | map() | nil) :: String.t() | map() | nil
```

Sanitizes a request/response body by redacting sensitive data.

Handles string, map, and nil bodies. JSON strings are sanitized structurally;
other strings via pattern matching for credit cards and CVV codes plus
configured field names.

## Examples

    iex> HTTPower.Sanitizer.sanitize_body("card: 4111111111111111")
    "card: [REDACTED]"

    iex> HTTPower.Sanitizer.sanitize_body(%{"password" => "secret123"})
    %{"password" => "[REDACTED]"}

# `sanitize_body`

```elixir
@spec sanitize_body(String.t() | map() | nil, [String.t()]) ::
  String.t() | map() | nil
```

Sanitizes a body using an explicit list of (lowercased) field names to redact.

# `sanitize_headers`

```elixir
@spec sanitize_headers(map()) :: map()
```

Sanitizes headers by redacting sensitive values.

Header names are matched case-insensitively against the configured list
(defaults merged with `config :httpower, :sanitization, :sanitize_headers`) and
their values replaced with "[REDACTED]". All keys are normalized to lowercase.

## Examples

    iex> HTTPower.Sanitizer.sanitize_headers(%{"Authorization" => "Bearer token123"})
    %{"authorization" => "[REDACTED]"}

    iex> HTTPower.Sanitizer.sanitize_headers(%{"Content-Type" => "application/json"})
    %{"content-type" => "application/json"}

# `sanitize_headers`

```elixir
@spec sanitize_headers(map(), [String.t()]) :: map()
```

Sanitizes headers using an explicit list of (lowercased) header names to redact.

---

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