Authentication¶
FenLiu has two independent authentication layers: session-based web UI auth for browser access, and API key auth for machine/bot access.
Web UI Authentication¶
All browser-facing routes (dashboard, review queue, settings, streams, statistics) are protected by UIAuthMiddleware.
Single-user scope¶
FenLiu supports exactly one account. The username is always admin and is not configurable. There is no user management UI, no roles, and no per-user data isolation. If you need multiple operators, run separate instances or put a multi-user auth proxy (Authelia, Authentik, etc.) in front.
First-run setup¶
On first start, no password is stored. UIAuthMiddleware detects this and redirects all web UI requests to /setup. The setup page explains single-user scope and when it is acceptable to run without authentication. After submitting a password, it is hashed with PBKDF2-SHA256 and stored as an AppSetting row — no Alembic migration required. The browser is then redirected to /login.
Session flow¶
After login, a Starlette SessionMiddleware session is created with authenticated=True. The session is signed using SECRET_KEY. Logout clears the session and redirects to /login.
Password storage¶
Passwords are hashed with PBKDF2-SHA256 via the stdlib hashlib module (no additional dependencies). Verification uses hmac.compare_digest for timing-safety.
Bypass mode¶
Set UI_AUTH_ENABLED=false to skip UIAuthMiddleware entirely. This is acceptable only for:
- A personal machine accessible only to you
- A private home LAN with no port forwarding and no other users
- Behind a hardware firewall where only you have access
It is not acceptable if the instance is reachable from the public internet, shared hosting, any VPN/WireGuard network with other participants, or any network where other people could reach port 8000.
Public endpoints (always accessible)¶
UIAuthMiddleware never redirects these paths regardless of auth state:
/login,/logout,/setup/static/*/api/*/health/info
Credential management¶
Change the password at Settings → Change Password (three-field form: current password, new password, confirm new password). To reset credentials when locked out: stop the app, delete or wipe the ui_password_hash AppSetting row from the database, and restart — the app will redirect to /setup.
API Key Authentication¶
All /api/v1/* endpoints (except the three listed below) require an X-API-Key header. API keys are managed by APIKeyMiddleware.
Unprotected endpoints¶
GET /health— health checkGET /info— application infoGET /api/v1/api-keys/status— whether a key is configured (safe to expose)
Bootstrap flow¶
On first run, no API key exists. POST /api/v1/api-keys/generate accepts the request without authentication. Once a key is stored, all subsequent generate and revoke calls must supply the current key in X-API-Key.
Usage¶
curl -H "X-API-Key: your-api-key" http://localhost:8000/api/v1/posts
Error responses¶
| Situation | Status | Body |
|---|---|---|
| Missing header | 401 | {"detail": "Missing X-API-Key header"} |
| Invalid key | 401 | {"detail": "Invalid API key"} |
Next Steps¶
- Configuration —
UI_AUTH_ENABLED,SECRET_KEY - Container Deployment — first-run auth in containers
- API Overview — all API endpoints