feat: use postgres

This commit is contained in:
Ilia Denisov
2026-04-26 20:34:39 +02:00
committed by GitHub
parent 48b0056b49
commit fe829285a6
365 changed files with 29223 additions and 24049 deletions
+88
View File
@@ -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`).
+14 -13
View File
@@ -7,10 +7,16 @@ verification, shutdown, and common authsession incidents.
Before starting the process, confirm:
- `AUTHSESSION_REDIS_ADDR` points to the Redis deployment used for authsession
source-of-truth data, resend throttling, and gateway projection
- the configured Redis ACL, DB, TLS, and key-prefix settings match the target
environment
- `AUTHSESSION_REDIS_MASTER_ADDR` and `AUTHSESSION_REDIS_PASSWORD` point to the
Redis deployment used for authsession source-of-truth data, resend
throttling, and gateway projection. Optional read replicas may be listed in
`AUTHSESSION_REDIS_REPLICA_ADDRS` (currently unused; reserved for future
read-routing).
- the configured Redis DB and key-prefix settings match the target environment.
Per `ARCHITECTURE.md §Persistence Backends`, Redis traffic is
password-protected and TLS is disabled by policy; the deprecated
`AUTHSESSION_REDIS_TLS_ENABLED` and `AUTHSESSION_REDIS_USERNAME` variables
are no longer accepted and cause a hard fail at startup.
- if `AUTHSESSION_USER_SERVICE_MODE=rest`, both
`AUTHSESSION_USER_SERVICE_BASE_URL` and
`AUTHSESSION_USER_SERVICE_REQUEST_TIMEOUT` are configured
@@ -21,15 +27,10 @@ Before starting the process, confirm:
- `gateway:session:` cache key prefix
- `gateway:session_events` stream name
At startup the process performs bounded `PING` checks for:
- challenge store
- session store
- config provider
- gateway projection publisher
- resend-throttle protector
Startup fails fast if any of those checks fail.
At startup the process performs one bounded `PING` against the shared Redis
client used by every adapter (challenge store, session store, config provider,
gateway projection publisher, resend-throttle protector). Startup fails fast
if the ping fails.
Expected listener state after a healthy start:
+16 -5
View File
@@ -101,7 +101,8 @@ gateway-facing projection namespaces as a derived integration view.
Required for all process starts:
- `AUTHSESSION_REDIS_ADDR`
- `AUTHSESSION_REDIS_MASTER_ADDR`
- `AUTHSESSION_REDIS_PASSWORD`
Core process config:
@@ -124,13 +125,23 @@ Internal HTTP config:
- `AUTHSESSION_INTERNAL_HTTP_IDLE_TIMEOUT`
- `AUTHSESSION_INTERNAL_HTTP_REQUEST_TIMEOUT`
Redis connectivity and namespace config:
Redis connection topology (managed by `pkg/redisconn`,
see `ARCHITECTURE.md §Persistence Backends`):
- `AUTHSESSION_REDIS_USERNAME`
- `AUTHSESSION_REDIS_PASSWORD`
- `AUTHSESSION_REDIS_MASTER_ADDR` (required)
- `AUTHSESSION_REDIS_REPLICA_ADDRS` (optional, comma-separated; reserved for
future read-routing — currently unused)
- `AUTHSESSION_REDIS_PASSWORD` (required)
- `AUTHSESSION_REDIS_DB`
- `AUTHSESSION_REDIS_TLS_ENABLED`
- `AUTHSESSION_REDIS_OPERATION_TIMEOUT`
> Removed: `AUTHSESSION_REDIS_ADDR`, `AUTHSESSION_REDIS_USERNAME`,
> `AUTHSESSION_REDIS_TLS_ENABLED`. `pkg/redisconn.LoadFromEnv` rejects the
> deprecated `*_REDIS_TLS_ENABLED` and `*_REDIS_USERNAME` variables at
> startup; see `docs/redis-config.md` for the rationale.
Redis namespace and stream config:
- `AUTHSESSION_REDIS_CHALLENGE_KEY_PREFIX`
- `AUTHSESSION_REDIS_SESSION_KEY_PREFIX`
- `AUTHSESSION_REDIS_USER_SESSIONS_KEY_PREFIX`