Volver a la wiki

Incidente s58 — Help Widget incomunicado tras endurecimiento CF Access (s57)

Incidente s58 — Help Widget incomunicado tras endurecimiento CF Access (s57)

Resumen ejecutivo

El 12 de mayo de 2026 (sesión 58), Edu detectó que el Help Widget de CreaRack Pro estaba completamente incomunicado en producción. Los síntomas eran:

Sin afectación a usuarios reales — Edu lo detectó antes de que cargara ningún usuario. Resuelto en la misma sesión mediante PR #26 (hotfix d20).

Línea temporal

Hora (aprox.)Evento
s57 (11-12 mayo)Se elimina bypass-everyone de las apps CF Access “Workspace MCP API” y “API Biblioteca”. Service Token distribuido a 8 workflows + 6 scripts + crons.
s57core/api_help.py y scripts/harness/bib_report_check.py NO incluidos en el audit de callers.
s58 inicioEdu detecta síntomas al usar el Help Widget en PROD.
s58 — PR #26Hotfix: _workspace_headers() inyecta CF Access headers cuando están configurados.
Post-mergeEdu configura CF_ACCESS_CLIENT_ID + CF_ACCESS_CLIENT_SECRET en Dokploy y redeploya PROD.

Causa raíz

En s57 se endureció CF Access (quitar bypass-everyone) en dos apps:

El audit de callers de s57 cubrió correctamente los callers batch (5 sitios: GitHub workflows, scripts CLI, crons). Pero omitió los callers Django runtime de PROD:

A partir de s57, todas esas llamadas devolvían 403/302 porque no presentaban CF-Access-Client-Id + CF-Access-Client-Secret.

Impacto

DimensiónDetalle
SeveridadAlta (funcionalidad core del Help Widget completamente rota en PROD)
Afectación usuariosNula (detectado antes de carga real de usuarios)
DuraciónDesde s57 hasta fix en s58 (~1 sesión de trabajo)
Componentes afectadosHelp Widget (proxy bib_ask, lista artículos, traducciones), pre-commit hook bib_report_check

Fix aplicado (PR #26)

core/api_help.py — _workspace_headers()

def _workspace_headers():
    token = getattr(settings, "WORKSPACE_MCP_TOKEN", "")
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }
    cf_id = getattr(settings, "CF_ACCESS_CLIENT_ID", "")
    cf_secret = getattr(settings, "CF_ACCESS_CLIENT_SECRET", "")
    if cf_id and cf_secret:
        headers["CF-Access-Client-Id"] = cf_id
        headers["CF-Access-Client-Secret"] = cf_secret
    return headers

Un solo helper cubre los 3 callers del Help Widget que usaban _workspace_headers().

scripts/harness/bib_report_check.py — _cf_access_headers()

Helper análogo que lee CF_ACCESS_CLIENT_ID / CF_ACCESS_CLIENT_SECRET de env vars y los inyecta en las 2 funciones que llaman a la API Biblioteca.

Settings y compose

Pasos manuales post-merge (PROD)

  1. Configurar CF_ACCESS_CLIENT_ID y CF_ACCESS_CLIENT_SECRET en Dokploy panel del stack PROD.
  2. Redeploy de PROD desde Dokploy.
  3. Verificar Help Widget: preguntar algo (proxy /api/mcp) + abrir lista de artículos (/api/biblioteca/wiki).
  4. Configurar las 2 env vars en PowerShell local de cada miembro del staff (para pre-commit hook al 100%).

Lección aprendida

Cuando se endurezca CF Access (quitar bypass-everyone o equivalente), el audit de callers debe incluir explícitamente los callers Django runtime, no solo workflows/scripts batch. Los callers de Django en PROD no aparecen en los workflows de GitHub — hay que revisar activamente los archivos api_*.py y scripts que llamen a workspace.crearack.com.

Lección registrada en CHANGELOG.md (Lección s58) y RELEASE_NOTES.md v1.0.73 hotfix.

Véase también

Subir