<!-- tempo-docs-context -->
> Source: [/docs/accounts/authentication/passkeys](https://tempo.xyz/developers/docs/accounts/authentication/passkeys.md)
> Section: [Accounts](https://tempo.xyz/developers/docs/accounts.md). Create accounts, set up signing methods, policies, access keys, key rotation, and fees, and follow guides for users, automations, agents, and teams.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# Passkeys

A passkey lets only the customer approve the account's transactions, with Face ID, a fingerprint, or a security key.

<span id="what-a-passkey-is" />

## Overview

A passkey is the WebAuthn credential behind passwordless sign-in. It's a P-256 key that stays on the customer's device or security key and signs only when the customer approves. Tempo checks each passkey signature onchain. For payments without a prompt, add a [device key](https://tempo.xyz/developers/docs/accounts/authentication/device-keys). On a server, use a [private key](https://tempo.xyz/developers/docs/accounts/authentication/private-keys) instead.

<span id="passkey-authenticators" />

<span id="how-it-works" />

## Supported Authenticators

Passkeys work with Face ID and Touch ID, Windows Hello, an Android screen lock, and security keys such as YubiKey.

<span id="what-a-passkey-trusts" />

Your servers and wallet providers never hold the passkey. Its security rests on the customer's device. A synced passkey also rests on the service that syncs it: iCloud Keychain, Google Password Manager, or a password manager.

<span id="try-a-passkey-account" />

<span id="create-the-passkey" />

<span id="open-the-account-with-it" />

<span id="open-an-account-with-a-passkey" />

<span id="passkey-signer-weights" />

<span id="create-a-passkey-signer" />

## Create a Passkey

In the interactive web page, create a passkey account or reconnect an existing passkey, inspect and copy its address, and disconnect. Creating the account does not move or fund stablecoins.

The demo creates a passkey and shows the single-key account it signs for. On mainnet and testnet today, a passkey can be a single-key account's one key. Losing it loses the account.

:::warning
**Multiple signers arrive with the [T14 network upgrade](https://tempo.xyz/developers/docs/protocol/upgrades/t14).** Until T14 activates, an account with several signers and a threshold runs only on the [Tempo Accounts devnet](https://tempo.xyz/developers/docs/accounts/create#connect-to-the-devnet), not on mainnet or testnet, and may still change.
:::

On the Tempo Accounts devnet, make the passkey the first signer of a configurable account instead. It approves alone.

```ts [passkey.ts]
import { Account, WebAuthnP256 } from 'viem/tempo'

const credential = await WebAuthnP256.createCredential({ label: 'Acme' }) // [!code hl]
const passkey = Account.fromWebAuthnP256(credential) // [!code hl]
const account = Account.fromConfig({ address: 'infer', owners: [passkey] }) // [!code hl]
```

`account.address` receives stablecoins right away. The account's first transaction registers it onchain. Next, [add a recovery signer](https://tempo.xyz/developers/docs/accounts/apps/self-custodial-wallets) so a lost passkey doesn't lock the customer out. [Recommended signer setups](https://tempo.xyz/developers/docs/accounts/policies/signing-thresholds#recommended-signer-setups) gives the weights for customer accounts and treasuries.

<span id="passkey-limits" />

## Limits

* A passkey works only on its domain, the relying party ID (`rpId`), and that domain's subdomains. Pick the `rpId`, such as `acme.com`, before customers create passkeys. Pass it to both `WebAuthnP256.createCredential` and `Account.fromWebAuthnP256`.
* WebAuthn returns the public key only at creation. Save `credential.id` and `credential.publicKey`. Pass them to `Account.fromWebAuthnP256` when the customer returns.
* Passkeys work only over HTTPS or on `localhost`. A cancelled or timed-out prompt fails with `NotAllowedError`.
* A passkey on a security key isn't synced, so losing the key loses the signer.
* On mainnet and testnet, a passkey account is a single-key account and can't add a signer or swap its key. A synced passkey survives a lost phone only through its sync provider, such as iCloud Keychain or Google Password Manager. If the customer loses every synced copy, they lose the account and its funds.

## Related

[Device Keys](https://tempo.xyz/developers/docs/accounts/authentication/device-keys): Covers keys that pay from the customer's device without a prompt.

[Private Keys](https://tempo.xyz/developers/docs/accounts/authentication/private-keys): Covers keys in a wallet, a wallet provider, or your KMS or HSM.

[Set Up a Self-Custodial Wallet With a Provider](https://tempo.xyz/developers/docs/accounts/apps/self-custodial-wallets): Use for adding a recovery signer beside the customer's passkey.

[Signing Thresholds](https://tempo.xyz/developers/docs/accounts/policies/signing-thresholds): Covers signer weights and the threshold a transaction must reach.
