Provision instance bank credentials automatically (Refs #146)

This commit is contained in:
2026-10-12 20:44:01 -04:00
parent e071e5b574
commit d14c6a7ff4
21 changed files with 634 additions and 109 deletions
+51 -24
View File
@@ -9,32 +9,45 @@ IDs. This release does not introduce separate bank-assisted rankings.
## Setup and rollout
1. Back up the controller database. Deploy Electric Cherry first and restart
the controller. Migration 20 creates accounts, transfer requests and a ledger.
2. Generate a **different** secret for each registered game server, for example
`ec_bank_` followed by `openssl rand -hex 32`. Configure `EC_BANK_TOKENS` as a
JSON object mapping exact server names to these secrets. Docker Compose
forwards this environment variable. An example shape with placeholders is
`{"t5_zombie_theater_1":"ec_bank_<random-secret>"}`.
1. Back up the controller database. Update every host agent to **1.9.0 or later**
before enabling the bank. This version settles game journals before removing
runtime storage; older agents do not. Package and offline-sign the agent
release using the [host update workflow](native-hosts.md).
2. Deploy Electric Cherry and restart the controller. Migration 20 creates
accounts, requests and the ledger; migration 21 adds instance credentials and
binds existing requests to their currently active native instance, if any.
3. Set `EC_BANK_MAX_BALANCE` (default 250000, range 1–1000000). Invalid configuration
refuses new deposits. A limit reduction does not confiscate existing balances
or invalidate already prepared deposits; withdrawals remain available.
refuses new deposits. Lowering the limit preserves existing balances and
prepared deposits; withdrawals remain available.
4. Build/install TWS plugins `t5-plugin`/`t6-plugin` 1.1.0 or later and restart
the **whole game-server process**. Install `tws_t5_bank.gsc` or
`tws_t6_bank.gsc` 1.0.0, the game's common module (1.0.0+) and telemetry
reporter (1.0.0+). Restart the map after installing scripts/configuration.
5. In each server's private configuration, set `tws_server_id` to its registered
name and `tws_bank_token` to that server's secret. The optional `tws_bank_url`
defaults to `https://ec.thewrightserver.net/api/bank`; overrides must use
HTTPS. Keep these settings out of shared scripts and public config downloads.
`tws_t6_bank.gsc` 1.0.0, common 1.0.0+ and telemetry 1.0.0+.
5. Create or rebuild the servers through EC. Launch preparation generates a
cryptographically random `ec_bank_` credential for each immutable instance,
stores it in the private controller database, and injects it through
`configs/electric_cherry_bank.cfg`. The launch command executes this private
file and sets `tws_server_id`. The host agent writes the private file and derives `tws_bank_url` from its
enrolled controller URL. Use an HTTPS controller URL.
Bank tokens must match `ec_bank_` followed by 32–128 URL-safe letters, digits,
underscores or hyphens. Missing, malformed, duplicate, or telemetry-reused tokens
disable authentication. `EC_TELEMETRY_TOKEN`, host tokens and browser sessions
cannot authorize bank requests. The credential determines the server, and a
different `server` in the body is refused. Rotate a token by updating both the
controller mapping and that server's private configuration, then restart them.
Keep the same server name and bank URL so existing decisions can finish.
There is **no `EC_BANK_TOKENS` environment map** and no per-server secret setup.
The private configuration is sent only in that host's authenticated operation
payload. It is excluded from shared recipes, promoted files and blob downloads.
Do not upload `electric_cherry_bank.cfg`: its filename is reserved. Protect the
controller database, host operation journal and per-instance runtime directory,
which contain private credentials.
Retries, rebuilds and host moves of the same instance reuse its credential.
Retiring the instance immediately revokes authentication. Creating another
server with the same display name produces a new instance ID and secret; it
cannot finish the old instance's requests. Accounts remain attached to player
GUIDs, so balances survive the servers. Telemetry tokens and browser sessions
cannot authorize bank requests. Host credentials can only settle decisions
through the separate, operation-scoped teardown endpoint.
For an upgrade from the initial static-token implementation, drain outstanding
transfers while the old controller/configuration still runs, then deploy and
rebuild. Remove the obsolete environment map and any manually supplied token.
Do not replace identities or discard pending journals to force an upgrade.
## Machine API
@@ -76,7 +89,8 @@ Preparation requires the GUID to be present in the server's latest active match,
with the exact telemetry match key. Late joiners may need to wait for the next
30-second heartbeat. Unknown/destroyed servers, absent players and old matches
cannot prepare transfers. Settlement of an existing decision remains possible
after match completion, retention or server deletion.
after match completion or retention. Host teardown can finish saved decisions
after retirement; the retired game credential itself no longer authenticates.
Successful application responses include `ok`, `state`, `code`, `request_id`,
`amount` and `balance`. States are `balance`, `prepared`, `committed`, `cancelled`
@@ -110,7 +124,8 @@ decision, retries only finish the ledger; they never change game points again.
These points now belong to the current match, so an applied withdrawal is not
automatically refunded if that match ends or its server crashes.
Keep `fs_homepath/tws-bank/t5/` or `t6/` on persistent writable storage with a
Keep `tws-bank/t5/` or `tws-bank/t6/`, relative to the game process working
directory, on persistent writable storage with a
single process per server/endpoint. Journals contain transfer data, not secrets.
On a map/process restart, saved decisions settle before new bank commands.
Unreadable storage disables the bank; failed writes prevent points changes.
@@ -121,6 +136,18 @@ original journal to resolve holds; never delete a pending journal to unblock
the bank. If storage is permanently lost, reconcile against the retained
request and ledger records before any manual repair.
During removal, rebuild, host migration or launch cancellation, agent 1.9.0+
stops the game and drains its journals **before** deleting runtime files or
starting a replacement. It uses its host credential at
`POST /api/agent/bank/settle`; EC checks the assigned host, immutable instance,
unfinished teardown operation, server and original request identity. This
endpoint permits only commit/cancel, never new deposits or withdrawals. Journal
URLs must match that host's configured controller; the agent never follows a
journal URL. Corruption, a mismatched controller, failed acknowledgment or an
outage retains storage and leaves the operation unresolved for retry. An
interrupted rebuild uses the existing rebuild recovery workflow to retry with
a fresh operation after settlement. Do not manually erase its old directory.
The journal provides recovery from map/process restart. It cannot make live
game memory and SQLite one atomic transaction or preserve match points after a
machine/storage failure. Back up persistent storage and verify crash behavior
+9
View File
@@ -1035,3 +1035,12 @@ game hosts. Run:
- Controller restart, agent restart and network loss before execution, during
execution and after execution but before acknowledgement. Verify the same
operation IDs and absence of duplicate containers/restarts.
### Bank journals during server teardown
Agent 1.9.0 adds `bank.settlement`: removal, rebuild, migration and creation
cancellation finish pending TWS bank decisions before deleting the old runtime.
An unavailable controller or corrupt journal leaves the operation unresolved
and preserves storage. Update all agents before enabling the
[player bank](bank.md). EC generates and injects bank credentials per instance;
no token map or manual server-secret provisioning is required.