Two-step sign-in: authenticator app, security keys and passkeys
This commit is contained in:
@@ -67,6 +67,14 @@ The screenshots show sample data from the built-in simulator.
|
||||
- **Sign-in:** one or more users, all admins. Passwords are stored as argon2id hashes.
|
||||
After 5 failed attempts, sign-in is locked for 15 minutes. Sessions use an
|
||||
HttpOnly, SameSite=Strict cookie and last 12 hours by default.
|
||||
- **Two-step sign-in:** each user can add an authenticator app (TOTP), security
|
||||
keys such as a YubiKey, and passkeys that sign in without a password, under
|
||||
My account. Turning it on gives 10 one-time recovery codes. An admin can
|
||||
require it for everyone (Settings → Sign-in) and reset it for a user who lost
|
||||
their phone or key. Security keys and passkeys use WebAuthn and need the
|
||||
server's domain name with a trusted certificate (Let's Encrypt, certificate
|
||||
files, or a reverse proxy); on a self-signed certificate or an IP address,
|
||||
only the authenticator app is offered. API tokens never need a second step.
|
||||
- **API tokens** are stored only as hashes and can be read-only or full access.
|
||||
- `config.json` holds the server private key and is readable only by the
|
||||
service (0600).
|
||||
@@ -235,6 +243,12 @@ GET. Full-access tokens can do everything the web interface does except backup
|
||||
and restore. Users, passwords and API tokens need a full-access token even for
|
||||
reading.
|
||||
|
||||
For a user with two-step sign-in, `POST /auth/login` answers
|
||||
`{"mfa": true, "ticket": "…", "methods": ["key", "totp", "recovery"]}`
|
||||
instead of starting a session; the ticket is good for 5 minutes, and one of
|
||||
the `/auth/login/…` steps turns it into the session. `PATCH /settings`
|
||||
`{"signin": {"requireMfa": true}}` requires two-step sign-in for every user.
|
||||
|
||||
`POST /users` and `POST /users/{id}/reset-password` take
|
||||
`{"password": "…", "mustChangePassword": true}`; with `true` (the default) the
|
||||
user can do nothing but choose a new password at the next sign-in.
|
||||
@@ -242,7 +256,14 @@ user can do nothing but choose a new password at the next sign-in.
|
||||
```
|
||||
POST /auth/login · /auth/logout GET /auth/me POST /auth/password (own password)
|
||||
GET /users POST /users PATCH /users/{id} DELETE /users/{id}
|
||||
POST /users/{id}/reset-password
|
||||
POST /users/{id}/reset-password POST /users/{id}/reset-mfa
|
||||
GET /auth/options (public: is passkey sign-in offered here)
|
||||
POST /auth/login/totp · /auth/login/recovery {"ticket", "code"}
|
||||
POST /auth/login/key/begin {"ticket"} · /auth/login/key/finish?ticket= (body: the WebAuthn credential)
|
||||
POST /auth/login/passkey/begin · /auth/login/passkey/finish?id=
|
||||
signed in: GET /auth/mfa · POST /auth/mfa/totp/setup · /auth/mfa/totp/confirm · DELETE /auth/mfa/totp
|
||||
signed in: POST /auth/mfa/keys/begin {"passkey"} · /auth/mfa/keys/finish?name= · PATCH|DELETE /auth/mfa/keys/{id}
|
||||
signed in: POST /auth/mfa/recovery-codes
|
||||
GET /status GET /stats?range=24h|7d|30d|90d
|
||||
GET /server PATCH /server POST /server/rotate-key GET /server/detect-ip
|
||||
GET /peers POST /peers (returns the config and QR once)
|
||||
|
||||
Reference in New Issue
Block a user