# `Ankusa.Edge.StoredHeaders`
[🔗](https://github.com/jamescarr/ankusa/blob/ankusa-v0.7.0/packages/ankusa/lib/ankusa/edge/stored_headers.ex#L1)

Which provider request headers a hook is *stored* with.

Every header a provider sends used to be written verbatim into the hook, then
archived into segments and claim packs and carried to every sink. Credentials
(`Authorization`, `Cookie`, an API key) have no business in any of those, so a
policy decides, per header name, what survives:

  * `drop` — the header is removed;
  * `hash` — the header is kept, its value replaced by `"sha256:<hex>"` of the
    original value (a consumer can still tell two requests carried the same
    value, and nobody can read it).

A name in both lists is dropped. Names are matched case-insensitively.

The policy is applied by `Ankusa.Edge.Ingest` **after** verification: the
verifier reads the request's complete header list, so a scheme that signs a
header (or a source that dedupes on one) is unaffected. Only what is stored,
archived, claim-checked and forwarded loses the header. A quarantined hook is
stored with the policy applied too, so a quarantine replay re-verifies against
the stored list: do not drop a header a verifier of that source needs.

The instance policy is `Ankusa.Config`'s `store_headers`; a source's own
`store_headers` overrides it key by key (an absent `drop` or `hash` inherits
the instance's list).

# `override`

```elixir
@type override() :: %{drop: [String.t()] | nil, hash: [String.t()] | nil}
```

# `policy`

```elixir
@type policy() :: %{drop: [String.t()], hash: [String.t()]}
```

# `default`

```elixir
@spec default() :: policy()
```

The instance default: the credential-bearing headers dropped, nothing hashed.

# `normalize!`

```elixir
@spec normalize!(term(), String.t()) :: policy()
```

Validate and normalise an instance policy (`key` names it in the error): a map
or keyword list with optional `:drop` and `:hash` lists of non-empty header
names, lowercased. An absent key keeps the default's list.

# `normalize_override!`

```elixir
@spec normalize_override!(term(), String.t()) :: override() | nil
```

Validate and normalise a source's override: `nil` stays `nil`; otherwise
`normalize!/2`'s shape, with an absent key left `nil` (inherit).

# `resolve`

```elixir
@spec resolve(override() | nil, policy()) :: policy()
```

The policy a source runs under: its override laid over the instance's.

# `strip`

```elixir
@spec strip([{String.t(), String.t()}], policy()) ::
  {[{String.t(), String.t()}], non_neg_integer()}
```

Apply `policy` to a header list: `{headers, dropped}`, `dropped` counting the
headers removed. A list nothing matched is returned as it came, with no
allocation: the common request carries none of the named headers.

---

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