Document a concrete auth design for the deferred permissions work
Planning only, no code yet. Per-role PIN codes (not named accounts - a shared trackside laptop doesn't want individual logins), an optional IP/host allowlist as a separate complementary layer, and 2FA deliberately left out unless a club actually exposes the server past their own LAN. Flags one open question for the user to decide before implementation starts: auth off by default vs. on by default with an auto-generated Admin PIN on first run. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,12 @@ The application version is maintained in `package.json` and displayed in the adm
|
||||
|
||||
No changes recorded yet.
|
||||
|
||||
## 1.21.2 - 2026-09-12
|
||||
|
||||
### Changed
|
||||
|
||||
- Documented a concrete auth design in ROADMAP.md ("Permissions and mobile Race Control"): per-role PIN codes rather than named accounts, an optional IP/host allowlist as a separate complementary layer, and 2FA deliberately left out unless a club actually exposes the server past their own LAN. Planning only - no auth code shipped yet.
|
||||
|
||||
## 1.21.1 - 2026-09-12
|
||||
|
||||
### Changed
|
||||
|
||||
11
ROADMAP.md
11
ROADMAP.md
@@ -155,6 +155,17 @@ Deferred 2026-09-09 at the user's request - requires a paid third-party neural T
|
||||
|
||||
Deferred 2026-09-09 at the user's request - the largest remaining item, on par with or bigger than the full optimistic-locking rework already deferred under section 2. Today there is no login or authorization at all: anyone reaching the server on the network has full admin access. Building this needs an identity system that doesn't exist yet (no user accounts, no sessions), server-side authorization on every mutating endpoint (not just hiding UI controls), and a genuinely new "compact mobile Race Control" surface (start/stop, track call, flags, next heat) - plus a real decision on how login should work in practice on a shared trackside laptop (PIN codes per role? named accounts? offline/LAN-only requirement?) before any of it can be designed, let alone built. Revisit as its own dedicated design conversation.
|
||||
|
||||
### Recommended auth design (discussed 2026-09-12, not yet built)
|
||||
|
||||
The user framed the actual threat model clearly: this normally runs on a trusted local race-day LAN, so a random internet attacker isn't the realistic concern - but someone else on that same LAN/venue WiFi being able to open the admin UI and interfere with a live race (stop a session, change results, trigger the unauthenticated `/api/update/run` restart from the audit follow-up above) is a real, low-effort risk worth closing. That framing should drive the design: **simple enough for volunteers on a shared trackside laptop, not an internet-grade identity system.**
|
||||
|
||||
- **PIN codes per role, not named accounts.** One shared PIN each for Admin, Race Director, Speaker, and Read-only (matching the capabilities list below) - a race club hands a laptop between whoever's running the desk that night; individual logins would just add friction nobody wants. Entering a PIN issues a signed, long-lived token (HMAC'd server-side, no session store needed - a secret already has to live somewhere, e.g. a value in `data/`, generated on first run) stored as a cookie, so it survives normal use for weeks and specifically **survives the server restarting** (relevant since the update checker and a power blip both restart the process mid-event).
|
||||
- **IP/host allowlist as a separate, complementary layer**, per the user's own question - not instead of the PIN, in addition to it: an optional `RC_ADMIN_ALLOWED_CIDRS` env var (same shape as the existing `RC_ALLOWED_ORIGINS`) that, when set, rejects admin requests from outside the listed ranges before the PIN even matters. Left unset by default - forcing IP configuration would break the simple "clone it and it just works" flow this app has always had, but a club that wants belt-and-suspenders on their venue's fixed subnet can turn it on.
|
||||
- **2FA: explicitly not part of this.** Only relevant if a club deliberately exposes the server past their own LAN (port-forwarded for a remote stream day, say) - a real but separate scenario from "someone else at the track." If that ever comes up, the natural shape is requiring a TOTP code on top of the PIN specifically for requests arriving from outside the allowlisted ranges, not a blanket requirement that would slow down the normal trackside case for no benefit. Not planned unless a club actually asks for internet-facing access.
|
||||
- **Server-side enforcement on every mutating endpoint**, not just hiding buttons (this was already the plan below) - a small role-to-endpoint capability map, in the same spirit as the `MANAGE_TAB_TARGETS`-style lookup tables already used elsewhere in this codebase rather than scattering checks ad hoc through `server.js`.
|
||||
- **Public overlays and training links are unaffected** - they're already gated per-share-token independently of admin auth (see the security audit's scope notes) and are meant to be shared outside the operator group; nothing about this design changes that.
|
||||
- **Open question needing the user's decision before building:** auth off by default (today's zero-friction behavior, but does nothing until someone remembers to turn it on) vs. on by default with an auto-generated Admin PIN printed once to the console/log on first run (safer out of the box, closer to how other self-hosted tools like this one already print startup info to logs, but a new "one more thing to notice" step during setup). Leaning toward on-by-default given the whole point is closing a real live-race risk, but this is exactly the kind of call that should be confirmed, not assumed, before implementation starts.
|
||||
|
||||
- [ ] Define Admin, Race Director, Speaker and Read-only capabilities.
|
||||
- [ ] Enforce permissions on server endpoints, not only in the UI.
|
||||
- [ ] Keep public overlays and training links restricted.
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "rc-racecore",
|
||||
"version": "1.21.1",
|
||||
"version": "1.21.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "rc-racecore",
|
||||
"version": "1.21.1",
|
||||
"version": "1.21.2",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^12.11.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rc-racecore",
|
||||
"version": "1.21.1",
|
||||
"version": "1.21.2",
|
||||
"private": true,
|
||||
"description": "RC RaceCore live timing and race control with AMMC ingest and SQLite persistence",
|
||||
"engines": {
|
||||
|
||||
Reference in New Issue
Block a user