---
title: Customization
sidebar:
  order: 4
---

## Overview

Like the other **SuperTokens** authentication recipes, you can customize the `WebAuthn` flow through different configuration options and overrides.
The following page describes the options that you can change and the different scenarios enabled through customization.

---

## Backend recipe configuration

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```ts
import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import WebAuthn from "supertokens-node/recipe/webauthn";

supertokens.init({
  framework: "express",
  supertokens: {
    // https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
    connectionURI: "https://try.supertokens.com",
    // apiKey: <API_KEY(if configured)>,
  },
  appInfo: {
    // learn more about this on https://supertokens.com/docs/references/backend-sdks/reference#sdk-configuration
    appName: "<YOUR_APP_NAME>",
    apiDomain: "<YOUR_API_DOMAIN>",
    websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    WebAuthn.init({
      getOrigin: async () => {
        return "https://example.com";
      },
      getRelyingPartyId: async () => {
        return "example.com";
      },
      getRelyingPartyName: async () => {
        return "example";
      },
    }),
    Session.init(), // initializes session features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"net/http"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/webauthn"
	"github.com/supertokens/supertokens-golang/recipe/webauthn/webauthnmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	apiBasePath := "/auth"
	websiteBasePath := "/auth"
	err := supertokens.Init(supertokens.TypeInput{
		Supertokens: &supertokens.ConnectionInfo{ConnectionURI: "https://try.supertokens.com"},
		AppInfo: supertokens.AppInfo{
			AppName:         "<YOUR_APP_NAME>",
			APIDomain:       "<YOUR_API_DOMAIN>",
			WebsiteDomain:   "<YOUR_WEBSITE_DOMAIN>",
			APIBasePath:     &apiBasePath,
			WebsiteBasePath: &websiteBasePath,
		},
		RecipeList: []supertokens.Recipe{
			webauthn.Init(&webauthnmodels.TypeInput{
				GetOrigin: func(tenantID string, req *http.Request, userContext supertokens.UserContext) (string, error) {
					return "https://example.com", nil
				},
				GetRelyingPartyId: func(tenantID string, req *http.Request, userContext supertokens.UserContext) (string, error) {
					return "example.com", nil
				},
				GetRelyingPartyName: func(tenantID string, userContext supertokens.UserContext) (string, error) {
					return "example", nil
				},
			}),
			session.Init(nil),
		},
	})
	if err != nil {
		panic(err)
	}
}
```
</Tab>
<Tab title="Python" value="python">
```python
from typing import Optional

from supertokens_python import InputAppInfo, SupertokensConfig, init
from supertokens_python.framework import BaseRequest
from supertokens_python.recipe import session, webauthn
from supertokens_python.recipe.webauthn import WebauthnConfig
from supertokens_python.types.base import UserContext


async def get_origin(*, tenant_id: str, request: Optional[BaseRequest], user_context: UserContext):
    return "https://example.com"

async def get_relying_party_id(*, tenant_id: str, request: Optional[BaseRequest], user_context: UserContext):
    return "example.com"

async def get_relying_party_name(*, tenant_id: str, user_context: UserContext):
    return "example"

init(
    app_info=InputAppInfo(
        app_name="<YOUR_APP_NAME>",
        api_domain="<YOUR_API_DOMAIN>",
        website_domain="<YOUR_WEBSITE_DOMAIN>",
        api_base_path="/auth",
        website_base_path="/auth"
    ),
    supertokens_config=SupertokensConfig(
        # https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
        connection_uri="https://try.supertokens.com",
        # api_key="<API_KEY(if configured)>"
    ),
    framework='flask',  # Replace this with the framework you are using
    recipe_list=[
        webauthn.init(
            config=WebauthnConfig(
                get_origin=get_origin,
                get_relying_party_id=get_relying_party_id,
                get_relying_party_name=get_relying_party_name,
            )
        ),
        session.init()  # initializes session features
    ]
)
```
</Tab>
</CodeGroup>

<DependentContent passive group="backend-language">
<ContentOption title="Node.js" value="nodejs">
The backend recipe accepts the following properties during initialization:

