Packages
ash_authentication
5.0.0-rc.5
5.0.0-rc.12
5.0.0-rc.11
5.0.0-rc.10
5.0.0-rc.9
5.0.0-rc.8
5.0.0-rc.7
5.0.0-rc.6
5.0.0-rc.5
5.0.0-rc.4
5.0.0-rc.3
5.0.0-rc.2
5.0.0-rc.1
5.0.0-rc.0
4.14.1
4.14.0
4.13.7
4.13.6
4.13.5
4.13.4
4.13.3
4.13.2
retired
4.13.1
retired
4.13.0
4.12.0
4.11.0
4.10.0
4.9.9
4.9.8
4.9.7
4.9.6
4.9.5
4.9.4
4.9.3
4.9.2
4.9.1
4.9.0
4.8.7
4.8.6
4.8.5
4.8.3
4.8.2
4.8.1
4.8.0
4.7.6
4.7.5
4.7.4
4.7.3
4.7.2
4.7.1
4.7.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.6
4.5.5
4.5.4
4.5.3
4.5.2
4.5.1
4.5.0
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.12
4.3.11
4.3.10
4.3.9
4.3.8
4.3.7
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
4.0.0-rc.6
4.0.0-rc.5
4.0.0-rc.3
4.0.0-rc.2
4.0.0-rc.1
4.0.0-rc.0
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.16
3.11.15
3.11.14
3.11.13
3.11.12
3.11.11
3.11.10
3.11.9
3.11.8
3.11.7
3.11.6
3.11.5
3.11.4
3.11.3
3.11.2
3.11.1
3.11.0
3.10.8
3.10.7
3.10.6
3.10.5
3.10.4
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.0
3.7.9
3.7.8
3.7.6
3.7.5
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.1
3.6.0
3.5.3
3.5.2
3.5.1
3.5.0
3.3.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.0
3.0.3
Authentication extension for the Ash Framework.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
documentation/dsls/DSL-AshAuthentication.Strategy.RecoveryCode.md
<!--
This file was generated by Spark. Do not edit it by hand.
-->
# AshAuthentication.Strategy.RecoveryCode
Strategy for recovery code authentication.
Allows users to authenticate using one-time recovery codes when they can't
access their primary authentication method (e.g., TOTP authenticator app).
Recovery codes are single-use and deleted after successful verification.
## Requirements
1. A separate Ash resource for storing recovery codes with:
- A sensitive string attribute for the hashed code
- A `belongs_to` relationship to the user resource
- `create`, `read`, and `destroy` actions
2. A `has_many` relationship on the user resource pointing to recovery codes
3. A brute force protection strategy (rate limiting, audit log, or custom preparation)
## Example
```elixir
defmodule MyApp.Accounts.RecoveryCode do
use Ash.Resource,
data_layer: AshPostgres.DataLayer,
domain: MyApp.Accounts
attributes do
uuid_primary_key :id
attribute :code, :string, sensitive?: true, allow_nil?: false
end
relationships do
belongs_to :user, MyApp.Accounts.User, allow_nil?: false
end
actions do
defaults [:read, :destroy]
create :create do
accept [:code]
argument :user_id, :uuid, allow_nil?: false
change manage_relationship(:user_id, :user, type: :append)
end
end
end
defmodule MyApp.Accounts.User do
use Ash.Resource,
extensions: [AshAuthentication],
domain: MyApp.Accounts
relationships do
has_many :recovery_codes, MyApp.Accounts.RecoveryCode
end
authentication do
strategies do
recovery_code do
recovery_code_resource MyApp.Accounts.RecoveryCode
hash_provider AshAuthentication.BcryptProvider
brute_force_strategy {:preparation, MyApp.NoopPreparation}
end
end
end
end
```
## Actions
The recovery code strategy generates up to two actions:
- **verify** - Verifies a recovery code for a user. On success, deletes the
used code and returns the user. On failure, returns nil.
- **generate** - When `generate_enabled?` is true, generates new recovery codes
for a user. Deletes any existing codes and returns the plaintext codes.
### authentication.strategies.recovery_code
```elixir
recovery_code name \\ :recovery_code
```
Adds recovery code authentication for account recovery when TOTP is unavailable.
### Arguments
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`name`](#authentication-strategies-recovery_code-name){: #authentication-strategies-recovery_code-name .spark-required} | `atom` | | Uniquely identifies the strategy. |
### Options
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`recovery_code_resource`](#authentication-strategies-recovery_code-recovery_code_resource){: #authentication-strategies-recovery_code-recovery_code_resource .spark-required} | `module` | | The Ash resource module that stores recovery codes. Must have a `code` attribute and a `belongs_to` relationship to the user. |
| [`brute_force_strategy`](#authentication-strategies-recovery_code-brute_force_strategy){: #authentication-strategies-recovery_code-brute_force_strategy .spark-required} | `:rate_limit \| {:audit_log, atom} \| {:preparation, module}` | | How you are mitigating brute-force recovery code checks. |
| [`recovery_codes_relationship_name`](#authentication-strategies-recovery_code-recovery_codes_relationship_name){: #authentication-strategies-recovery_code-recovery_codes_relationship_name } | `atom` | `:recovery_codes` | The name of the `has_many` relationship on the user resource that points to recovery codes. |
| [`code_field`](#authentication-strategies-recovery_code-code_field){: #authentication-strategies-recovery_code-code_field } | `atom` | `:code` | The name of the attribute on the recovery code resource that stores the hashed code. |
| [`user_relationship_name`](#authentication-strategies-recovery_code-user_relationship_name){: #authentication-strategies-recovery_code-user_relationship_name } | `atom` | `:user` | The name of the `belongs_to` relationship on the recovery code resource that points to the user. |
| [`hash_provider`](#authentication-strategies-recovery_code-hash_provider){: #authentication-strategies-recovery_code-hash_provider } | `module` | `AshAuthentication.SHA256Provider` | The hash provider to use for hashing and verifying recovery codes. Defaults to `AshAuthentication.SHA256Provider` which requires codes with at least 60 bits of entropy. For shorter codes, use `AshAuthentication.BcryptProvider` or `AshAuthentication.Argon2Provider`. |
| [`code_alphabet`](#authentication-strategies-recovery_code-code_alphabet){: #authentication-strategies-recovery_code-code_alphabet } | `String.t` | `"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"` | The set of characters used when generating recovery codes. Each character in the string must be unique. |
| [`recovery_code_count`](#authentication-strategies-recovery_code-recovery_code_count){: #authentication-strategies-recovery_code-recovery_code_count } | `pos_integer` | `10` | The number of recovery codes to generate. |
| [`code_length`](#authentication-strategies-recovery_code-code_length){: #authentication-strategies-recovery_code-code_length } | `pos_integer` | `12` | The length of each generated recovery code. |
| [`verify_action_name`](#authentication-strategies-recovery_code-verify_action_name){: #authentication-strategies-recovery_code-verify_action_name } | `atom` | | The name to use for the verify action. Defaults to `verify_with_<strategy_name>`. |
| [`generate_enabled?`](#authentication-strategies-recovery_code-generate_enabled?){: #authentication-strategies-recovery_code-generate_enabled? } | `boolean` | `true` | Whether to generate the generate action. Set to false if you want to handle code generation yourself. |
| [`generate_action_name`](#authentication-strategies-recovery_code-generate_action_name){: #authentication-strategies-recovery_code-generate_action_name } | `atom` | | The name to use for the generate action. Defaults to `generate_<strategy_name>_codes`. |
| [`audit_log_window`](#authentication-strategies-recovery_code-audit_log_window){: #authentication-strategies-recovery_code-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-recovery_code-audit_log_max_failures){: #authentication-strategies-recovery_code-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.RecoveryCode`
<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>