147 lines
8.8 KiB
Markdown
147 lines
8.8 KiB
Markdown
# 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 | Operator | Administrator |
|
||
| --------------------------------------------------------------------------------------------- | -------------- | ----------- | ------------- |
|
||
| Fleet, metrics, matches and operation summaries | Yes | Yes | Yes |
|
||
| Raw configs, file diffs, logs, RCON and telemetry diagnostics | No | Yes | Yes |
|
||
| Deploy/start/stop/restart/rebuild/remove servers | No | Yes | Yes |
|
||
| Scripts, plugins, configs, campaigns, betas and collections | Read summaries | Manage | Manage |
|
||
| Host setup, deletion, enrollment, credentials, runtime preparation and game-file upload/cache | Read status | Read status | Manage |
|
||
| Server keys and global settings/maintenance policies | No | No | Manage |
|
||
| Create users, change roles, disable accounts and reset passwords | No | No | Yes |
|
||
| Own password and sign out | Yes | Yes | Yes |
|
||
|
||
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.
|
||
|
||
RCON failure replies are available only to 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. Sessions expire after 12 hours, or
|
||
30 minutes without authenticated requests; background dashboard polling counts
|
||
as activity. 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, initial setup and password verification are rate-limited with persistent
|
||
15-minute windows. The database stores audit entries for login results, account
|
||
changes and successful management requests without recording passwords, tokens
|
||
or request bodies. Administrators can review recent entries in Users.
|
||
|
||
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).
|