| Option | Description | Default |
|--------|-------------|---------|
| `getRelyingPartyId` | Sets the domain name associated with the WebAuthn credentials. This helps ensure that only your domain uses the credentials. | Hostname of `appInfo.apiDomain` |
| `getRelyingPartyName` | Sets a human-readable name for your application. The name appears to users during the WebAuthn registration process. | The `appName` value that you have set in `appConfig` |
| `getOrigin` | Configures the frontend origin that WebAuthn credentials bind to. | `appInfo.getOrigin(...)`, normally the configured website origin |
| `emailDelivery` | Configures how the system builds and sends account-recovery emails. Read the [email delivery page](/platform-configuration/email-delivery) for more information. | Default email service |
| `validateEmailAddress` | Adds custom validation logic for email addresses. | Basic email format validation |

All the properties are optional.
</ContentOption>
<ContentOption title="Python" value="python">
The backend recipe accepts the following properties during initialization:

| Option | Description | Default |
|--------|-------------|---------|
| `get_relying_party_id` | Sets the domain name associated with the WebAuthn credentials. This helps ensure that only your domain uses the credentials. | Hostname of `app_info.api_domain` |
| `get_relying_party_name` | Sets a human-readable name for your application. The name appears to users during the WebAuthn registration process. | The `app_name` value that you have set in `app_config` |
| `get_origin` | Configures the frontend origin that WebAuthn credentials bind to. | `app_info.get_origin(...)`, normally the configured website origin |
| `email_delivery` | Configures how the system builds and sends account-recovery emails. Read the [email delivery page](/platform-configuration/email-delivery) for more information. | Default email service |
| `validate_email_address` | Adds custom validation logic for email addresses. | Basic email format validation |

All the properties are optional.
</ContentOption>
<ContentOption title="Go" value="go">
The backend recipe accepts the following optional properties in `webauthnmodels.TypeInput`:

| Option | Description | Default |
|--------|-------------|---------|
| `GetRelyingPartyId` | Sets the domain name associated with the WebAuthn credentials. | Hostname of `AppInfo.APIDomain` |
| `GetRelyingPartyName` | Sets a human-readable name for your application. | `AppInfo.AppName` |
| `GetOrigin` | Configures the frontend origin that WebAuthn credentials bind to. | `AppInfo.GetOrigin(...)`, normally the configured website origin |
| `EmailDelivery` | Configures how the system builds and sends account-recovery emails. | Default email service |
| `ValidateEmailAddress` | Adds custom validation logic for email addresses. | Basic email format validation |
</ContentOption>
</DependentContent>

The RP ID must equal the frontend origin's host or be a registrable domain suffix of it. It must not include a scheme, port, or path. The origin must include the exact scheme and host, plus the port when it is non-default. For example, RP ID `example.com` is valid for origin `https://login.example.com`, but `api.example.net` is not. If your API and website use unrelated hosts, the default RP ID derived from the API domain is invalid for the website origin; configure both values explicitly.

---

## Credential generation

The client generates the credentials based on the options provided by the backend SDK.
The frontend SDK uses [`navigator.credentials.create()`](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create) to start the registration ceremony.

