Skip to main content

Central Redis

French version: ../redis.md.

Role (kit rule 6.2)​

Redis is a cache and temporary coordination: rate limit counters, a per tenant cache that can be encrypted (eai.cache), distributed locks with a fencing token. It is never the only source of truth for permissions, suspensions, quotas or evidence: those are read from PostgreSQL. tests/test_core_redis.py::test_sources_of_truth_never_read_from_redis refuses any Redis or eai.cache import in those modules.

Connection, TLS and ACL​

  • EAI_REDIS_URL=rediss://redis.internal:6390/0, EAI_REDIS_USERNAME=eai, EAI_REDIS_PASSWORD_FILE=/run/secrets/redis-password, EAI_REDIS_TLS_CA_FILE=/etc/eai/redis-ca.pem (server certificate verified). In prod the startup refuses redis:// and a URL without a password (file).
  • Minimal ACL user: ACL SETUSER eai on >... ~eai:* +@all -@dangerous (keys prefixed eai:).
  • Keys: eai:c:<tenant>:<namespace>:<name> (cache, mandatory TTL from 1 s to 7 days), eai:rl:* (rate limits, one minute window).
  • /readyz publishes redis: {configured, ok, role, error} without making the instance not ready.

High availability​

  • deploy/data/redis (OT redis-operator): replication with sentinels and TLS. After a failover the client reconnects to the new primary; verified with a real redis-server: --replicaof replica, primary stopped (the cache answers miss without error), REPLICAOF NO ONE promotion, read and write on the new primary.

Redis down​

  • Cache: read = miss, write = False, lock refused. Rate limiting: falls back to the in-memory counters of each replica (warning logged). The API keeps serving.

Backup​

  • None: the content is rebuilt. Persistence may be disabled.

Tests​

cd services/control-plane && .venv/bin/python -m pytest -q tests/test_core_redis.py (starts /usr/bin/redis-server on free ports): TTL, tenant isolation, encrypted entry bound to its key, lock and fencing, rate limit shared by two instances, replication and failover, ACL with password file, Redis stopped.