Packages
ash_authentication
5.0.0-rc.6
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
lib/ash_authentication/strategies/webauthn/dsl.ex
# SPDX-FileCopyrightText: 2026 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.Strategy.WebAuthn.Dsl do
@moduledoc """
Defines the Spark DSL entity for the WebAuthn strategy.
"""
alias AshAuthentication.Strategy.WebAuthn
alias Spark.Dsl.Entity
@doc false
@spec dsl :: map
def dsl do
%Entity{
name: :webauthn,
describe: """
Strategy for authenticating using WebAuthn/FIDO2 hardware security keys and passkeys.
""",
examples: [
"""
webauthn :webauthn do
credential_resource MyApp.Accounts.Credential
rp_id "example.com"
rp_name "My App"
identity_field :email
end
"""
],
args: [{:optional, :name, :webauthn}],
hide: [:name],
target: WebAuthn,
no_depend_modules: [:credential_resource],
schema: [
name: [
type: :atom,
doc: "Uniquely identifies the strategy.",
required: true
],
credential_resource: [
type: {:or, [:atom, {:behaviour, Ash.Resource}]},
doc:
"The Ash resource used to store WebAuthn credentials. Must have `credential_id` (binary), `public_key` (binary), and `sign_count` (integer) attributes, plus a `belongs_to` relationship to the user resource.",
required: true
],
rp_id: [
type:
{:or,
[
:string,
{:mfa_or_fun, 1}
]},
doc: """
Relying Party ID - your domain name (e.g. "example.com").
For multi-tenant setups, pass an MFA tuple or 1-arity function that
receives the tenant and returns the domain string:
rp_id {MyApp.WebAuthn, :rp_id_for_tenant, []}
""",
required: true
],
rp_name: [
type:
{:or,
[
:string,
{:mfa_or_fun, 1}
]},
doc: """
Relying Party display name shown to the user during registration.
For multi-tenant setups, pass an MFA tuple or 1-arity function:
rp_name {MyApp.WebAuthn, :rp_name_for_tenant, []}
""",
required: true
],
origin: [
type:
{:or,
[
:string,
{:mfa_or_fun, 1}
]},
doc: """
The expected origin for WebAuthn ceremonies.
In WebAuthn, the **origin** is the scheme + domain + port that the browser
reports during registration and authentication. It is distinct from `rp_id`:
- `rp_id` = domain only (e.g. `"example.com"`)
- `origin` = full URL (e.g. `"https://example.com"` or `"https://localhost:4001"`)
If not set, defaults to `"https://{rp_id}"`. This default **omits the port**,
which works for production on port 443 but will cause Wax to reject ceremonies
in development where the port is non-standard.
**Production:**
origin "https://example.com"
**Development (non-standard port):**
origin "https://localhost:4001"
**Dynamic (multi-tenant):**
origin {MyApp.WebAuthn, :origin_for_tenant, []}
""",
required: false
],
identity_field: [
type: :atom,
doc:
"The name of the attribute which uniquely identifies the user (e.g. `:email`). Used for looking up the user during authentication.",
default: :email
],
authenticator_attachment: [
type: {:in, [nil, :platform, :cross_platform]},
doc:
"Restricts authenticator type. `nil` allows any, `:platform` limits to built-in (Touch ID, Windows Hello), `:cross_platform` limits to USB/NFC keys (YubiKey).",
default: nil
],
user_verification: [
type: {:in, ["required", "preferred", "discouraged"]},
doc:
"Whether user verification (PIN/biometric) is required. Use `\"required\"` for highest security.",
default: "preferred"
],
attestation: [
type: {:in, ["none", "direct"]},
doc:
"Attestation conveyance preference. `\"none\"` is recommended for most use cases. `\"direct\"` requests the authenticator's attestation certificate.",
default: "none"
],
timeout: [
type: :pos_integer,
doc: "Timeout for WebAuthn ceremonies in milliseconds.",
default: 60_000
],
resident_key: [
type: {:in, [:required, :preferred, :discouraged]},
doc:
"Whether to require discoverable credentials (passkeys). `:required` enables username-less authentication.",
default: :required
],
credential_id_field: [
type: :atom,
doc: "The name of the credential ID attribute on the credential resource.",
default: :credential_id
],
public_key_field: [
type: :atom,
doc: "The name of the public key attribute on the credential resource.",
default: :public_key
],
sign_count_field: [
type: :atom,
doc: "The name of the sign count attribute on the credential resource.",
default: :sign_count
],
label_field: [
type: :atom,
doc: "The name of the label attribute on the credential resource.",
default: :label
],
last_used_at_field: [
type: :atom,
doc:
"The name of the last_used_at attribute on the credential resource. Set to `nil` to disable tracking.",
default: :last_used_at
],
user_relationship_name: [
type: :atom,
doc:
"The name of the belongs_to relationship on the credential resource pointing to the user.",
default: :user
],
credentials_relationship_name: [
type: :atom,
doc:
"The name of the has_many relationship on the user resource pointing to credentials.",
default: :webauthn_credentials
],
registration_enabled?: [
type: :boolean,
doc: "Whether to allow new user registration via WebAuthn.",
default: true
],
register_action_name: [
type: :atom,
doc:
"The name of the register action on the user resource. Defaults to `register_with_<strategy_name>`.",
required: false
],
sign_in_action_name: [
type: :atom,
doc:
"The name of the sign-in action on the user resource. Defaults to `sign_in_with_<strategy_name>`.",
required: false
],
store_credential_action_name: [
type: :atom,
doc:
"The name of the create action on the credential resource. Defaults to `store_<strategy_name>_credential`.",
required: false
],
update_sign_count_action_name: [
type: :atom,
doc:
"The name of the update action for sign_count on the credential resource. Defaults to `update_<strategy_name>_sign_count`.",
required: false
],
list_credentials_action_name: [
type: :atom,
doc:
"The name of the read action to list credentials. Defaults to `list_<strategy_name>_credentials`.",
required: false
],
delete_credential_action_name: [
type: :atom,
doc:
"The name of the destroy action for credentials. Defaults to `delete_<strategy_name>_credential`.",
required: false
],
update_credential_label_action_name: [
type: :atom,
doc:
"The name of the update action for credential labels. Defaults to `update_<strategy_name>_credential_label`.",
required: false
],
add_credential_action_name: [
type: :atom,
doc:
"The name of the action to add a credential to an existing user. Defaults to `add_<strategy_name>_credential`.",
required: false
]
]
}
end
end