Enable passkeys in a Laravel 13 app so users can sign in with Face ID, Touch ID, Windows Hello, or a security key. This is for Laravel developers who want a faster sign-in flow without adding another auth package. Budget about 5 to 10 minutes for a clean starter-kit setup.

Quick Answer: Laravel 13 adds first-party passkey support through its authentication stack, so the fastest path is to create or update a Laravel 13 app, use the official starter kit or Laravel Fortify, migrate your database, then register a passkey from your normal sign-up or account flow. Once it is saved, supported devices can log in with biometrics or a hardware key.

What you need first

Why this trick is worth doing

Traditional sign-in secrets are easy to reuse, easy to phish, and annoying for users. Passkeys remove most of that friction. Laravel 13 matters here because the framework now documents passkeys as part of its first-party auth story instead of pushing you toward a pile of custom WebAuthn glue.

How to enable Laravel 13 passkeys

1. Start from Laravel 13 and the official auth stack

If you are building a new app, create it with the official starter kit flow described in the starter kit documentation. If you already have an app and want a frontend-agnostic backend, install Fortify.

composer create-project laravel/laravel my-app
cd my-app
composer require laravel/fortify

Expected check: Your app runs locally and your auth routes exist. If you use Fortify, php artisan route:list should show login and registration routes.

2. Enable the passkeys-ready auth flow

For starter-kit apps, make sure you use the Laravel 13 auth scaffolding path that includes passkeys. For headless apps, publish Fortify and wire it into your existing auth UI.

php artisan fortify:install
npm install
npm run build

If you are following the Laravel 13 passkeys docs directly, use the passkeys-enabled starter-kit option shown in the official authentication docs: Laravel 13 passkeys documentation.

Expected check: You can open your local auth pages or API-backed auth UI without missing view, route, or asset errors.

3. Run the database migrations

The auth scaffolding needs its tables in place before passkey registration works.

php artisan migrate

Expected check: Migrations finish cleanly, and your database now contains the tables added by the auth install. In a normal starter-kit flow, you should also have your users table ready for account creation.

4. Register a user and save the first passkey

Open your app in the browser, go through the normal registration or account-security flow, and choose the passkey option when prompted. Your device should hand off to Face ID, Touch ID, Windows Hello, or your hardware key.

Expected check: After approving the device prompt, your app should return to the authenticated session without asking for the older credential flow on that sign-in step.

5. Test passkey sign-in on a fresh session

Log out, open a private window, or use a second browser profile. Then sign in again using the saved passkey.

Expected check: The browser should show a system-level passkey prompt. After confirmation, Laravel should create the user session normally.

Common mistakes

  • Mixing old auth scaffolding with Laravel 13 assumptions. If your app started on an older auth package or custom login stack, update deliberately instead of assuming passkeys appear automatically.
  • Skipping migrations. The UI may look ready while the backend storage is not.
  • Testing in an unsupported browser or device flow. Passkeys depend on browser and OS support.
  • Expecting Sanctum alone to provide registration and login screens. Sanctum handles API token and session auth, while starter kits or Fortify handle the actual auth flow.

Troubleshooting

  • No passkey prompt appears: Confirm your browser, OS, and device support passkeys, then retry in a fresh session.
  • Fortify routes work but your UI does not: Recheck your frontend form actions, CSRF setup, and published Fortify config.
  • Registration succeeds but login falls back to the older sign-in form: Make sure the passkey was actually enrolled on the account, then remove the session cookie and test again.
  • Headless app confusion: Read Laravel’s separation of concerns again. Fortify handles auth backend routes, and Sanctum handles API tokens and SPA session auth.

Direct references

Related reads

Try this next

Once passkeys work locally, test the same flow on one second device and one private browsing session. If both succeed, you have a much better signal than a single happy-path demo. Passkeys are great, but fake confidence is still free.