Javlon Baxtiyorov
← All projects
Open library  ·  alpha · v0.1  ·  2025 – present

Passwordless Trust

Phishing-resistant login, without owning your auth.

A FastAPI library that adds passkey / WebAuthn login — the “sign in with Face ID or fingerprint” standard — without taking over the rest of your authentication.

Role
Author & maintainer
Impact
Secure-by-default WebAuthn
Open source
1★ · Python
PyPI downloads
516 · 285/30d
Year
2025 – present
Fig. 2 — Verification Mechanism: cutaway of a lock showing tumblers, ratchet wheel with pawl for monotonic counter clone detection CHALLENGE SIGNATURE TUMBLER PINS SHEAR LINE ORIGIN CHECK RATCHET WHEEL MONOTONIC COUNTER · CLONE DETECT PAWL ONE DIRECTION ONLY fig. 2 — verification mechanism
fig. — passwordless trust

The problem

WebAuthn is the strongest login we have and the easiest to implement subtly wrong, leaving a lock that looks closed but isn't.

WebAuthn is the strongest mainstream authentication we have and the easiest to implement subtly wrong. Skip an origin check, reuse a challenge, ignore the signature counter, and you have built a lock that looks closed and isn't. Secure-by-default means the unsafe path should be the one you have to go out of your way to take.

What I built

The library owns exactly one thing: ceremony verification. Single-use, TTL-bound challenges. Strict origin and relying-party validation. A monotonic signature counter that detects cloned authenticators. Credential and challenge storage sit behind async protocols, with in-memory, stateless, SQLAlchemy, and Redis adapters supplied. The clone-detection ratchet only turns one direction — like the counter it models. I drew it that way because that's what it is.

Key decisions

It is auth-agnostic and ORM-agnostic on purpose. It verifies the passkey and returns the user — your session, your JWT, your database, your call, exposed through explicit hooks. Owning only the hard security problem is the whole point: a library should be small where it is dangerous and silent everywhere else. Alpha, and I say so. An archive records the date and the revision; it doesn't pretend the ink is older than it is.

The result

It performs the cryptographic ceremony correctly — challenges, origin checks, clone detection — and hands you back the verified user, so the secure path is the default one.

Secure-by-default WebAuthn

Built with

WebAuthn / PasskeysSingle-use TTL challengesMonotonic counter · clone detectionStrict origin / RP checksAsync-native · fully typedRedis · SQLAlchemy · in-memory adapters

Lessons from the bench

  •  Secure-by-default means the unsafe path should be the one you have to go out of your way to take.
  •  The clone-detection ratchet only turns one direction — like the counter it models. I drew it that way because that's what it is.
  •  Alpha, and I say so. An archive records the date and the revision; it doesn't pretend the ink is older than it is.

See the code

Open fastapi-passkeys on GitHub