# `Ithibati.Identity.Grant`
[🔗](https://github.com/oliverandrich/ithibati/blob/v0.6.2/lib/ithibati/identity/grant.ex#L1)

Adds an account's first passkey and recovery codes to an application's `Ecto.Multi`.

Create the account and any related application rows in the same transaction. Append the grant
after steps that can refuse registration:

    alias Ecto.Multi
    alias MyApp.Accounts.User

    Multi.new()
    |> Multi.insert(:account, User.changeset(%User{}, attrs))
    |> Ithibati.Identity.Grant.with_key_and_codes(key_attrs)
    |> MyApp.Repo.transaction()

Use `Ithibati.Identity.Passkeys.add_key/2` to add a passkey to an existing account without
replacing its recovery codes.

# `with_key_and_codes`

Returns the multi with `:passkey` and `:recovery_codes` steps appended.

`key_attrs` must be verified credential attributes from
`Ithibati.Identity.Passkeys.verify_registration/2`, optionally labelled with
`Ithibati.Identity.Passkeys.key_attrs/2`. The multi must already contain the account step.

## Options

  * `:account` — name of the step that provides the account; defaults to `:account`.
  * `:count` — number of recovery codes; defaults to `12`. Accepts a non-negative integer.
    `0` issues no codes; invalid values raise when the step runs.

Reserve `:passkey` and `:recovery_codes` for these steps. On transaction success,
`:recovery_codes` contains the plaintext list to display. Existing codes for the account,
if any, are replaced.

> #### Keep plaintext codes out of failed transaction logs {: .warning}
>
> A later failure returns earlier step results in `changes_so_far`, including any plaintext
> recovery codes already generated. Put bootstrap claims, invitation acceptance and other
> steps that can refuse before this grant. Do not log complete transaction results.

---

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