Register
/api/auth/email/send-verification after sign-in. The user can keep using the app while their email is unverified. Gate sensitive flows on User.emailVerified.
Validation rules
displayName defaults to the email if omitted.
Log in
From the SDKs
Password hashing
Pylon usesargon2 with the Argon2id variant, the winner of the Password Hashing Competition and the OWASP recommendation. It resists both side-channel attacks (Argon2i) and GPU-based brute-force (Argon2d) by design.
Default parameters:
Each hash is self-describing. The algorithm parameters are stored in the hash string, so future Pylon versions can rotate them without breaking existing passwords.
Password reset
Pylon ships a built-in “forgot password” flow. Two endpoints email a single-use reset link and change the password after the user clicks it: 1. Request a reset link. The user submits their email:200 { "sent": true }, whether or not the email is
registered. The endpoint is rate-limited and equalizes response timing
across the registered and not-registered paths, so it cannot be used to
enumerate accounts. When the email exists, Pylon emails a link of the form
<public-url>/reset-password?token=<token>.
2. Complete the reset. Your /reset-password page reads the token
from the URL and POSTs it with the new password:
passwordHash, revokes every
existing session for that user, and mints a fresh one:
If you do not want a password-reset UI, run users through the
magic-code flow instead. It mints a session without a
password. Then update
User.passwordHash yourself from an authenticated
action.
Configuring the User entity
Password auth expects aUser entity with these fields (auto-created by pylon init):
passwordHash is optional because users who signed up via OAuth or magic code never had one. emailVerified is null until they prove control of the email.
Security notes
- Never deserialize
AuthContextfrom request body. The Rust side intentionally doesn’t deriveDeserializeso a client can’t forgeis_admin: true. Identity comes from the session lookup, not the wire. /api/auth/sessionPOST is gated — only dev mode or admin token can mint a session for an arbitrary user_id. Your registration/login endpoints are the only public ways to obtain a token.- Sessions expire after 30 days by default — see Sessions to change.
/loginis rate-limited by default — the built-in per-IP/per-email limiter throttles the credential bucket (login, register, reset, TOTP verify) and returns429 RATE_LIMITEDwith aretry_afterhint on abuse. Pylon Cloud layers additional per-IP limiting at the edge.
When to use password vs alternatives
Use password when:- Email isn’t reliable (offline-first apps, regions with poor SMTP delivery)
- Compliance requires it
- Users explicitly prefer it