To change the options used to generate credentials, you need to override the `registerOptions` function.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```ts
import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import WebAuthn from "supertokens-node/recipe/webauthn";

supertokens.init({
  framework: "express",
  supertokens: {
    // https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
    connectionURI: "https://try.supertokens.com",
    // apiKey: <API_KEY(if configured)>,
  },
  appInfo: {
    // learn more about this on https://supertokens.com/docs/references/backend-sdks/reference#sdk-configuration
    appName: "<YOUR_APP_NAME>",
    apiDomain: "<YOUR_API_DOMAIN>",
    websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    WebAuthn.init({
      override: {
        functions: (originalImplementation) => {
          return {
            ...originalImplementation,
            registerOptions: (input) => {
              return originalImplementation.registerOptions({
                ...input,
                attestation: "direct",
                residentKey: "required",
                timeout: 10 * 1000,
                userVerification: "required",
                userPresence: true,
                displayName: "John Doe",
                supportedAlgorithmIds: [-257],
                relyingPartyId: "example.com",
                relyingPartyName: "example",
                origin: "https://example.com",
              });
            },
          };
        },
      },
    }),
    Session.init(), // initializes session features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go check=false reason="Override excerpt; pass config to webauthn.Init in your recipe list."
config := &webauthnmodels.TypeInput{
	Override: &webauthnmodels.OverrideStruct{
		Functions: func(original webauthnmodels.RecipeInterface) webauthnmodels.RecipeInterface {
			originalRegisterOptions := *original.RegisterOptions
			registerOptions := func(
				email, recoverAccountToken, displayName *string,
				relyingPartyID, relyingPartyName, origin string,
				timeout *int, attestation *webauthnmodels.Attestation,
				residentKey *webauthnmodels.ResidentKey,
				userVerification *webauthnmodels.UserVerification,
				userPresence *bool,
				supportedAlgorithmIDs []webauthnmodels.COSEAlgorithmIdentifier,
				tenantID string, userContext supertokens.UserContext,
			) (webauthnmodels.RegisterOptionsResponse, error) {
				customTimeout := 10 * 1000
				customAttestation := webauthnmodels.AttestationDirect
				customResidentKey := webauthnmodels.ResidentKeyRequired
				customUserVerification := webauthnmodels.UserVerificationRequired
				customUserPresence := true
				return originalRegisterOptions(
					email, recoverAccountToken, displayName,
					"example.com", "example", "https://example.com",
					&customTimeout, &customAttestation, &customResidentKey,
					&customUserVerification, &customUserPresence,
					[]webauthnmodels.COSEAlgorithmIdentifier{-257}, tenantID, userContext,
				)
			}
			original.RegisterOptions = &registerOptions
			return original
		},
	},
}
```
</Tab>
<Tab title="Python" value="python">
```python
from typing import List, Optional, cast

from typing_extensions import Unpack

from supertokens_python import InputAppInfo, SupertokensConfig, init
from supertokens_python.recipe import session, webauthn
from supertokens_python.recipe.webauthn import (
    RecipeInterface,
    WebauthnConfig,
    WebauthnOverrideConfig,
)
from supertokens_python.recipe.webauthn.interfaces.recipe import (
    Attestation,
    RegisterOptionsKwargsInput,
    ResidentKey,
    UserVerification,
)
from supertokens_python.types.base import UserContext


def override_webauthn_functions(original_implementation: RecipeInterface):
    original_register_options = original_implementation.register_options

    async def register_options(
        *,
        relying_party_id: str,
        relying_party_name: str,
        origin: str,
        resident_key: Optional[ResidentKey] = None,
        user_verification: Optional[UserVerification] = None,
        user_presence: Optional[bool] = None,
        attestation: Optional[Attestation] = None,
        supported_algorithm_ids: Optional[List[int]] = None,
        timeout: Optional[int] = None,
        tenant_id: str,
        user_context: UserContext,
        **kwargs: Unpack[RegisterOptionsKwargsInput],
    ):
        return await original_register_options(
            relying_party_id="example.com",
            relying_party_name="example",
            origin="https://example.com",
            resident_key="required",
            user_verification="required",
            user_presence=True,
            attestation="direct",
            supported_algorithm_ids=[-257],
            timeout=10 * 1000,
            tenant_id=tenant_id,
            user_context=user_context,
            email=cast(str, kwargs.get("email")),
            recover_account_token=cast(str, kwargs.get("recover_account_token")),
            display_name="John Doe",
        )

    original_implementation.register_options = register_options
    return original_implementation


init(
    app_info=InputAppInfo(
        app_name="<YOUR_APP_NAME>",
        api_domain="<YOUR_API_DOMAIN>",
        website_domain="<YOUR_WEBSITE_DOMAIN>",
        api_base_path="/auth",
        website_base_path="/auth",
    ),
    supertokens_config=SupertokensConfig(
        # https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
        connection_uri="https://try.supertokens.com",
        # api_key="<API_KEY(if configured)>"
    ),
    framework="flask",  # Replace this with the framework you are using
    recipe_list=[
        webauthn.init(
            config=WebauthnConfig(
                override=WebauthnOverrideConfig(functions=override_webauthn_functions)
            )
        ),
        session.init(),  # initializes session features
    ],
)
```
</Tab>
</CodeGroup>

