Lion Cipher Lab

Add passkey login to a web app you build (the relying-party side of WebAuthn)

Why it matters

Every 'add passkeys' ticket eventually lands on a developer, and the industry's guidance mostly stops at the marketing layer: passkeys are phishing-resistant, turn them on. That is true and it is not enough to ship with. The server half -- the relying party -- is where the real decisions live: what you store, what you compare the response against, what you do when the user's laptop goes in a river. This lab has you build that half end to end in about a hundred lines of Flask, so 'the browser handles it' stops being a hand-wave. Then it has you break your own server on purpose: point…

What you'll learn

Steps in this lab

  1. The four parties, and the one that is your job
  2. Why localhost needs no TLS certificate (and why that is the ONLY exception)
  3. Create the project and install the two dependencies
  4. Write /register/options -- every field, and what it decides
  5. Write the page: navigator.credentials.create() and the base64url dance
  6. Write /register/verify -- three expectations, then store the public key
  7. Write the login half: /login/options and /login/verify
  8. Run it -- and what to do if you have no fingerprint reader
  9. Break it on purpose (1): point expected_origin at the wrong place
  10. Break it on purpose (2): stop discarding the challenge and replay a login
  11. The edges that decide whether a real rollout survives: recovery, UV, discoverability
  12. The judgment to walk away with

Open the full interactive lab →