Files
galaxy-game/authsession/docs/redis-config.md
T
2026-04-26 20:34:39 +02:00

3.9 KiB

Decision: Redis configuration shape

PG_PLAN.md §7. Captures the standing rules adopted by Auth/Session Service when it joined the project-wide Redis topology defined in ARCHITECTURE.md §Persistence Backends.

Context

Auth/Session Service intentionally stays Redis-only. All authsession state is TTL-bounded and recoverable from a fresh login flow:

  • challenge records expire with the login window;
  • device-session records expire with their session TTL;
  • gateway projection cache keys are write-through reflections of the source-of-truth session record;
  • the gateway-session-events stream is consumed lazily by the gateway and trimmed by MAXLEN ~;
  • the resend-throttle protector is purely TTL-driven.

Stage 7 brought authsession in line with the steady-state rules established in Stage 0: every Galaxy service uses one master plus zero-or-more replicas with a mandatory password, no TLS, and no Redis ACL username; the connection is configured by the shared pkg/redisconn helper.

Decisions

One shared *redis.Client owned by the runtime

internal/app/runtime.go constructs a single *redis.Client via internal/adapters/redis.NewClient, attaches OpenTelemetry tracing and metrics via internal/adapters/redis.InstrumentClient, performs one bounded PING via internal/adapters/redis.Ping, and registers client.Close for shutdown. The challenge store, session store, config provider, projection publisher and resend-throttle protector all receive this same client.

Adapters no longer build or own a Redis client. Their Config structs hold only namespace and per-adapter timeout settings (no Addr/Username/Password/ DB/TLSEnabled). Adapter constructors take (*redis.Client, Config).

One env-var prefix per service

Connection topology is loaded from a single AUTHSESSION_REDIS_* group via redisconn.LoadFromEnv("AUTHSESSION"):

  • AUTHSESSION_REDIS_MASTER_ADDR (required)
  • AUTHSESSION_REDIS_REPLICA_ADDRS (optional, comma-separated; currently unused, reserved for future read-routing)
  • AUTHSESSION_REDIS_PASSWORD (required)
  • AUTHSESSION_REDIS_DB (default 0)
  • AUTHSESSION_REDIS_OPERATION_TIMEOUT (default 250ms)

The per-adapter namespace and stream env vars (*_KEY_PREFIX, *_STREAM, *_STREAM_MAX_LEN) keep their existing names and semantics — they describe key shape, not connection topology.

Retired env vars (hard removal)

  • AUTHSESSION_REDIS_ADDR — replaced by AUTHSESSION_REDIS_MASTER_ADDR.
  • AUTHSESSION_REDIS_USERNAME — Redis ACL not used.
  • AUTHSESSION_REDIS_TLS_ENABLED — TLS disabled by policy.
  • AUTHSESSION_REDIS_OPERATION_TIMEOUT keeps its name (it now lives in redisconn.Config).

pkg/redisconn.LoadFromEnv rejects AUTHSESSION_REDIS_TLS_ENABLED and AUTHSESSION_REDIS_USERNAME at startup with a clear error pointing to ARCHITECTURE.md §Persistence Backends. There is no backward-compatibility shim; this is consistent with the project-wide rule that the migration window has no production deploys to preserve.

Telemetry

redisconn.Instrument wires redisotel.InstrumentTracing (with WithDBStatement(false)) and redisotel.InstrumentMetrics. This is the first authsession release that emits Redis tracing and connection-pool metrics; downstream dashboards will start populating without further changes.

Consequences

  • Test code that previously constructed a Redis client per adapter must now construct one client and pass it to every adapter under test (see the pattern in internal/adapters/redis/<adapter>/store_test.go).
  • Operators must set AUTHSESSION_REDIS_PASSWORD. A passwordless local Redis is still acceptable as long as a placeholder password is supplied to the binary; Redis without requirepass accepts AUTH unconditionally.
  • The integration test harness passes AUTHSESSION_REDIS_PASSWORD = "integration" alongside AUTHSESSION_REDIS_MASTER_ADDR (see integration/internal/harness/authsessionservice.go).