<DependentContent passive group="backend-language">
<ContentOption title="Node.js" value="nodejs">
<br />

#### Input properties

| Name | Type | Description | Default Value |
|----------|----------|-------------|---------------|
| `relyingPartyId` | `string` | The domain name of your application that the system uses for validating the credential. | Uses `getRelyingPartyId` from the recipe configuration, which defaults to the hostname of `appInfo.apiDomain` |
| `relyingPartyName` | `string` | The human-readable name of your application. | Uses `getRelyingPartyName` from the recipe configuration, which defaults to `appName` |
| `origin` | `string` | The frontend origin where the credential is created. | Uses `getOrigin` from the recipe configuration, which normally defaults to the configured website origin |
| `timeout` | `number` | The time in milliseconds that the user has to complete the credential generation process. | `60000` |
| `attestation` | `"none" \| "indirect" \| "direct" \| "enterprise"`  | The attestation conveyance preference requested from the authenticator. | `none` |
| `supportedAlgorithmIds` | `number[]` | The cryptographic algorithms that can generate credentials. Different authenticators support different algorithms. | `[-8, -7, -257]` |
| `residentKey` | `"discouraged" \| "preferred" \| "required"` | Whether the authenticator creates a discoverable credential. A discoverable credential may be synced or device-bound. | `required` |
| `userVerification` | `"discouraged" \| "preferred" \| "required"` | Whether user verification (like `PIN` or biometrics) is necessary. | `preferred` |
| `userPresence` | `boolean` | Whether the ceremony requires evidence of user interaction. This is separate from user verification. | `true` |
| `displayName` | `string` | The display name of the user. | The user's `email` property |
</ContentOption>
<ContentOption title="Python" value="python">
<br />

#### Input properties

| Name | Type | Description | Default Value |
|----------|----------|-------------|---------------|
| `relying_party_id` | `str` | The domain name of your application that the system uses for validating the credential. | Uses `get_relying_party_id` from the recipe configuration, which defaults to the hostname of `app_info.api_domain` |
| `relying_party_name` | `str` | The human-readable name of your application. | Uses `get_relying_party_name` from the recipe configuration which defaults to the `app_name` |
| `origin` | `str` | The frontend origin where the credential is created. | Uses `get_origin` from the recipe configuration, which normally defaults to the configured website origin |
| `timeout` | `int` | The time in milliseconds that the user has to complete the credential generation process. | `60000` |
| `attestation` | `"none" \| "indirect" \| "direct" \| "enterprise"`  | The attestation conveyance preference requested from the authenticator. | `none` |
| `supported_algorithm_ids` | `List[int]` | The cryptographic algorithms that can generate credentials. Different authenticators support different algorithms. | `[-8, -7, -257]` |
| `resident_key` | `"discouraged" \| "preferred" \| "required"` | Whether the authenticator creates a discoverable credential. A discoverable credential may be synced or device-bound. | `required` |
| `user_verification` | `"discouraged" \| "preferred" \| "required"` | Whether user verification (like `PIN` or biometrics) is necessary. | `preferred` |
| `user_presence` | `bool` | Whether the ceremony requires evidence of user interaction. This is separate from user verification. | `True` |
| `display_name` | `str` | The display name of the user. | The user's `email` property |
</ContentOption>
<ContentOption title="Go" value="go">
<br />

#### Input properties

