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
Why Argon2id?
Pylon usesargon2 with the Argon2id variant — winner of the Password Hashing Competition and the OWASP recommendation. It’s resistant to 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 that email a single-use reset link and swap the password once 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 / not-registered paths, so it can’t 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’d rather not surface a password-reset UI at all, you can instead run
users through the magic-code flow (which mints a session
without a password) and 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