[API reference](https://evolu.dev/docs/api-reference) › [@evolu/web](https://evolu.dev/docs/api-reference/web) › createPasskeyAuth

```ts
function createPasskeyAuth(
  __namedParameters: CreatePasskeyKeyProviderOptions & {
    appName: string & Brand<"UrlSafeString"> & Brand<"AppName">;
  },
): Task<
  PasskeyAuth,
  UnknownError,
  CreateDbWorkerDep &
    CreateBroadcastChannelDep &
    CreateMessageChannelDep &
    DevicePersistenceDep &
    LockManagerDep &
    ReloadAppDep &
    Partial<ConsoleDep> &
    Partial<CreateMemoryInstanceWorkerDep> &
    Partial<FlushSyncDep> &
    Partial<RequestPersistentStorageDep> &
    StoredWorkerDep
>;
```

Defined in: [packages/web/src/local-first/Passkey.ts:173](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/web/src/local-first/Passkey.ts#L173)

Unlocks the app's [DeviceSecret](https://evolu.dev/docs/api-reference/common/local-first/Auth/variables/DeviceSecret) with a passkey, for
[createEvoluApp](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvoluApp)'s `DeviceSecret` auth on the web, and decides when the
app can offer to start over. It reads, without a prompt, whether the browser
keeps anything and whether a wrapped DeviceSecret is stored, so the app can
label its first screen, such as "Unlock" or "Create account". Where the
browser keeps nothing, as in Safari's Private Browsing or a Firefox private
window, its state is `NotPersisted`, and the app starts without a passkey,
with `InstantStart`, in memory.

Call [PasskeyAuth.unlock](https://evolu.dev/docs/api-reference/web/interfaces/PasskeyAuth#unlock) in a user gesture, such as a button click,
because some browsers allow a passkey prompt only in one. The app shows its
own UI and error messages for each [PasskeyAuthState](https://evolu.dev/docs/api-reference/web/type-aliases/PasskeyAuthState), its own
confirmation before a start over loses the stored secret, and decides what
happens once it's `Unlocked`, such as creating or restoring an account. A
failure keeps the state usable, so the user can try again.

Its state doesn't follow other tabs. A start over forgets only a pending key
without asking, under the lock setups take, so another tab's setup can't
store a secret in between. Disposing it aborts the unlock or start over in
progress.

It uses [unlockWrappedDeviceSecret](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/unlockWrappedDeviceSecret), [hasWrappedDeviceSecret](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/hasWrappedDeviceSecret), and
[forgetWrappedDeviceSecret](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/forgetWrappedDeviceSecret) with [createPasskeyKeyProvider](https://evolu.dev/docs/api-reference/web/functions/createPasskeyKeyProvider).