Files
electric-cherry/docs/guides/authentication.md
T
josh 82e07ea33e
CI / checks (push) Successful in 6m29s
Add optional 30-day remembered sessions
2026-10-13 14:42:53 -04:00

190 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Users and access
Electric Cherry requires a user session for operator pages and management APIs.
HTTPS protects the connection; server-side role checks protect each operation.
There is no anonymous management mode or public registration.
Leaderboard API reads (`GET` and `HEAD /api/leaderboard`) are public and need no
session or credentials. This exception covers only that exact API route;
leaderboard/profile pages, match-history routes and management operations retain
their access checks. HTTPS requirements still apply. See the
[leaderboard API reference](leaderboard.md#read-api) for requests and response fields.
## First administrator and upgrades
1. Generate a setup secret: `openssl rand -hex 32`.
2. Set `EC_SETUP_TOKEN` to that value in the controller environment (or Compose
`.env`), set `EC_PUBLIC_URL` to the external HTTPS URL, and start EC. For a
direct Node deployment, set `ORIGIN` to that same URL.
3. Visit EC. `/setup` asks for the setup token, a username, display name and
password. Only the holder of the token can create the first administrator.
4. Remove `EC_SETUP_TOKEN` after setup and restart/recreate the controller.
Setup remains closed once any user exists, even if the token is still set.
5. Use **Admin → Users** to create additional accounts. Share temporary
passwords privately; each user must change theirs on first login.
Existing installations become protected on upgrade. Existing game servers and
agent enrollment credentials continue working independently of browser login.
Preserve the current database when upgrading: accounts and sessions are stored
there alongside the fleet metadata. Never publish a blank setup page with a
guessable token. An unset setup token holds setup closed.
## Roles
| Capability | Viewer | Super Viewer | Operator | Administrator |
| --------------------------------------------------------------------------------------------- | -------------- | ------------ | ----------- | ------------- |
| Fleet, metrics, matches and operation summaries | Yes | Yes | Yes | Yes |
| Raw configs, file diffs, logs, saved RCON and telemetry diagnostics | No | Read | Read | Read |
| Deploy/start/stop/restart/rebuild/remove servers and run diagnostic probes | No | No | Yes | Yes |
| Scripts, plugins, configs, campaigns, betas and collections | Read summaries | Read | Manage | Manage |
| Host setup, deletion, enrollment, credentials, runtime preparation and game-file upload/cache | Read status | Read status | Read status | Manage |
| Server keys and global settings/maintenance policies | No | Read | No | Manage |
| Users and account audit activity | No | Read | No | Manage |
| Create users, change roles, disable accounts and reset passwords | No | No | No | Yes |
| Own password and sign out | Yes | Yes | Yes | Yes |
Super Viewer is a read-only administrator. It includes the Admin navigation and
access to sensitive configuration and diagnostic content, but cannot change fleet
state, settings, keys, or other accounts. Cleanup previews remain available because
they do not save settings or run cleanup. Assign it only to people trusted to read
administrative information. Existing accounts and sessions are preserved on upgrade.
Operators can launch using available game-pool keys already saved by an administrator. They
cannot save keys indirectly through a launch request. An operator's content
permissions include executable scripts and plugins; assign that role only to
people trusted to operate the game fleet.
Drift previews (`/api/drift`) and GitHub release lookups
(`/api/plugins/github/release`) require operator or administrator access, including
`GET` and `HEAD` requests. These endpoints initiate fleet file scans or use GitHub
API quota; Viewers and Super Viewers cannot trigger them.
Saved RCON failure replies are available to Super Viewers, operators and administrators in the
server's Diagnostics tab. Player addresses are redacted before diagnostics are
saved; successful checks clear the saved reply. Fleet snapshots and live status
streams contain no reply snippets. Upgrades discard older saved RCON snippets.
Permissions are checked on the server for API calls, normal pages and Svelte
page-data requests. Hiding UI controls is a convenience, not the access boundary.
The controller prevents disabling or demoting the last enabled administrator.
Accounts are disabled rather than deleted so history retains their identity.
## Passwords, sessions and recovery
Passwords are 8–128 characters and stored using salted scrypt hashes. Temporary
passwords created or reset by administrators must be changed before any fleet
access. Password changes require the current password.
Sessions use random tokens in HTTP-only cookies, with only token hashes stored in
SQLite. HTTPS uses a Secure `__Host-` cookie. By default, sessions expire after
12 hours, or 30 minutes without authenticated requests; background dashboard
polling counts as activity.
Select **Keep me signed in on this device** at sign-in to stay signed in for
30 days, including between visits from a phone's home-screen app. This option is
unchecked by default and applies only to that browser or home-screen app. Remembered
sessions have no inactivity timeout, but still expire 30 days after sign-in;
activity does not extend that deadline. Use this option only on a device you trust.
Existing sessions keep their original limits after upgrading.
Password changes always require the current password. Remembered administrator
sessions also require the administrator's current password when creating accounts
or editing users, including access changes and password resets. A successful
password change replaces the current session, preserving its remember-device
choice with a fresh lifetime, and revokes all other sessions.
For API clients, `POST /api/auth/login` accepts an optional boolean `rememberMe`
(omitted or `false` keeps the default limits). When using a remembered session,
`POST /api/users` and `PATCH /api/users/:id` require the administrator's password
in `currentPassword`; the `password` field remains the target user's temporary
password. The password-change endpoint preserves the current session's choice.
Login replaces the existing browser session. Logout revokes it.
Changing a password, changing a role, disabling an account, or revoking that
user's sessions invalidates their existing sessions. Live event streams check
revocation every 15 seconds and then close.
Login and password changes for enabled Administrators and Super Viewers are exempt
from per-account and per-address rate limits, including existing exhausted windows.
Their attempts do not consume either limit. Other accounts and initial setup use
persistent 15-minute windows. Exemptions use the account's current database role;
password verification is still required. The database stores audit entries for login
results, account changes and successful management requests without recording
passwords, tokens or request bodies. Administrators and Super Viewers can review
recent entries in Users.
For every role, the password service runs at most two scrypt operations at once
and queues up to 16 more for up to two seconds. If that queue fills or the wait
expires, the request returns HTTP 429 with `Retry-After: 2`. The persistent rate
limits return `Retry-After: 900` when a non-exempt account or address reaches its
attempt limit.
An administrator can reset another user's password from Users. If the only
administrator forgets their password, an operator with local controller/container
access can run the recovery command in an interactive terminal:
```sh
docker compose exec electric-cherry node scripts/reset-admin.mjs admin
# Direct Node deployment, using the correct database:
DB_PATH=./data/cherry.db node scripts/reset-admin.mjs admin
```
Replace `admin` with the existing administrator's username. The command prompts
without echoing the password, resets that enabled administrator only, revokes
their sessions and records the recovery. It does not expose a remote recovery
endpoint or accept passwords as command arguments.
## Agent and telemetry connections
Host agents retain enrollment/host-token authentication under `/api/agent/`.
Installer and release files remain public so a new machine can enroll. A browser
login never substitutes for a host credential, and host tokens cannot manage EC.
The agent and standalone updater source contain no credentials. Automatic
updates fetch the controller's public HTTPS release manifest and verify its
checksums and compatibility. The installed host retains its own credential;
the updater accepts an upgrade only after a fresh authenticated heartbeat from
the new agent process. Updating agent code does not change browser sessions or
user roles. See [automatic agent updates](native-hosts.md#automatic-agent-updates)
for the one-time installer upgrade required by existing hosts.
Host deletion uses a separate operation-scoped receipt token so the uninstall
worker can confirm removal and retry its acknowledgment after host credentials
are revoked. That token authorizes only the corresponding cleanup receipt.
Game reporters must send a separate secret of at least 32 characters configured
as `EC_TELEMETRY_TOKEN`:
```http
POST /api/telemetry
Authorization: Bearer <telemetry-token>
Content-Type: application/json
```
`X-EC-Telemetry-Token` is also supported. Cookies, query parameters and JSON fields
cannot supply it. A missing server token disables ingestion; a missing or wrong
request token is rejected before parsing or recording the payload. Existing JSON
event fields are unchanged. Configure your uploaded reporter/plugin, or a trusted
relay if that reporter cannot set headers, before upgrading. Use HTTPS for the
reporter-facing endpoint. Rotating this shared token requires updating reporters.
## Proxy and local development
Keep Node's internal port behind your TLS proxy and configure `ORIGIN` correctly.
Management writes require an exact matching `Origin` header, including login,
JSON requests and multipart uploads. Do not configure a proxy to replace arbitrary
incoming origins with your trusted origin. Machine endpoints use their own token
checks and do not require a browser Origin.
Use the adapter's real client-address configuration only with a trusted proxy
that strips spoofed forwarding headers; login throttling otherwise uses the direct
peer address. Forwarded host or user headers do not authenticate users.
Local HTTP browser development requires `EC_AUTH_ALLOW_HTTP=true` and a loopback
hostname (`localhost`, `127.0.0.1` or `::1`). This uses a separate development
cookie. It never enables HTTP login for a LAN/public hostname. Agent HTTP
development remains separately controlled by `EC_AGENT_ALLOW_HTTP` and the agent's
loopback-only option.
The implementation follows OWASP's guidance for [authorization on every request](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html#validate-the-permissions-on-every-request),
[password hashing](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#scrypt),
and [session management](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html).