| Name | Type | Description | Default Value |
|----------|----------|-------------|---------------|
| `relyingPartyId` | `string` | The domain name used to validate the credential. | Uses `GetRelyingPartyId`, which defaults to the hostname of `AppInfo.APIDomain` |
| `relyingPartyName` | `string` | The human-readable name of your application. | Uses `GetRelyingPartyName`, which defaults to `AppInfo.AppName` |
| `origin` | `string` | The frontend origin where the credential is created. | Uses `GetOrigin`, which normally defaults to the configured website origin |
| `timeout` | `*int` | The time in milliseconds available to complete credential creation. | `60000` |
| `attestation` | `*webauthnmodels.Attestation` | The attestation conveyance preference requested from the authenticator. | `AttestationNone` |
| `supportedAlgorithmIds` | `[]webauthnmodels.COSEAlgorithmIdentifier` | The allowed credential algorithms. | `[-8, -7, -257]` |
| `residentKey` | `*webauthnmodels.ResidentKey` | Whether the authenticator creates a discoverable credential. | `ResidentKeyRequired` |
| `userVerification` | `*webauthnmodels.UserVerification` | Whether user verification, such as a PIN or biometrics, is necessary. | `UserVerificationPreferred` |
| `userPresence` | `*bool` | Whether the ceremony requires evidence of user interaction. | `true` |
| `displayName` | `*string` | The display name of the user. | The user's email |
</ContentOption>
</DependentContent>

Keep the default `attestation: "none"` unless your relying party has a specific attestation policy. `"direct"` can expose identifying authenticator information and still requires you to validate the attestation statement and its certificate chain against trust anchors you maintain. Requesting direct attestation does not by itself make an authenticator trusted.

---

## Credential validation

When a user attempts to sign in, the authenticator uses their credential to sign an assertion on the client.
The frontend SDK uses [`navigator.credentials.get()`](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get) to start the authentication ceremony.

The server generates the options for signing the challenge through the backend SDK, and then sends them to the client.
To change those, you need to override the `signInOptions` function.


<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```ts
import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import WebAuthn from "supertokens-node/recipe/webauthn";

supertokens.init({
  framework: "express",
  supertokens: {
    // https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
    connectionURI: "https://try.supertokens.com",
    // apiKey: <API_KEY(if configured)>,
  },
  appInfo: {
    // learn more about this on https://supertokens.com/docs/references/backend-sdks/reference#sdk-configuration
    appName: "<YOUR_APP_NAME>",
    apiDomain: "<YOUR_API_DOMAIN>",
    websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
    apiBasePath: "/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    WebAuthn.init({
      override: {
        functions: (originalImplementation) => {
          return {
            ...originalImplementation,
            signInOptions: (input) => {
              return originalImplementation.signInOptions({
                ...input,
                timeout: 10 * 1000,
                userVerification: "required",
                userPresence: true,
                relyingPartyId: "example.com",
                origin: "https://example.com",
              });
            },
          };
        },
      },
    }),
    Session.init(), // initializes session features
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go check=false reason="Override excerpt; pass config to webauthn.Init in your recipe list."
config := &webauthnmodels.TypeInput{
	Override: &webauthnmodels.OverrideStruct{
		Functions: func(original webauthnmodels.RecipeInterface) webauthnmodels.RecipeInterface {
			originalSignInOptions := *original.SignInOptions
			signInOptions := func(
				relyingPartyID, relyingPartyName, origin string,
				timeout *int,
				userVerification *webauthnmodels.UserVerification,
				userPresence *bool,
				tenantID string, userContext supertokens.UserContext,
			) (webauthnmodels.SignInOptionsResponse, error) {
				customTimeout := 10 * 1000
				customUserVerification := webauthnmodels.UserVerificationRequired
				customUserPresence := true
				return originalSignInOptions(
					"example.com", "example", "https://example.com",
					&customTimeout, &customUserVerification, &customUserPresence,
					tenantID, userContext,
				)
			}
			original.SignInOptions = &signInOptions
			return original
		},
	},
}
```
</Tab>
<Tab title="Python" value="python">
```python
from typing import Any

from supertokens_python import InputAppInfo, SupertokensConfig, init
from supertokens_python.recipe import session, webauthn
from supertokens_python.recipe.webauthn import (
    RecipeInterface,
    WebauthnConfig,
    WebauthnOverrideConfig,
)
from supertokens_python.types.base import UserContext


def override_webauthn_functions(original_implementation: RecipeInterface):
    original_sign_in_options = original_implementation.sign_in_options

    async def sign_in_options(
        *,
        tenant_id: str,
        user_context: UserContext,
        **kwargs: Any
    ):
        return await original_sign_in_options(
            tenant_id=tenant_id,
            user_context=user_context,
            timeout=10 * 1000,
            user_verification="required",
            user_presence=True,
            relying_party_id='example.com',
            relying_party_name='Example',
            origin='https://example.com',
        )

    original_implementation.sign_in_options = sign_in_options
    return original_implementation

init(
    app_info=InputAppInfo(
        app_name="<YOUR_APP_NAME>",
        api_domain="<YOUR_API_DOMAIN>",
        website_domain="<YOUR_WEBSITE_DOMAIN>",
        api_base_path="/auth",
        website_base_path="/auth"
    ),
    supertokens_config=SupertokensConfig(
        # https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core.
        connection_uri="https://try.supertokens.com",
        # api_key="<API_KEY(if configured)>"
    ),
    framework='flask',  # Replace this with the framework you are using
    recipe_list=[
        webauthn.init(
            config=WebauthnConfig(
                override=WebauthnOverrideConfig(
                    functions=override_webauthn_functions
                )
            )
        ),
        session.init()  # initializes session features
    ]
)
```
</Tab>
</CodeGroup>

