# 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. ## 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 **Settings → 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 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 server 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. 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 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).