<!--
This file was generated by Spark. Do not edit it by hand.
-->
# AshAuthentication.Strategy.Totp

Strategy for Time-based One-Time Password (TOTP) authentication.

Provides TOTP support via [nimble_totp](https://hex.pm/packages/nimble_totp),
allowing users to authenticate using time-based codes from authenticator apps
like Google Authenticator, Authy, or 1Password.

## Requirements

Your resource needs to meet the following minimum requirements:

1. Have a primary key.
2. An identity field (e.g., `email` or `username`) for identifying users.
3. A sensitive binary field for storing the TOTP secret.
4. A sensitive datetime field for tracking the last successful TOTP authentication.
5. A brute force protection strategy (rate limiting, audit log, or custom preparation).

## Example

```elixir
defmodule MyApp.Accounts.User do
  use Ash.Resource,
    extensions: [AshAuthentication],
    domain: MyApp.Accounts

  attributes do
    uuid_primary_key :id
    attribute :email, :ci_string, allow_nil?: false, public?: true
    attribute :totp_secret, :binary, sensitive?: true
    attribute :last_totp_at, :utc_datetime, sensitive?: true
  end

  authentication do
    tokens do
      enabled? true
      token_resource MyApp.Accounts.Token
    end

    strategies do
      totp do
        identity_field :email
        issuer "MyApp"
        brute_force_strategy {:audit_log, :my_audit_log}
      end
    end

    add_ons do
      audit_log :my_audit_log do
        audit_log_resource MyApp.Accounts.AuditLog
        log_actions [:sign_in_with_totp, :verify_with_totp, :confirm_setup_with_totp]
      end
    end
  end

  identities do
    identity :unique_email, [:email]
  end
end
```

## Actions

The TOTP strategy can generate up to four actions:

- **setup** - Generates a new TOTP secret for the user. Returns the user with
  a `totp_url` calculation that can be rendered as a QR code.
- **confirm_setup** - When `confirm_setup_enabled?` is true, this action verifies
  a TOTP code before activating the secret. Requires tokens to be enabled.
- **sign_in** - Authenticates a user using their identity and a TOTP code.
- **verify** - Checks if a TOTP code is valid for a given user (without signing in).

## Brute Force Protection

TOTP codes have a small keyspace (typically 6 digits), making them vulnerable
to brute force attacks. You must configure a `brute_force_strategy`:

- `:rate_limit` - Uses `AshRateLimiter` to limit attempts.
- `{:audit_log, :audit_log_name}` - Uses an audit log to track failed attempts.
- `{:preparation, ModuleName}` - Custom preparation for rate limiting.

## Working with Actions

You can interact with TOTP actions via the `AshAuthentication.Strategy` protocol:

    iex> strategy = AshAuthentication.Info.strategy!(MyApp.Accounts.User, :totp)
    ...> {:ok, user} = AshAuthentication.Strategy.action(strategy, :setup, %{user: existing_user})
    ...> user.totp_url_for_totp  # QR code URL

    iex> {:ok, true} = AshAuthentication.Strategy.action(strategy, :verify, %{user: user, code: "123456"})



### authentication.strategies.totp
```elixir
totp name \\ :totp
```


Adds TOTP-based one-time passcode authentication.






### Arguments

| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#authentication-strategies-totp-name){: #authentication-strategies-totp-name .spark-required} | `atom` |  | Uniquely identifies the strategy. |
### Options

| Name | Type | Default | Docs |
|------|------|---------|------|
| [`brute_force_strategy`](#authentication-strategies-totp-brute_force_strategy){: #authentication-strategies-totp-brute_force_strategy .spark-required} | `:rate_limit \| {:audit_log, atom} \| {:preparation, module}` |  | How you are mitigating brute-force token checks. |
| [`identity_field`](#authentication-strategies-totp-identity_field){: #authentication-strategies-totp-identity_field } | `atom` | `:username` | The name of the attribute which uniquely identifies the user, usually something like `username` or `email_address`. |
| [`issuer`](#authentication-strategies-totp-issuer){: #authentication-strategies-totp-issuer } | `String.t` |  | The TOTP issuer to use. Defaults to the strategy name. |
| [`secret_field`](#authentication-strategies-totp-secret_field){: #authentication-strategies-totp-secret_field } | `atom` | `:totp_secret` | The name of the attribute within which to store the TOTP secret. |
| [`read_secret_from`](#authentication-strategies-totp-read_secret_from){: #authentication-strategies-totp-read_secret_from } | `atom` |  | The attribute or calculation to read the TOTP secret from. Defaults to `secret_field`. Useful with AshCloak where encrypted values are read via calculations. |
| [`secret_length`](#authentication-strategies-totp-secret_length){: #authentication-strategies-totp-secret_length } | `pos_integer` | `20` | The number of bytes to use when generating secrets. Default is 20 as per the [HOTP RFC](https://tools.ietf.org/html/rfc4226#section-4). |
| [`last_totp_at_field`](#authentication-strategies-totp-last_totp_at_field){: #authentication-strategies-totp-last_totp_at_field } | `atom` | `:last_totp_at` | The name of the attribute or calculation used to track the last successful TOTP time. |
| [`period`](#authentication-strategies-totp-period){: #authentication-strategies-totp-period } | `pos_integer` | `30` | The period (in seconds) in which the code is valid. |
| [`grace_period`](#authentication-strategies-totp-grace_period){: #authentication-strategies-totp-grace_period } | `non_neg_integer \| nil` |  | The number of additional previous time periods to accept when validating TOTP codes. For example, `1` also accepts the previous period's code. See the [NimbleTOTP grace period docs](https://hexdocs.pm/nimble_totp/NimbleTOTP.html#valid?/3-grace-period). Defaults to `nil` (no grace period). |
| [`setup_enabled?`](#authentication-strategies-totp-setup_enabled?){: #authentication-strategies-totp-setup_enabled? } | `boolean` | `true` | If you do not want the setup action to be generated/validated you disable it by setting this to false. |
| [`setup_action_name`](#authentication-strategies-totp-setup_action_name){: #authentication-strategies-totp-setup_action_name } | `atom` |  | The name to use for the setup action. Defaults to `setup_with_<strategy_name>`. |
| [`totp_url_field`](#authentication-strategies-totp-totp_url_field){: #authentication-strategies-totp-totp_url_field } | `atom` |  | The name to use for the TOTP URL calculation. Defaults to `totp_url_for_<strategy_name>`. |
| [`sign_in_enabled?`](#authentication-strategies-totp-sign_in_enabled?){: #authentication-strategies-totp-sign_in_enabled? } | `boolean` | `false` | If you do not want users to be able to sign in using this strategy, set this to false. |
| [`sign_in_action_name`](#authentication-strategies-totp-sign_in_action_name){: #authentication-strategies-totp-sign_in_action_name } | `atom` |  | The name to use for the sign in action. Defaults to `sign_in_with_<strategy_name>`. |
| [`verify_enabled?`](#authentication-strategies-totp-verify_enabled?){: #authentication-strategies-totp-verify_enabled? } | `boolean` | `true` | If you do not want users to be able to verify their TOTP codes outside of the sign-in action (or you want to handle it yourself), set this to false. |
| [`verify_action_name`](#authentication-strategies-totp-verify_action_name){: #authentication-strategies-totp-verify_action_name } | `atom` |  | The name to use for the verify action. Defaults to `verify_with_<strategy_name>`. |
| [`confirm_setup_enabled?`](#authentication-strategies-totp-confirm_setup_enabled?){: #authentication-strategies-totp-confirm_setup_enabled? } | `boolean` | `false` | When enabled, setup generates a token that must be confirmed with a valid TOTP code before the secret is stored. |
| [`confirm_setup_action_name`](#authentication-strategies-totp-confirm_setup_action_name){: #authentication-strategies-totp-confirm_setup_action_name } | `atom` |  | The name to use for the confirm setup action. Defaults to `confirm_setup_with_<strategy_name>`. |
| [`setup_token_lifetime`](#authentication-strategies-totp-setup_token_lifetime){: #authentication-strategies-totp-setup_token_lifetime } | `pos_integer \| {pos_integer, :days \| :hours \| :minutes \| :seconds}` | `{10, :minutes}` | How long the setup token is valid. If no unit is provided, then `minutes` is assumed. Defaults to 10 minutes. |
| [`audit_log_window`](#authentication-strategies-totp-audit_log_window){: #authentication-strategies-totp-audit_log_window } | `pos_integer \| {pos_integer, :days \| :hours \| :minutes \| :seconds}` | `{5, :minutes}` | Time window for counting failed attempts when using the `{:audit_log, ...}` brute force strategy. If no unit is provided, then `minutes` is assumed. Defaults to 5 minutes. |
| [`audit_log_max_failures`](#authentication-strategies-totp-audit_log_max_failures){: #authentication-strategies-totp-audit_log_max_failures } | `pos_integer` | `5` | Maximum allowed failures within the window before blocking when using the `{:audit_log, ...}` brute force strategy. Defaults to 5. |





### Introspection

Target: `AshAuthentication.Strategy.Totp`



<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>
