# `AttestoPhoenix.ClientIdMetadata.Client`
[🔗](https://github.com/XukuLLC/attesto_phoenix/blob/v2.13.0/lib/attesto_phoenix/client_id_metadata/client.ex#L1)

The wrapper that marks a client as having been resolved through CIMD.

A resolved CIMD client is not the host's opaque client value: its redirect
URIs, keys and scopes come from a document the server fetched and validated,
not from the host's `:client_redirect_uris` / `:client_jwks` callbacks, and it
authenticates only as a public client or with `private_key_jwt`. Every policy
decision that differs for such a client keys on this struct.

## Why a struct and not a tagged tuple

The host's client value is opaque by contract - the library never inspects it,
and a host may represent a client however it likes, including as a tuple. A
marker like `{:cimd, metadata}` is therefore a shape a host could return from
`:load_client` by coincidence, and the library would read it as "this client
was resolved from a validated document" on the strength of the shape alone.
That is the wrong way round: every CIMD-specific relaxation would apply to a
client that never went through CIMD, and `client_public?/2` answers `true` for
a CIMD client, so such a client would authenticate with no secret at all.

A struct cannot be produced by coincidence. A host that constructs
`%AttestoPhoenix.ClientIdMetadata.Client{}` has named this module explicitly, which is a
deliberate act rather than an accident of representation.

# `t`

```elixir
@type t() :: %AttestoPhoenix.ClientIdMetadata.Client{
  metadata: AttestoPhoenix.ClientIdMetadata.client()
}
```

A CIMD client: the normalized, string-keyed metadata map
`Attesto.ClientIdMetadata.validate_document/2` produced, wrapped so it cannot
be confused with a host-supplied client value.

# `new`

```elixir
@spec new(AttestoPhoenix.ClientIdMetadata.client()) :: t()
```

Wrap a validated CIMD metadata document as a resolved client.

---

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