[← 10 — The signature counter](10-signature-counter.md) · [index](README.md) # Should you build this ## Yes, if - **You have consumer users and a password reset problem.** Passkeys remove credential stuffing and phishing in one move, and both are probably in your incident history. - **You already federate.** If most users arrive through Google or Apple, they already have a passkey-capable account recovery story, and you are adding a first-party option rather than inventing one. - **You can afford a second credential.** Passkeys are excellent when a user has two. They are a support burden when a user has one and drops their phone in a canal. - **Your users are on current devices.** Platform authenticator support is effectively universal on hardware from the last few years, and effectively absent below it. ## No, or not yet, if - **Your recovery path is an email magic link and nothing else.** Then your security level is your users' email accounts, and you have added complexity without adding strength. Fix recovery first; the passkeys will still be there. - **You cannot run HTTPS everywhere, including in development.** `localhost` is the only exception browsers make. A staging environment on plain HTTP simply cannot run the ceremony. - **You are behind a load balancer without sticky sessions and cannot add shared session storage.** The challenge lives in the `HttpSession`. Registration will fail intermittently and the logs will not obviously say why. - **You need attestation.** Verifying which model of authenticator a user holds is a real project on top of what Spring Security gives you ([05](05-defaults.md)), and requires a trust-anchor source such as the FIDO Metadata Service. - **You are counting on clone detection.** You do not have it ([10](10-signature-counter.md)). ## What it actually costs The Spring Security part is genuinely small: one dependency, one DSL block, one `UserDetailsService`. Working passkey login in an afternoon is a fair estimate, and the built-in registration and login pages mean you can demonstrate it before writing any JavaScript. The rest is not small: | work | why it is not optional | |---|---| | a delivery channel for one-time tokens | the bootstrap problem ([06](06-the-bootstrap-problem.md)) | | a credential management UI | list, label, delete, and refuse to delete the last one | | recovery policy, rate limits, notifications | this is where your real security level is set | | a real front end | the built-in pages are a reference, not a product | | persistence and backups | the credential table is the account ([09](09-persistence.md)) | | a fallback for unsupported clients | which means keeping passwords or federation alive during the migration | The honest framing is that Spring Security 7.1 has removed the protocol from your list of problems, and left you with all the product ones. That is a good trade — it is just not the same as being finished. ## Where to go next - [`docs/01`–`18`](../) — JWT authentication and OAuth2 resource servers, the other two projects in this repository - [`docs/authorization-server/`](../authorization-server/README.md) — running your own OAuth2 / OIDC provider, which is the other way to solve the bootstrap problem - [WebAuthn Level 3](https://www.w3.org/TR/webauthn-3/) — the specification, and readable - [passkeys.dev](https://passkeys.dev) — device and browser support, and the UX conventions users now expect [← 10 — The signature counter](10-signature-counter.md) · [index](README.md)