Files
chemavxandClaude Opus 5 b19bb4d414 auditoría: quitar la excepción de reddit-intel
Los manifiestos que amparaba ya no existen, así que la excepción solo podía
envejecer. La auditoría queda en 0 hallazgos nuevos y 4 esperados (antes 13:
los otros 8 eran precisamente reddit-intel inactivo).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 20:12:45 +00:00
..

tools/

audita-exports.py — ¿miente este repo?

Compara cada manifiesto con el objeto que hay desplegado de verdad.

python3 tools/audita-exports.py            # informe (sale 1 si hay algo nuevo)
python3 tools/audita-exports.py -v         # incluye las excepciones y su motivo
python3 tools/audita-exports.py -d gitea   # sólo esos directorios

Por qué existe

Sólo mira los directorios que no gestiona ArgoCD. En los que sí, ArgoCD ya compara git contra el cluster cada 3 minutos y lo marca OutOfSync; ahí la deriva no puede esconderse. En los demás —monitoring, argocd, authentik, gitea, homarr, vaultwarden, cloudflare-ddns, cluster-wide…— nadie comprueba nada: git es documentación, y una documentación desfasada es peor que no tenerla, porque se aplica creyendo que restaura y en realidad rompe.

La primera pasada (2026-07-22) encontró, sobre 175 objetos:

  • argocd/deployment-argocd-redis.yaml no llevaba el anclaje al control-plane ni los límites de recursos. Aplicarlo deshacía el arreglo del Exit Code 255.
  • A gitea/configmap-daemon-json.yaml le faltaban dos insecure-registries que sí estaban vivos: aplicarlo dejaba a la CI sin poder subir imágenes.
  • El ConfigMap buildkitd-config llevaba 90 días desplegado sin manifiesto.
  • Siete imágenes con tag flotante: git decía gitea:1.25.5 y el cluster corría 1.27.0, subido solo en algún reinicio.

Recordatorio que explica cómo se llega a eso: en estos directorios un commit no despliega nada. Hay que editar el fichero y kubectl apply.

Cómo leer la salida

Tipo Significa
DIFIERE el fichero afirma algo que ya no es cierto
SOLO VIVO hay algo desplegado que el fichero no menciona
NO DESPLEGADO el fichero describe un objeto que no existe

Lo normal es terminar en hallazgos NUEVOS: 0. Si sale algo, o el cluster se tocó a mano sin actualizar el fichero (regenéralo), o el fichero se cambió sin aplicarlo (aplícalo), o es una excepción legítima (justifícala abajo).

excepciones-auditoria.yaml

Un informe que siempre saca ruido deja de leerse, así que las excepciones conocidas se declaran ahí con su motivo. El script avisa cuando una excepción ya no se dispara: significa que aquello se arregló y la entrada sobra.

Temporizador semanal

audita-semanal.py pasa la auditoría y decide si molestar. Instalado como servicio de host en chemavx-k8 (fuera del cluster, como seo-watch y el canario de hermes):

sudo cp tools/audita-exports.{service,timer} /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now audita-exports.timer
systemctl list-timers audita-exports.timer      # sábados 07:00 UTC
sudo systemctl start audita-exports.service     # forzar una pasada

Callado por diseño. Sólo escribe a Telegram si hay hallazgos nuevos y cambian respecto a la semana anterior: si la deriva sigue igual porque aún no se ha arreglado, no repite. Un aviso que llega todas las semanas deja de leerse.

Qué sí rompe el silencio:

Situación Aviso
Deriva nueva 🟠 con el informe
El repo local por detrás de origin 🟠/🟡 — se comparó contra ficheros viejos
Excepciones que ya no se disparan 🟡 — sobran, bórralas
El propio auditor ha fallado 🔴 — un vigilante roto no es un "todo bien"

Tener cambios sin commitear no avisa: es estado de trabajo normal y la copia local es justamente la intención que hay que comparar. Sale como contexto entre paréntesis cuando ya se avisa por otra cosa.

Probado viéndolo hacer las cuatro cosas, no sólo la buena: con el repo limpio se calla; con una deriva inyectada manda el aviso; repetida la misma deriva no insiste; y con el auditor roto a propósito (error de sintaxis y muerte temprana) manda el 🔴. Ojo con ese último caso: un error de sintaxis en Python sale con código 1, el mismo que "hay deriva", así que no basta mirar el código de salida — se exige además que el informe traiga su línea de resumen.

El token de Telegram sale del secret grafana-telegram-infisical (ns monitoring), el mismo que usan seo-watch y hermes-bot. Al venir de Infisical, una rotación llega sola a los tres y no hay copia en disco.

Lo que NO hace

No compara valores de Secret —sólo nombres de clave—, se salta lo que ignora .gitignore (los kube-root-ca.crt y ServiceAccounts default autogenerados) y no toca nada: es de sólo lectura.

Un aviso por experiencia propia: el imageID de un pod no siempre es el digest del registro. Si viene como repo@sha256:… lo es; si es un sha256:… pelado es el id local de containerd y no se puede descargar — fijar una imagen a ese valor da ImagePullBackOff. Para comparar imágenes, repoDigest contra repoDigest, con sudo k3s crictl inspecti <ref>.