This document describes how recomp-net-server handles secrets, optional client authentication, and the limits of “validating” game clients.
- Anything shipped in a game binary can be extracted. Shared secrets, static API keys, or obfuscated strings are hints, not proofs of a legitimate client. Assume compromise and design for revocation and rotation.
- Server-side enforcement is what matters: rate limits, abuse detection, short-lived credentials, and lobby/session integrity checks on the server.
- Open source does not weaken the threat model. Attackers can already replay API calls or patch a client; server-side checks and short-lived credentials remain the real controls.
All sensitive values are read from the process environment (or your platform’s secrets injector).
| Variable | Secret? | Purpose |
|---|---|---|
BIND_ADDR |
No | host:port to listen on (e.g. 0.0.0.0:8091). |
DATABASE_URL |
Often | Database connection string; never commit. |
REQUIRE_AUTH |
No | If 1/true, server refuses to start unless JWT signing secrets are set. |
JWT_SECRET_CURRENT |
Yes | HMAC key for signing short-lived session/player tokens. |
JWT_SECRET_PREVIOUS |
Yes | Optional second key still accepted while rotating JWT_SECRET_CURRENT. |
COTURN_STATIC_AUTH_SECRET |
Yes | Shared secret for coturn use-auth-secret / REST HMAC passwords. Must match coturn static-auth-secret exactly (see COTURN.md). |
Rules implemented in code:
- There is no hard-coded signing key, API key, or password in the repository.
- If
REQUIRE_AUTHis enabled andJWT_SECRET_CURRENTis missing, startup fails fast.
- Issued JWTs should use a short expiration (e.g. 15–60 minutes for session tokens; tune to your launcher flow). Long-lived bearer tokens in binaries are a liability.
- Rotation: set a new
JWT_SECRET_CURRENTand move the old value toJWT_SECRET_PREVIOUS. The server accepts signatures from either key until all old tokens expire; then clearJWT_SECRET_PREVIOUS.
- Use tokens for session continuity and revocation, not as DRM.
- Combine with: TLS in production, per-IP rate limits, anomaly flags, and server-authoritative lobby membership.
- Game identity (
game_id) is client-reported; enforce an allowlist and matchingclient_version/ build pins so peers do not join mismatched sims.
- Never commit
.env,*.pem, or productionDATABASE_URL. - Keep CI logs free of printed secrets and internal stack traces where possible.
- Rotate Coturn / JWT secrets if they were ever shared outside a trusted host.
When rotating Coturn, update both
COTURN_STATIC_AUTH_SECRETand the daemon’sstatic-auth-secretin the same change window.