# `AshOnetime.KeySource`
[🔗](https://github.com/baselabs/ash_onetime/blob/v1.5.0/lib/ash_onetime/key_source.ex#L1)

Closed key-source algebra used by protected actions.

# `source`

```elixir
@type source() ::
  {:client, atom()}
  | {:argument, atom()}
  | {:attribute, atom()}
  | {:external, atom()}
  | {:verified, atom(), module()}
  | {:minted, module()}
```

# `algorithm`

```elixir
@callback algorithm() :: :hmac_sha256 | :ed25519
```

# `mint`

```elixir
@callback mint(context :: map()) :: {:ok, AshOnetime.Verified.t()} | {:error, term()}
```

# `trust_model`

```elixir
@callback trust_model() :: :same_service | :separated
```

# `normalize`

```elixir
@spec normalize(source() | [source()]) :: {:ok, [source()]} | {:error, String.t()}
```

Normalizes a key source or list of sources into a validated list.

Enforces five invariants: non-empty (at least one source), at most `16` sources, no nested
composites (a source cannot itself be a list), all sources unique, and every source a valid
tag (`:client`/`:argument`/`:attribute`/`:external`/`:verified`/`:minted`). A single source
is wrapped in a one-element list. Returns `{:ok, list}` verbatim on success, or
`{:error, message}` naming the violated invariant.

# `references`

```elixir
@spec references([source()]) :: %{arguments: [atom()], attributes: [atom()]}
```

Extracts the argument and attribute names a list of sources binds, for reference-checking
against declared action inputs.

`:client`, `:argument`, `:external`, and `:verified` sources bind argument names;
`:attribute` sources bind attribute names; `:minted` binds neither (it is a freshly-minted
trusted source, not an action input). Returns `%{arguments: [atom], attributes: [atom]}`.

---

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