v1.32.0
The Go server can now run more than one replica. Nothing changes for existing single-instance deployments.
Added
Redis-backed shared state (REDIS_URL).
FCaptcha keeps state that its security properties depend on: proof-of-work challenges, token replay protection, Siteverify idempotency, site-key state and suspicion history. All of it lived in process memory, so a second replica meant a second, independent set of tables — a challenge issued by one pod was unknown to the next, and "single-use" was only single-use per pod.
Setting REDIS_URL moves that state into Redis, so every replica sees the same tables.
Both failure modes are closed, not open:
- the server refuses to start if a configured Redis is unreachable
- it fails closed if Redis drops out while running, rather than quietly reverting to process-local state
The second one is the important half. A distributed-state backend that silently degrades to local state on failure gives you the appearance of shared enforcement and none of the substance.
Go server only. Node and Python ignore REDIS_URL and must stay single-instance. The environment tables described REDIS_URL as reserved through 1.31.0; that description is now accurate only for those two servers.
The Helm chart enforces it. Rendering with replicaCount > 1 or autoscaling.enabled and no Redis configured now fails with an explanation rather than deploying pods that disagree with each other. That guard, and the existing signing-key guard, are both exercised in CI.
--set redis.url=redis://your-redis:6379
--set redis.existingSecret=my-redis-secret
Fixed
- The chart's
_helpers.tplstopped parsing when the shared-state guard landed inside thevalidateSecretdefine instead of after it, which took every template in the chart with it. Caught before release — no published chart was affected.
Upgrading
Single instance, no Redis: nothing to do. REDIS_URL unset keeps the existing process-local behaviour.
Running multiple Go replicas today: you were already running with per-pod state. Set REDIS_URL — and note the chart will now refuse to render that configuration without it.