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(default0)AUTHSESSION_REDIS_OPERATION_TIMEOUT(default250ms)
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 byAUTHSESSION_REDIS_MASTER_ADDR.AUTHSESSION_REDIS_USERNAME— Redis ACL not used.AUTHSESSION_REDIS_TLS_ENABLED— TLS disabled by policy.AUTHSESSION_REDIS_OPERATION_TIMEOUTkeeps its name (it now lives inredisconn.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 withoutrequirepassaccepts AUTH unconditionally. - The integration test harness passes
AUTHSESSION_REDIS_PASSWORD = "integration"alongsideAUTHSESSION_REDIS_MASTER_ADDR(seeintegration/internal/harness/authsessionservice.go).