feat: multi-user authentication (dual mode)
Add optional login protection for the web UI/API, intended for shared machines (e.g. AI servers). Dual mode: with no users configured the API and web UI are open (as before); once at least one user exists, every /api/* and /ws/* endpoint requires a valid session. - bcrypt password hashing: passwords stored as $2b$ hashes in /etc/nvcurve/users.json (0600, root-owned); plaintext never persisted. - 24-hour sessions: HttpOnly cookie for browsers, Authorization: Bearer token for CLI/scripts; in-memory, invalidated on server restart. - Multi-user: multiple named accounts (no shared-password mode). - New CLI: nvcurve user add|list|remove|set-password (root for mutating ops; password always prompted, never a CLI argument). - New endpoints: GET /api/ping (public), /api/auth/status|login|logout|users. - Web UI: sign-in screen when auth is enabled; status bar shows the signed-in user with sign-out; expired sessions (401) re-show sign-in. - Brute-force lockout: 10 failed logins/IP within 5 min -> 15 min lockout. - New dependency: bcrypt. Also: LSP config (pyrightconfig.json) pointing at the project .venv, and small error-handling cleanups in daemon.py/server.py.
This commit is contained in:
1 parent
af23a10f25
commit
bbd692ea2e
16 files changed
+2085
-483
No files matched your search
+61
-3
@@ -38,7 +38,7 @@ nvcurve serve stop # Stop the server
|
||||
The curve editor displays your GPU's V/F curve as an interactive graph with draggable points.
|
||||
|
||||
| Action | How |
|
||||
|---|---|
|
||||
| --- | --- |
|
||||
| Select a point | Click on it |
|
||||
| Multi-select | Shift+click to add/remove points |
|
||||
| Select all active points | Ctrl/Cmd+A |
|
||||
@@ -58,7 +58,7 @@ The curve editor displays your GPU's V/F curve as an interactive graph with drag
|
||||
The point table provides a spreadsheet-like view of all curve points with their frequency, voltage, and offset values.
|
||||
|
||||
| Action | How |
|
||||
|---|---|
|
||||
| --- | --- |
|
||||
| Select a point | Click a row |
|
||||
| Toggle selection | Ctrl/Cmd+click |
|
||||
| Range select | Shift+click or drag across rows |
|
||||
@@ -88,6 +88,64 @@ Data is streamed via WebSocket from the backend at a configurable poll interval
|
||||
|
||||
When multiple NVIDIA GPUs are detected, a GPU selector dropdown appears in the status bar. Switching GPUs resets pending edits, selection state, and monitoring for the new target.
|
||||
|
||||
## Authentication (Multi-User)
|
||||
|
||||
By default the server runs **without** authentication — anyone who can reach the port can use it. This is fine for a single-user workstation, but on a shared AI server you will want to lock it down. nvcurve uses a **dual mode**:
|
||||
|
||||
- **No users configured** → the API and web UI are open, exactly as before.
|
||||
- **One or more users configured** → every API and WebSocket endpoint requires a login. The web UI shows a sign-in screen first.
|
||||
|
||||
There is no "single shared password" mode — once you add a user, each person gets their own account.
|
||||
|
||||
### Managing users
|
||||
|
||||
Users are stored as **bcrypt** hashes in `/etc/nvcurve/users.json` (mode `0600`, root-owned). Plaintext passwords are never written to disk. Manage them with the CLI (root required to add/remove/change):
|
||||
|
||||
```bash
|
||||
# Add a user (prompts for the password twice). Never pass the password as an
|
||||
# argument — it would be visible in the process list and recorded in sudo logs.
|
||||
sudo nvcurve user add alice
|
||||
sudo nvcurve user add bob
|
||||
|
||||
# List users
|
||||
nvcurve user list
|
||||
|
||||
# Change a user's password
|
||||
sudo nvcurve user set-password alice
|
||||
|
||||
# Remove a user
|
||||
sudo nvcurve user remove bob
|
||||
```
|
||||
|
||||
Adding the first user **switches the server into authenticated mode immediately** (no restart needed). Removing the last user switches it back to open mode.
|
||||
|
||||
### Signing in
|
||||
|
||||
- **Web UI:** open the app as usual; if authentication is enabled you will see a sign-in screen. Enter your username and password.
|
||||
- **CLI / scripts:** the Python client can authenticate and reuse the session:
|
||||
|
||||
```python
|
||||
from nvcurve.client import NvCurveClient
|
||||
client = NvCurveClient(base="http://127.0.0.1:8042")
|
||||
client.login("alice", "S3cret!") # stores the session token
|
||||
print(client.gpu()) # subsequent calls are authorized
|
||||
```
|
||||
|
||||
Or pass a token you already have: `NvCurveClient(base=..., token="...")`.
|
||||
|
||||
### Sessions
|
||||
|
||||
- A successful login creates a session that **lasts 24 hours**, after which a new login is required.
|
||||
- Browsers receive the session as an `HttpOnly` cookie; CLI/scripts use the returned token as an `Authorization: Bearer <token>` header.
|
||||
- Sessions are kept in server memory, so a server restart invalidates them (users must sign in again).
|
||||
- A per-IP lockout (10 failed attempts within 5 minutes → 15-minute lockout) slows down brute-force guessing.
|
||||
|
||||
### Security notes
|
||||
|
||||
- The user store file should stay root-owned and `0600` (the CLI enforces this).
|
||||
- The web UI and API are still only as safe as the network path to the server — bind to a trusted interface (`--host`) and/or firewall the port. Authentication protects against casual access, not a determined network attacker.
|
||||
- The `nvcurve user` commands and the user store require root; day-to-day sign-in does not.
|
||||
|
||||
## CLI Reference
|
||||
|
||||
The CLI is designed for scripting, headless use, and quick operations. All write commands support `--dry-run` to preview changes.
|
||||
@@ -198,7 +256,7 @@ sudo nvcurve service configure --host 0.0.0.0 --port 8042
|
||||
## Configuration Files
|
||||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| --- | --- |
|
||||
| `/etc/nvcurve/config.json` | Persistent config (host, port, auto-serve, default profiles) |
|
||||
| `/etc/nvcurve/profiles/*.json` | Saved profiles |
|
||||
| `/var/cache/nvcurve/snapshots/` | Auto-saved snapshots before writes |
|
||||
|
||||
Reference in new issue
Block a user