# `AttestoPhoenix.Schema.CIBARequest`
[🔗](https://github.com/XukuLLC/attesto_phoenix/blob/v2.1.0/lib/attesto_phoenix/schema/ciba_request.ex#L1)

Ecto schema + record bridge for the CIBA authentication-request store
(`AttestoPhoenix.Store.EctoCIBAStore`).

Backs `Attesto.CIBAStore`: a CIBA authentication request is a mutable row
that moves through `pending` → (`approved` | `denied`) → `consumed` while the
client polls the token endpoint (poll mode) or awaits a notification (ping
mode). `from_record/1` spreads the core's `Attesto.CIBAStore.entry()` map
across the row's columns for the initial `pending` insert; `to_entry/1` folds
a loaded row back into that contract shape (reconstructing the `:data` map).
The mutating transitions are done as guarded atomic `UPDATE`s in the store,
not through this changeset.

Only the `auth_req_id`'s `Attesto.Secret.hash/1` is stored, never the
plaintext. The §7.3 minimum token-request interval is frozen into the row's
`interval` column at issue (it is the value the client was told), so the
poll throttle reads it per-row.

## `client_notification_token` at rest

For ping mode the row stores the client-generated bearer
`client_notification_token` in plaintext (parity with how PAR request params
are stored): it is single-flow-scoped and short-lived (≤ the request's
lifetime), and the ping deliverer needs it back to authenticate the
notification, so it cannot be one-way hashed. A deployment that wants it
encrypted at rest supplies its own store.

# `t`

```elixir
@type t() :: %AttestoPhoenix.Schema.CIBARequest{
  __meta__: term(),
  acr: term(),
  acr_values: term(),
  auth_req_id_hash: term(),
  auth_time: term(),
  binding_message: term(),
  client_id: term(),
  client_notification_token: term(),
  delivery_mode: term(),
  dpop_jkt: term(),
  expires_at: term(),
  granted_claims: term(),
  granted_scope: term(),
  hint_subject: term(),
  id: term(),
  inserted_at: term(),
  interval: term(),
  last_polled_at: term(),
  resource: term(),
  scope: term(),
  status: term(),
  subject: term()
}
```

# `from_record`

```elixir
@spec from_record(
  Attesto.CIBAStore.entry(),
  keyword()
) :: t()
```

Build the insert map for a new `pending` authentication request from the core
store record. Returns `{schema_struct, prefix}` ready for `Repo.insert/2`.

# `to_entry`

```elixir
@spec to_entry(t()) :: Attesto.CIBAStore.entry()
```

Fold a loaded row into the `Attesto.CIBAStore.entry()` contract shape.

---

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