Adds an authentication layer in front of the bot handlers : - Auth handler on the principal bot (@arcodange_factory_bot, slug factory) parses /start, /auth <code>, /whoami, /logout. On a successful /auth, the message containing the code is best-effort deleted from the user's chat (replay defense). - Redis-backed sessions (key tg-gw:auth:<from.id>, TTL 24h, configurable via AUTH_SESSION_TTL). Constant-time secret compare via crypto/subtle. - ALLOWED_USERS env (CSV of Telegram user IDs) — silent-drops anyone not in the list before the auth gate runs. - New per-bot field 'requireAuth' (pointer-bool). Default = true (secure by default). Auto-forced to false for handler=auth (chicken-and-egg). - Server gates: allowlist first, then requireAuth before handler dispatch. - Fail-at-startup if a bot is configured with handler=auth or requireAuth: true while AUTH_SECRET is unset. Design: factory/docs/adr/20260509-telegram-gateway-auth.md (in factory PR). User docs: AUTH.md (new), HOWTO_ADD_BOT.md (Cas 2 updated for default true and gated flow). New deps: github.com/redis/go-redis/v9. Refs ~/.claude/plans/pour-les-notifications-on-inherited-seal.md § Phase 1.5.
4.7 KiB
← README · HOWTO_ADD_BOT · Authentification
Détails de design : factory ADR 20260509 — telegram-gateway auth
Authentification
Le gateway est protégé en deux couches :
- Allowlist (
ALLOWED_USERS, optionnelle) — filtre la liste des Telegram user IDs autorisés à parler à n'importe quel bot. Hors-liste : silent drop, le bot ne répond rien (l'inconnu ne sait même pas que le bot existe). - Session
/auth— par défaut, tous les bots du gateway exigent une session active (requireAuth: truepar défaut). Pour ouvrir une session, il faut DM@arcodange_factory_botavec/auth <code>. Une session dure 24 h (configurable viaAUTH_SESSION_TTL).
Côté utilisateur
1. Ouvrir une session
- Sur Telegram, ouvre
@arcodange_factory_bot. - Envoie
/auth <code>(le code t'a été partagé par l'admin du gateway). - Le bot répond
✅ Authentifié pour 24 h. Ton message contenant le code est automatiquement supprimé du chat (replay defense). - Tu peux maintenant DM les autres bots normalement.
2. Vérifier sa session
/whoami
Réponse type : user=123456 : ✅ authentifié, reste 23h59m. ou user=123456 : non authentifié..
3. Fermer une session
/logout
4. Quand un bot répond 🔒 Authentifie-toi …
Ta session a expiré (TTL dépassé) ou tu n'as jamais fait /auth. Va sur @arcodange_factory_bot, refais /auth <code>.
Côté opérateur
Définir / changer le code AUTH_SECRET
# Choisir un code fort (ex : openssl rand -hex 16)
SECRET='<chosen-code>'
kubectl -n telegram-gateway patch secret telegram-gateway-bots --type=json -p="[
{\"op\":\"replace\",\"path\":\"/data/AUTH_SECRET\",\"value\":\"$(echo -n "$SECRET" | base64)\"}
]"
# Restart pour reload du Secret
kubectl -n telegram-gateway rollout restart deploy/telegram-gateway
Rotation : changer
AUTH_SECRETinvalide les futurs/authmais pas les sessions Redis déjà ouvertes (elles vivent jusqu'à leur TTL). Pour invalider tout :kubectl exec -n tools redis-0 -- redis-cli --scan --pattern 'tg-gw:auth:*' | xargs -I{} kubectl exec -n tools redis-0 -- redis-cli DEL {}.
Définir / changer l'allowlist
kubectl -n telegram-gateway patch secret telegram-gateway-bots --type=json -p="[
{\"op\":\"replace\",\"path\":\"/data/ALLOWED_USERS\",\"value\":\"$(echo -n '12345,67890' | base64)\"}
]"
kubectl -n telegram-gateway rollout restart deploy/telegram-gateway
Pour désactiver l'allowlist (ouvrir à tout Telegram user en allowlist) :
kubectl -n telegram-gateway patch secret telegram-gateway-bots --type=json -p='[
{"op":"remove","path":"/data/ALLOWED_USERS"}
]'
kubectl -n telegram-gateway rollout restart deploy/telegram-gateway
Inspecter une session Redis
USER_ID=123456
kubectl exec -n tools redis-0 -- redis-cli GET "tg-gw:auth:$USER_ID" # → "1" ou (nil)
kubectl exec -n tools redis-0 -- redis-cli TTL "tg-gw:auth:$USER_ID" # → secondes restantes
kubectl exec -n tools redis-0 -- redis-cli DEL "tg-gw:auth:$USER_ID" # → forcer logout
Rendre un bot public (opt-out de l'auth)
Dans chart/values.yaml, ajouter requireAuth: false au bot concerné :
bots:
statusbot:
handler: echo
requireAuth: false # bot public, pas de session requise
Cas spécial :
handler: auth(le bot principalfactory) force toujoursrequireAuth: falseautomatiquement (sinon l'auth elle-même serait inaccessible — chicken-and-egg).
Limites connues
- Pas de TOTP / OTP rotatif — un code partagé suffit pour cet usage privé. À reconsidérer si on ouvre à plus d'utilisateurs.
- Pas de rate-limit sur
/auth— l'ALLOWED_USERSjoue le rôle de garde-fou. Avec un code fort (≥ 128 bits), le bruteforce est inutile dans la fenêtre de TTL. - Sessions invalidées si Redis tombe — fail-closed : tous les bots gated répondent
🔒jusqu'à ce que Redis revienne. Acceptable. from.id-based, pas IP-based — Telegram n'expose pas l'IP du user au bot. Une session couvre tous les devices d'un même compte Telegram, ce qui est le comportement attendu.
Chemin de migration vers Vault (Phase 2+)
Aujourd'hui, AUTH_SECRET et ALLOWED_USERS vivent dans un Secret k8s créé via kubectl create secret. À terme, ils basculeront dans Vault (toggle vault.enabled: true dans chart/values.yaml, provisionner kvv2/telegram-gateway/config). Le code n'a pas à changer — envFrom: secretRef consomme indifféremment un Secret manuel ou un Secret produit par VaultStaticSecret.