Cerrar el auto-reinicio: fail-closed, permisos por nombre y fallo visible

Tres agujeros que encontro una review adversarial de Codex sobre el trabajo
de ayer. Los tres verificados contra el fichero antes de tocar nada.

1. El webhook publico fallaba en ABIERTO. Con `optional: true` y un
   `if (secreto && ...)`, la ausencia del secreto equivalia a autorizacion:
   cualquier POST con heartbeat.status=0 y un monitor.name del mapa reiniciaba
   n8n, Gitea, ArgoCD, Vaultwarden o los blogs. El argumento para dejarlo asi
   era "que un despiste no te deje sin avisos", y era falso: el aviso de caida
   lo manda Kuma por su notificacion 1, directa, no por este webhook.
   Ahora el secreto es obligatorio (sin `optional`) y la puerta rechaza si
   falta. Secreto ausente da error ruidoso; cabecera que no casa, vacio.

2. El ClusterRole permitia patch sobre CUALQUIER deployment de 10 namespaces,
   y la SA va montada en el pod entero de n8n: cualquier workflow con un nodo
   Code heredaba eso. Ahora son Roles por namespace con resourceNames sobre
   los 12 workloads exactos del SERVICE_MAP.

3. El flujo daba exito aunque el PATCH fallara. `restartOk` se calculaba y se
   tiraba: `K8s API Check Status` construia un objeto nuevo sin el, y el IF
   final solo miraba `statusOk`. Un 403 sobre un servicio ya sano mandaba
   "reiniciado correctamente". Ahora hay rama de fallo tras el PATCH y el
   exito exige observedGeneration >= la generation que devolvio el PATCH.
   Se compara con >= porque selfHeal de ArgoCD revierte la anotacion y vuelve
   a subir la generation; con == daria un fallo falso.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 08:02:07 +00:00
co-authored by Claude Opus 5
parent 6454b56fe3
commit 50f090bbea
3 changed files with 482 additions and 335 deletions
+11 -3
View File
@@ -67,14 +67,22 @@ spec:
# webhook /webhook/uptime-kuma-restart es público y desde hoy sí
# reinicia servicios de verdad, así que no puede quedar abierto.
# ⚠️ FUERA DE GIT a propósito (secret n8n-kuma-webhook, creado con
# kubectl): si algún día falta, el workflow NO deja de avisar — se
# salta la comprobación y sigue, que es como se comportaba antes.
# kubectl).
#
# SIN "optional: true" desde el 2026-07-31: si el secreto falta, el
# pod NO arranca. Antes arrancaba y el workflow se saltaba la
# comprobación, o sea que la ausencia de credencial equivalía a
# autorización en un endpoint expuesto a internet. El argumento para
# dejarlo abierto era "que un despiste no te deje sin avisos", y era
# falso: el aviso de caída lo manda Kuma por su notificación 1
# (Telegram, directa). Fallar en cerrado no cuesta ni un aviso —
# solo el reinicio automático. Un pod que no arranca se ve; un
# webhook abierto, no.
- name: KUMA_WEBHOOK_TOKEN
valueFrom:
secretKeyRef:
name: n8n-kuma-webhook
key: KUMA_WEBHOOK_TOKEN
optional: true
# n8n ≥1.x bloquea $env en expresiones por defecto; sin esto el nodo
# HTTP del autopost no puede leer GETXAPI_TOKEN. Instancia single-user.
- name: N8N_BLOCK_ENV_ACCESS_IN_NODE