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#
-
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 withoutwwworapp, such asexample.com. A passkey made forexample.comalso works onapp.example.com,www.example.comand your mobile apps.Choose carefully. Every passkey is tied to this value, so changing it later means everyone has to add their passkeys again.
-
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 withhttps://. -
Set both values
In your production environment:
terminalWEBAUTHN_RP_ID=example.com WEBAUTHN_ORIGINS=https://example.com,https://app.example.com -
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-providersshows✓ Passkeys in browserswith your domain and addresses.- When your frontend starts adding a passkey,
POST /v1/auth/passkeys/registrationreturns 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.