apistockdocs
v0.4 GitHub apistock.dev
Guides/Set up sign-in

Passkeys

A passkey lets someone sign in with Face ID, Touch ID, Windows Hello, their phone or a security key, instead of typing a password. It can replace the password completely, or be the second step after one. Passkeys can't be phished: each one only works on the website it was created for.

Browsers need no account with Apple or Google for this. You tell your app two things: your domain, and the addresses of the web pages that use passkeys.

Variable Secret? What it is Example
WEBAUTHN_RP_ID No Your domain, which every passkey is tied to example.com
WEBAUTHN_ORIGINS No The web addresses of the pages that use passkeys, separated by commas https://app.example.com

On your computer#

Nothing to set. Passkeys work on localhost. Open your app at http://localhost:8080, not http://127.0.0.1:8080: browsers don't allow passkeys on IP addresses.

For production#

  1. Choose your passkey domain

    This is WEBAUTHN_RP_ID. RP stands for "relying party": the site people sign in to. Use the domain people see, usually without www or app, such as example.com. A passkey made for example.com also works on app.example.com, www.example.com and your mobile apps.

    Choose carefully. Every passkey is tied to this value, so changing it later means everyone has to add their passkeys again.

  2. List the pages that use passkeys

    This is WEBAUTHN_ORIGINS: the addresses of your web frontends, as scheme and host only, with no path and no trailing slash. Separate several with commas. Each must be your passkey domain or one of its subdomains, and must start with https://.

  3. Set both values

    In your production environment:

    terminal
    WEBAUTHN_RP_ID=example.com
    WEBAUTHN_ORIGINS=https://example.com,https://app.example.com
    
  4. Let those pages call your API

    Add the same addresses to APP_CORS_ORIGINS. Browsers block requests from a page to an API on another address unless the API allows it, and this is where you allow it.

If WEBAUTHN_RP_ID is empty in production, passkeys are turned off, and passkey requests answer 503 passkeys_unavailable.

Check it works#

  • go run ./cmd/api auth-providers shows ✓ Passkeys in browsers with your domain and addresses.
  • When your frontend starts adding a passkey, POST /v1/auth/passkeys/registration returns options containing "rp": {"id": "example.com"}.

If something goes wrong#

What you see What it means
SecurityError in the browser's console The page's address isn't on WEBAUTHN_RP_ID, doesn't use https, or is an IP address
A CORS error in the browser's console The page's address is missing from APP_CORS_ORIGINS
503 passkeys_unavailable WEBAUTHN_RP_ID is empty in production

Next, if you have an iOS or Android app: Passkeys in mobile apps.

esc
↑↓ move↵ openesc close