Files
nas-runbooks/common/baserow-rotation-casse-containers-standalone.md
T

5.4 KiB

Rotation secrets Baserow casse les containers standalone non supervises (25/07/2026)

Symptome

dashboard-terrain (container standalone : docker build + run manuel, pas de compose, pas de volume, code cuit dans l'image) retournait 500 sur /api/depenses. docker logs montrait uniquement la sequence de codes 500 successifs, aucun traceback applicatif exploitable directement dans les logs.

Cause racine

Le mot de passe admin Baserow (BASEROW_ADMIN_PASS) a ete change lors d'une rotation de secrets. Ce changement a bien ete propage a hermes-platform/.env et gsparc-mezzouna/.env (BASEROW_PASSWORD a jour), mais dashboard-terrain avait l'ancien mot de passe code en dur en fallback ENV du Dockerfile (ENV BASEROW_ADMIN_PASS=...). Comme ce container ne fait partie d'aucun inventaire supervise (pas de .env central, pas de docker-compose, pas de mount de code), il n'a jamais ete touche par la rotation.

Diagnostic rapide (reproductible en ~2 min)

  1. docker logs <container> pour reperer le endpoint et le code d'erreur (ici 500 sur /api/depenses).
  2. docker exec <container> python3 -c "..." pour rejouer l'appel Baserow directement depuis le reseau interne du container (Host header + Authorization) -> reponse brute Baserow, ici 401 ERROR_INVALID_CREDENTIALS: No active account found with the given credentials. Confirme la cause en un seul appel, plus fiable/rapide que d'ajouter du logging applicatif.
  3. Comparer avec les identifiants a jour dans hermes-platform/.env et gsparc-mezzouna/.env pour confirmer l'ecart.

Fix retenu

Basculer le container du login JWT admin (identifiants qui tournent, session a rafraichir) vers un Database API Token Baserow statique (header Authorization: Token <token>, scope adapte au consommateur : BASEROW_TOKEN_PERSO / BASEROW_TOKEN_NYORA / BASEROW_TOKEN_TT_RLA / BASEROW_TOKEN_TT_HORS_RLA deja presents dans hermes-platform/.env). Ce token ne casse jamais lors d'une rotation du mot de passe admin Baserow — seul un audit/rotation explicite des tokens API le ferait.

Simplification de code associee : suppression du thread de rafraichissement JWT (_jwt_refresher, JWT_REFRESH_INTERVAL), de _refresh_jwt() et de la logique de retry-sur-401 — plus necessaire avec un token statique.

Regle generale a appliquer

  • Tout nouvel outil en lecture seule sur Baserow : utiliser d'emblee un Database API Token par scope, jamais un login admin JWT.
  • Avant toute prochaine fenetre de rotation de secrets (voir common/rotation-secrets-inventaire.md) : lister les containers standalone (docker build/run manuel, sans compose, sans .env central) qui referencent des identifiants Baserow, Gitea ou autres services rotationnes, et les auditer un par un — ils sont invisibles depuis hermes-platform/.env et donc systematiquement oublies.
  • Container standalone identifie a ce jour : dashboard-terrain (corrige le 25/07/2026). Ajouter tout nouveau container de ce type ici au fil de l'eau.

Repo source

bolbol/dashboard-terrain (Gitea, branche master) — server.py + Dockerfile mis a jour, image rebuild dashboard-terrain:latest, container redeploye sur le reseau n8n, port 8085->8080.

Cas 2 (meme soir, 25/07/2026) : gsparc-mezzouna-api — .env a jour mais container jamais recree

Meme rotation, meme symptome (401 ERROR_INVALID_CREDENTIALS sur /api/user/token-auth/), mais cause differente : contrairement a dashboard-terrain, /volume1/docker/gsparc-mezzouna/.env avait deja ete mis a jour avec le bon BASEROW_PASSWORD au moment de la rotation. Le container tournait cependant depuis 5 semaines sans avoir jamais ete recree — docker inspect gsparc-mezzouna-api montrait encore l'ancien mot de passe dans .Config.Env, car les variables d'un container Docker sont figees a la creation ; editer un .env monte via env_file: dans docker-compose.yml ne change rien a un container deja demarre, il faut le recreer (docker compose up -d --force-recreate <service>).

Piege additionnel : le /health de gsparc-mezzouna-api restait vert (healthy) pendant toute la panne, car ce healthcheck ne teste que la disponibilite du process, pas la connexion Baserow — un statut "healthy" ne garantit donc pas que les dependances externes fonctionnent.

Fix : cd /volume1/docker/gsparc-mezzouna && docker compose up -d --force-recreate (a recree gotenberg au passage, dependance declaree dans le meme compose — pull de l'image ~450 Mo, prevoir 1-2 min). Log de confirmation au demarrage : [app.baserow] INFO: JWT Baserow regenere + [gsparc] INFO: Connexion Baserow etablie.

Consequence pour la checklist de rotation : mettre a jour un .env ne suffit jamais. Toute rotation de secret touchant un service en docker-compose doit se terminer par un docker compose up -d --force-recreate (ou docker restart a minima si aucune variable de build n'est en jeu) sur chaque service concerne — sinon le .env a jour reste theorique.

Suivi optionnel (non fait le 25/07/2026) : gsparc-mezzouna-api dispose deja d'un BASEROW_TOKEN dans son .env (actuellement egal a BASEROW_TOKEN_NYORA, cf. anomalie B1 de common/rotation-secrets-inventaire.md — a corriger separement pour l'etancheite des spheres) mais app/baserow.py n'utilise que le login JWT. Bascule vers le token statique possible plus tard pour la meme robustesse que dashboard-terrain, mais nécessite un rebuild d'image (code cuit) — non urgent puisque le fix --force-recreate suffit tant qu'on n'oublie pas cette etape apres une rotation.