feat: use postgres
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# 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`).
|
||||
Reference in New Issue
Block a user