<DependentContent passive group="backend-language">
<ContentOption title="Node.js" value="nodejs">
#### Input properties

| Name | Type | Description | Default |
|----------|----------|-------------|---------|
| `relyingPartyId` | `string` | The domain name of your application that the system uses for validating the credential. | Uses `getRelyingPartyId` from the recipe configuration, which defaults to the hostname of `appInfo.apiDomain` |
| `relyingPartyName` | `string` | The human-readable name of your application. | Uses `getRelyingPartyName` from the recipe configuration, which defaults to `appName` |
| `origin` | `string` | The expected frontend origin for the authentication response. | Uses `getOrigin` from the recipe configuration, which normally defaults to the configured website origin |
| `timeout` | `number` | The time in milliseconds that the user has to complete the credential validation process. | `60000` |
| `userVerification` | `"discouraged" \| "preferred" \| "required"` | The parameter controls whether user verification (like `PIN` or biometrics) is necessary. | `preferred` |
| `userPresence` | `boolean` | Whether the ceremony requires evidence of user interaction. This is separate from user verification. | `true` |
</ContentOption>
<ContentOption title="Python" value="python">
#### Input properties

| Name | Type | Description | Default |
|----------|----------|-------------|---------|
| `relying_party_id` | `str` | The domain name of your application that the system uses for validating the credential. | Uses `get_relying_party_id` from the recipe configuration, which defaults to the hostname of `app_info.api_domain` |
| `relying_party_name` | `str` | The human-readable name of your application. | Uses `get_relying_party_name` from the recipe configuration which defaults to the `app_name` |
| `origin` | `str` | The expected frontend origin for the authentication response. | Uses `get_origin` from the recipe configuration, which normally defaults to the configured website origin |
| `timeout` | `int` | The time in milliseconds that the user has to complete the credential validation process. | `60000` |
| `user_verification` | `"discouraged" \| "preferred" \| "required"` | The parameter controls whether user verification (like `PIN` or biometrics) is necessary. | `preferred` |
| `user_presence` | `bool` | Whether the ceremony requires evidence of user interaction. This is separate from user verification. | `True` |
</ContentOption>
<ContentOption title="Go" value="go">
#### Input properties

| Name | Type | Description | Default |
|----------|----------|-------------|---------|
| `relyingPartyId` | `string` | The domain name used to validate the credential. | Uses `GetRelyingPartyId`, which defaults to the hostname of `AppInfo.APIDomain` |
| `relyingPartyName` | `string` | The human-readable name of your application. | Uses `GetRelyingPartyName`, which defaults to `AppInfo.AppName` |
| `origin` | `string` | The expected frontend origin for the authentication response. | Uses `GetOrigin`, which normally defaults to the configured website origin |
| `timeout` | `*int` | The time in milliseconds available to complete authentication. | `60000` |
| `userVerification` | `*webauthnmodels.UserVerification` | Whether user verification, such as a PIN or biometrics, is necessary. | `UserVerificationPreferred` |
| `userPresence` | `*bool` | Whether the ceremony requires evidence of user interaction. | `true` |
</ContentOption>
</DependentContent>
