# `RequestSeal.TransportFacts`
[🔗](https://github.com/baselabs/request_seal/blob/v0.5.2/lib/request_seal/transport_facts.ex#L1)

Enumerated caller declarations about HTTP transport.

Evidence is always `:declared`: values describe what the caller says, not what
was observed or verified. No arbitrary metadata, addresses, or forwarded fields
are accepted. A declaration cannot prove a connection's security prerequisites.

# `t`

```elixir
@type t() :: %RequestSeal.TransportFacts{
  evidence: :declared,
  http_version: :unknown | :http1_0 | :http1_1 | :http2 | :http3,
  tls: :unknown | :plain | :tls
}
```

# `new`

```elixir
@spec new(map()) :: {:ok, t()} | {:error, RequestSeal.Message.Error.t()}
```

Construct enumerated declarations from an attribute map.

## Parameters

  * `attrs` - a plain map (not a struct) using only these keys; unknown keys reject:
    * `:http_version` - `:unknown` (default), `:http1_0`, `:http1_1`, `:http2`, or `:http3`.
    * `:tls` - `:unknown` (default), `:plain`, or `:tls`.
    * `:evidence` - only `:declared` (the default); attempts to supply observed
      or verified evidence reject.

## Returns

  * `{:ok, %RequestSeal.TransportFacts{}}`.
  * `{:error, %RequestSeal.Message.Error{reason: :invalid_transport}}` - the
    only reason. Meanings: `RequestSeal.Message.Error`.

## Examples

    iex> {:ok, facts} = RequestSeal.TransportFacts.new(%{http_version: :http2, tls: :tls})
    iex> facts.evidence
    :declared
    iex> RequestSeal.TransportFacts.new(%{evidence: :observed})
    {:error, %RequestSeal.Message.Error{reason: :invalid_transport}}
    iex> RequestSeal.TransportFacts.new(%{client_address: "192.0.2.10"})
    {:error, %RequestSeal.Message.Error{reason: :invalid_transport}}

# `validate`

```elixir
@spec validate(term()) :: :ok | {:error, RequestSeal.Message.Error.t()}
```

Recheck the declaration boundary, including manually modified structs.

## Parameters

  * `facts` - any term; only a `RequestSeal.TransportFacts` struct can pass.

## Returns

  * `:ok`.
  * `{:error, %RequestSeal.Message.Error{reason: :invalid_transport}}` - the
    only reason. Meanings: `RequestSeal.Message.Error`.

## Examples

    iex> {:ok, facts} = RequestSeal.TransportFacts.new(%{})
    iex> RequestSeal.TransportFacts.validate(facts)
    :ok
    iex> RequestSeal.TransportFacts.validate(%{facts | evidence: :verified})
    {:error, %RequestSeal.Message.Error{reason: :invalid_transport}}

---

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