Hardening y secretos del stack LLM soberano: defensa en profundidad
Parte de la serie operativa sobre exprimir un clúster LLM on-premise genérico 4×H100 SXM 80GB. Las piezas hermanas: la ingesta documental de PDF a chunk indexado que llena la base vectorial, el servicio de embeddings y rerankers con TEI en producción que la alimenta, y —la más directamente acoplada a este post— el GitOps del stack de inferencia con Flux, porque GitOps y secretos comparten un problema huevo-gallina que aquí resolvemos. El ensamblado completo de todo esto en un asistente conversacional (LibreChat + LiteLLM + RAG) lo cubre otro post de la serie, todavía en borrador.
TL;DR
Un stack de inferencia LLM soberano son, como mínimo, seis servicios: un gateway (LiteLLM o equivalente), un motor de inferencia (vLLM), un servicio de embeddings/rerankers (TEI), una base vectorial, una base de estado (conversaciones, usuarios) y un front (LibreChat). Seis servicios son seis superficies de ataque, y el asistente “funciona” en cuanto el gateway devuelve tokens — mucho antes de estar endurecido. Este post recorre la defensa en profundidad capa por capa:
- Secretos: nunca en claro en git.
sealed-secrets(cifrado asimétrico, controlador en el clúster) vs SOPS/age (cifrado de fichero, simple, GitOps puro) vs External Secrets Operator + Vault (secretos dinámicos, rotación nativa). El problema huevo-gallina del GitOps. - Red:
NetworkPolicydefault-deny + allow explícito; L3/L4 con la NetworkPolicy estándar, L7 y egress por DNS con Cilium (eBPF); control de egress para que el dato no salga del perímetro; mTLS interno. - Pod security:
runAsNonRoot,readOnlyRootFilesystem, drop de capabilities, seccompRuntimeDefault, Pod Security Standards restricted, nada privilegiado. - Cadena de suministro: pin por digest, escaneo con Trivy, firma con cosign, admission control que rechaza lo no firmado.
- AuthN/Z: claves virtuales de LiteLLM, OIDC/LDAP en el front, RBAC de Kubernetes con mínimo privilegio.
- Runtime: detección y, opcionalmente, enforcement con Tetragon.
- Dato en reposo: cifrado de almacenamiento, credenciales de la base vectorial y de la base de estado.
La tesis: el hardening reduce el radio de impacto, no lo elimina. Por eso se prioriza por impacto, y el primer trabajo en un 4×H100 es el par gateway↔vector store y el egress-deny.
La analogía: el despacho soberano
Imagina un despacho que custodia documentación sensible — el corpus que alimenta el RAG, las conversaciones de los usuarios, las credenciales del motor. No basta con que la puerta de la calle cierre. La seguridad de verdad es defensa en profundidad: varias capas, cada una asumiendo que la anterior puede fallar.
El mapeo es directo:
- El perímetro del edificio es el control de egress: que un secreto filtrado o un proceso comprometido no pueda exfiltrar el corpus a un servidor externo. Es la capa más infravalorada y la primera que pongo en un despliegue soberano.
- El control de accesos en cada puerta interior es la
NetworkPolicydefault-deny: el front no habla con la base vectorial directamente porque no tiene por qué; solo los pares estrictamente necesarios están abiertos. - Los tabiques cortafuegos son el aislamiento de pod (
restricted) y los namespaces: si un servicio arde, el fuego no salta al de al lado. - El portero que verifica credenciales es el admission control que comprueba la firma cosign de cada imagen antes de dejarla entrar al clúster.
- Las cámaras son Tetragon/Falco: registran qué hizo cada proceso y detectan (o matan) lo anómalo.
- La caja fuerte con llave rotada son los secretos: cifrados en reposo, fuera de git, y con rotación para que una llave robada caduque.
Ninguna capa es suficiente sola. El edificio es seguro porque atravesarlas todas es caro.
Capa 1 — Secretos: el problema huevo-gallina del GitOps
El stack se despliega por GitOps: la pieza hermana de Flux reconcilia el estado declarado en git contra el clúster. Eso es excelente para los manifiestos — pero hay un problema fundacional: el motor de inferencia necesita el token de Hugging Face para descargar el modelo, la base de estado necesita su contraseña, el gateway necesita su clave maestra. Esos secretos no pueden ir en claro en git. Cualquiera con acceso de lectura al repo —y en una organización con read generoso eso es mucha gente, más todo backup del repo, más todo fork— los leería.
El huevo y la gallina: GitOps quiere que todo el estado esté en git, pero los secretos no pueden estar en git en claro. La solución, en sus tres familias:
Familia A — sealed-secrets (cifrado asimétrico, controlador en el clúster)
Bitnami Sealed Secrets es un controlador que corre en el clúster más una CLI cliente, kubeseal. Usa criptografía asimétrica: hay un par de claves. La pública la tienen los desarrolladores y sirve para cifrar; la privada vive solo en el controlador del clúster y sirve para descifrar. El flujo:
- El desarrollador toma un
Secretnormal y lo cifra conkubeseal, que obtiene la clave pública del controlador. Resultado: un recursoSealedSecret. - Ese
SealedSecretsí se commitea a git en claro — está cifrado, no es legible. - El controlador en el clúster lo detecta, lo descifra con su clave privada y crea el
Secretde Kubernetes real en el namespace destino.
La propiedad clave: como la clave privada nunca sale del clúster, ni el desarrollador ni nadie con acceso a git puede descifrar. Y el cifrado incluye el nombre del namespace: un SealedSecret sellado para inferencia no se puede mover a front y descifrarlo allí — se comporta como si cada namespace tuviera su propia llave. El controlador gestiona también la rotación de las claves de sellado, etiquetándolas como active o compromised.
Ventaja: encaja perfecto en GitOps puro, el secreto cifrado vive con el resto del estado. Limitación: el secreto, ya descifrado, acaba siendo un Secret de Kubernetes normal — está en etcd, y hay que cifrar etcd aparte (lo veremos en la capa 7).
Familia B — SOPS + age (cifrado de fichero, simple)
SOPS cifra el fichero YAML/JSON entero (o solo sus valores) y lo deja en git cifrado, descifrándolo solo en el momento del despliegue. Soporta KMS de nube (AWS/GCP/Azure), PGP y —lo relevante para soberanía on-premise— age, un esquema de cifrado offline simple sin servidor. El operador de GitOps (Flux trae integración nativa de SOPS) descifra al reconciliar usando la clave age guardada en el clúster.
Ventaja: simple, scriptable, sin servidor que mantener; el peso operativo recae en custodiar la clave age. Es la recomendación habitual para equipos pequeños o para arrancar. Limitación: la rotación es manual (re-cifrar todo con la nueva clave) y no hay secretos dinámicos.
Familia C — External Secrets Operator + Vault (secretos dinámicos, rotación nativa)
El External Secrets Operator (ESO) no guarda secretos en git en absoluto. En git solo va un ExternalSecret: una referencia que dice “el campo password viene del path secret/data/vectordb de tal SecretStore”. El operador lee de un almacén externo —típicamente HashiCorp Vault— y sincroniza el Secret de Kubernetes. Vault guarda los secretos en su propio backend cifrado y los sirve por API autenticada, de modo que nunca residen en git y, con sus motores dinámicos, puede emitir credenciales de base de datos de vida corta que caducan solas.
Ventaja: rotación nativa, secretos dinámicos, auditoría centralizada, un único punto de gobierno. Limitación: hay que operar Vault (sellado/desellado, alta disponibilidad, política de acceso), lo que es trabajo real.
Cómo elegir, y la rotación
| Criterio | sealed-secrets | SOPS + age | ESO + Vault |
|---|---|---|---|
| Secreto en git | cifrado | cifrado | solo referencia |
| Servidor extra | controlador ligero | ninguno | Vault (pesado) |
| Rotación | claves de sellado auto | manual (re-cifrar) | nativa / dinámica |
| Secretos dinámicos (vida corta) | no | no | sí |
| Encaje GitOps puro | excelente | excelente | bueno (referencias) |
| Curva operativa | baja | muy baja | alta |
Para un 4×H100 soberano arrancando, SOPS/age o sealed-secrets cubren el 90% con coste mínimo. Cuando el sistema crece y aparecen requisitos de rotación frecuente y auditoría —típico en escenarios ENS Categoría Alta— se migra a ESO + Vault. La regla de la rotación: un secreto que nunca rota es un secreto que, una vez filtrado, está filtrado para siempre. La rotación no impide la filtración; acota su ventana de validez. Volveremos a ello al hablar de radio de impacto.
Capa 2 — Red: default-deny, egress y la matemática de la superficie
La matemática de los pares de comunicación
Sin política de red, en Kubernetes todos los pods pueden hablar con todos los pods. Esa es la postura por defecto, y es la peor para un sistema soberano. Con $N$ servicios, el número de pares ordenados de comunicación posibles (quién-puede-llamar-a-quién) es:
$$P_{\text{abierto}} = N \cdot (N-1) \approx N^2$$
Con nuestros $N = 8$ componentes (gateway, vLLM, TEI, base vectorial, base de estado, front, además del controlador de secretos y el de observabilidad), eso son $8 \cdot 7 = 56$ pares dirigidos posibles. Cincuenta y seis caminos por los que un servicio comprometido podría pivotar lateralmente.
Ahora aplicamos NetworkPolicy default-deny: nada habla con nada salvo lo explícitamente permitido. La whitelist real de un stack LLM es pequeña. Los pares estrictamente necesarios:
- front → gateway
- gateway → vLLM
- gateway → TEI
- gateway → base vectorial
- gateway → base de estado
- front → base de estado (sesiones/usuarios)
Eso son $E = 6$ aristas. La superficie de comunicación cae de $56$ a $6$:
$$\frac{E}{P_{\text{abierto}}} = \frac{6}{56} \approx 0{,}107$$
Casi un 89% de los caminos posibles quedan cerrados. El front ya no puede tocar vLLM ni TEI ni la base vectorial directamente; si alguien compromete el front, no tiene ruta de red hacia el corpus. Esto es la diferencia entre $\sim N^2$ y una whitelist $E \ll N^2$.
L3/L4 estándar, L7 y egress con Cilium
La NetworkPolicy nativa de Kubernetes opera a L3/L4: selecciona pods por label y permite/deniega por puerto y protocolo. Sirve para el grueso de la whitelist. Pero tiene límites: no entiende DNS ni HTTP. Aquí entra Cilium, que aplica las políticas en el kernel vía eBPF y extiende con CiliumNetworkPolicy:
- Egress por FQDN/DNS: en vez de fijar IPs (que cambian), permitir
egresssolo ahuggingface.copara que vLLM descargue el modelo y bloquear el resto. Crítico para el control de egress. - L7: permitir solo ciertos métodos/paths HTTP entre gateway y un servicio interno.
- Modos de enforcement: en modo por defecto, un endpoint sin política seleccionándolo tiene todo abierto; en modo always, todo está denegado hasta que una política lo abra explícitamente. Para un sistema soberano, always + default-deny es la postura objetivo.
El control de egress es la pieza soberana por excelencia. Que un servicio interno no pueda abrir conexiones a Internet salvo a un puñado de destinos explícitos significa que, aunque comprometan vLLM o el gateway, el corpus no puede salir del perímetro. El RAG es el activo de valor; el egress-deny es lo que impide que se fugue.
mTLS interno
La NetworkPolicy dice quién puede hablar con quién, pero no cifra ni autentica el tráfico este-oeste. Para eso, mTLS (TLS mutuo: cliente y servidor se autentican entre sí). Cilium ofrece autenticación mutua nativa; alternativas como Linkerd o Istio dan una malla de servicios completa. Para un stack de seis servicios, la malla completa de Istio suele ser sobreingeniería; la autenticación mutua de Cilium o Linkerd (más ligero) es proporcional. El efecto: un atacante en la red del clúster no puede suplantar al gateway ni espiar el tráfico interno en claro.
Capa 3 — Pod security: restricted, y nada privilegiado
Las Pod Security Standards definen tres perfiles: privileged (sin restricciones), baseline (lo mínimo razonable) y restricted (endurecido). El objetivo para todo el stack LLM es restricted, aplicado vía Pod Security Admission con label de namespace en modo enforce. El perfil restricted exige:
runAsNonRoot: trueyrunAsUserdistinto de 0. Ningún contenedor corre como root.readOnlyRootFilesystem: true. El sistema de ficheros raíz es de solo lectura; lo que necesite escribir va a unemptyDiro volumen explícito. Un atacante no puede dejar binarios persistentes en el contenedor.drop: ["ALL"]de capabilities de Linux. Sin capacidades que no se necesiten.- seccomp
RuntimeDefault, que aplica el perfil del runtime y bloquea las syscalls peligrosas. allowPrivilegeEscalation: false, nadaprivileged, sin host namespaces.
El matiz con GPU: los pods que usan H100 cargan el device plugin de NVIDIA, lo que históricamente tentaba a relajar el securityContext. No hace falta correr el contenedor de inferencia como privilegiado para usar la GPU; el acceso al dispositivo se gestiona por el plugin, y el pod de vLLM puede y debe correr restricted. Esto es un tabique cortafuegos: si comprometen vLLM, el atacante tiene un proceso no-root, sin capabilities, con FS de solo lectura y syscalls recortadas — un punto de partida pésimo para escalar.
Capa 4 — Cadena de suministro de imágenes
La imagen de contenedor es código de terceros que corre con acceso a tus datos. Tres controles compuestos:
- Pin por digest, no por tag.
vllm/vllm-openai:latestes un blanco móvil;@sha256:...es inmutable. Fijar el digest garantiza que lo que se desplegó es exactamente lo auditado. - Escaneo con Trivy. Antes de promover una imagen, Trivy enumera sus CVEs y compone el SBOM (inventario de componentes). Falla el pipeline si hay vulnerabilidades críticas sin mitigar.
- Firma con cosign y verificación en admission. El proyecto Sigstore (cosign para firmar, Fulcio como CA de certificados efímeros vía OIDC, Rekor como log de transparencia inmutable) permite firmar la imagen. Y el policy-controller de Sigstore —o Kyverno— es un admission controller que verifica la firma antes de admitir el pod: una imagen sin firma válida no entra al clúster.
Este es el portero de la analogía: comprueba la credencial (firma) de cada imagen en la puerta. Una imagen envenenada subida a un registro, o un tag secuestrado, se queda fuera porque no lleva firma del emisor de confianza.
Capa 5 — AuthN/Z: claves virtuales, OIDC y RBAC mínimo
Tres puntos de control de identidad, de fuera adentro:
- Front (OIDC/LDAP). El usuario humano se autentica contra el proveedor de identidad corporativo. El front no inventa su propio sistema de usuarios; delega en OIDC. Esto da SSO, MFA y revocación centralizada.
- Gateway (claves virtuales de LiteLLM). El gateway emite claves virtuales: cada equipo, aplicación o usuario tiene su clave con presupuesto, rate limit y modelos permitidos. La clave maestra del gateway —y las API keys reales hacia el motor— nunca las ve el cliente; solo manejan su clave virtual, revocable individualmente. Si se filtra una clave virtual, se revoca esa y solo esa.
- Kubernetes RBAC con mínimo privilegio. Los
ServiceAccountde cada servicio tienen los permisos justos. El pod de vLLM no necesita listarSecretde otros namespaces ni crear pods. RBAC restrictivo significa que un token de service account robado abre muy poco.
Capa 6 — Runtime: las cámaras con Tetragon
Las capas anteriores son preventivas. Falta la detección: ¿y si algo, pese a todo, se ejecuta donde no debe? Tetragon es seguridad observable y enforcement en runtime sobre eBPF, Kubernetes-aware. Hooka eventos del kernel —process_exec, tcp_connect, security_file_open— con sobrecarga típica por debajo del 1%, y puede pasar de observar (registrar el evento) a enforcement (matar el proceso o cortar la conexión en el kernel, Sigkill).
La regla operativa, que detallo en el runbook de bubblewrap + Tetragon: adopta primero, bloquea después. Primero se despliega en modo observación para levantar un baseline del comportamiento normal del stack —qué binarios ejecuta vLLM, a qué se conecta el gateway— sin falsos positivos. Solo después se promueven a enforcement las reglas claras: matar cualquier proceso que intente leer rutas de secretos, o cortar todo tcp_connect a destinos fuera de la whitelist de egress. Falco es la alternativa detection-only sobre eBPF; Tetragon añade enforcement. Estas cámaras producen, además, la evidencia de auditoría: qué ejecutó cada servicio y qué intento se bloqueó.
Capa 7 — Dato en reposo
Lo último que protegemos es el dato parado:
- Cifrado del almacenamiento. Los volúmenes persistentes —donde viven la base vectorial y la base de estado— sobre cifrado de disco (LUKS/dm-crypt) o cifrado a nivel de Ceph. Un disco robado del CPD no revela el corpus.
- Cifrado de
etcd. Recuerda que losSecretde Kubernetes, una vez descifrados por sealed-secrets o ESO, son objetos normales enetcd. Hay que activar el encryption at rest deetcd, o el secreto está en claro en el plano de control. - Credenciales de las bases. La contraseña de la base vectorial y la de la base de estado son secretos de primera (capa 1), nunca embebidas en el manifiesto ni en variables de entorno en claro en git.
Tabla de exposición: servicio × puerto × ¿egress externo?
Esta tabla es el insumo para escribir las NetworkPolicy. La columna de egress es la que decide qué sale del perímetro.
| Servicio | Puerto interno | Llamantes permitidos | ¿Egress externo? |
|---|---|---|---|
| front | 3080 | (ingress humano vía OIDC) | No |
| gateway (LiteLLM) | 4000 | front | No |
| vLLM | 8000 | gateway | Solo huggingface.co para descarga inicial; cero en operación |
| TEI (embeddings/reranker) | 8080 | gateway | Solo descarga del modelo; cero en operación |
| base vectorial | 6333 | gateway | No |
| base de estado | 5432 | gateway, front | No |
| controlador de secretos | — | (plano de control) | No |
| observabilidad | 9090 | scraping interno | No |
La lectura: ningún servicio necesita egress externo en operación normal. vLLM y TEI lo necesitan una vez para bajar el modelo, y ese permiso puede ser temporal o restringido por FQDN a huggingface.co. Todo lo demás es egress-deny total. Si un servicio empieza a intentar conexiones de salida que esta tabla no contempla, Tetragon lo registra y, en enforcement, lo corta.
Radio de impacto: un secreto filtrado, con y sin defensa
El radio de impacto (blast radius) mide cuánto daño hace un compromiso. Modelémoslo para el peor caso realista: se filtra la credencial de la base de estado.
Sin hardening (red plana, secreto sin rotar, sin egress-deny, sin detección):
- El secreto da acceso a la base de estado desde cualquier pod (red plana → 56 pares abiertos).
- El secreto no rota → es válido indefinidamente; la ventana de explotación es $\infty$ hasta que alguien lo note.
- Sin egress-deny, el atacante vuelca la base entera a un servidor externo.
- Sin Tetragon, nadie se entera hasta el incidente público.
- Radio de impacto: toda la base de estado, exfiltrada, sin detección, por tiempo indefinido.
Con hardening (default-deny, ESO + Vault con credenciales dinámicas, egress-deny, Tetragon en enforcement):
- El secreto solo es usable desde el pod que tiene ruta de red a la base de estado (1-2 pares, no 56).
- Con credenciales dinámicas de Vault, el secreto caduca —digamos en una ventana $T$ de horas—; pasado $T$, no vale nada.
- El egress-deny impide el volcado a Internet: el atacante puede leer, pero no sacar.
- Tetragon registra el acceso anómalo y, en enforcement, mata el proceso que intenta la conexión de salida.
La reducción cualitativa es enorme, pero seamos cuantitativos con la ventana. Si un secreto estático vale para siempre y uno rotado con periodo $T$ vale como mucho $T$, y los compromisos llegan a tasa $\lambda$, el número esperado de secretos vivos y explotables en un instante dado pasa de crecer sin techo a quedar acotado por $\lambda \cdot T$. Con rotación cada 24 h ($T = 1$ día) frente a “nunca”, la ventana de un secreto concreto cae de meses a un día: una reducción de uno a dos órdenes de magnitud en la exposición temporal. Combinado con la reducción de pares de red ($56 \to \sim 2$, factor $\sim 28\times$) y el egress-deny (de exfiltración posible a imposible por la ruta directa), el radio de impacto se reduce drásticamente.
Pero seamos honestos: no llega a cero. El atacante con la credencial puede leer la base de estado durante la ventana $T$ desde el pod comprometido. El hardening convirtió “catástrofe indefinida y silenciosa” en “incidente acotado, detectado y sin exfiltración por la vía directa”. Eso es exactamente lo que la defensa en profundidad promete: no la invulnerabilidad, sino que el coste de un compromiso completo sea alto y su radio, pequeño.
Ángulo ENS / NIS2
Estas capas no son higiene voluntaria: materializan controles concretos. El mapeo lo desarrolla en detalle el post de controles técnicos ENS × ISO 42001 × EU AI Act; aquí, el resumen accionable:
| Capa de hardening | Medida ENS (RD 311/2022) | Vínculo NIS2 / marco |
|---|---|---|
| Secretos cifrados + rotación | op.exp.11 (claves criptográficas), mp.info.3 (cifrado) | Gestión de credenciales; en Cat. Alta, HSM |
| NetworkPolicy default-deny + segmentación | mp.com.1 (perímetro), mp.com.4 (separación de flujos) | NIS2 art. 21: medidas de seguridad de red |
| Control de egress | mp.com.1 + op.mon.1 | Prevención de exfiltración |
| mTLS interno | mp.com.2-3 (confidencialidad/integridad en tránsito) | TLS obligatorio |
| Pod Security restricted | op.exp.2 (config endurecida) | Hardening de configuración (CIS) |
| Trivy + cosign + admission | op.exp.6 (código dañino), op.ext.3 (cadena de suministro) | NIS2 supply chain |
| OIDC + claves virtuales + RBAC | op.acc.1-2-5 (identificación, acceso, autenticación) | MFA en Cat. Alta |
| Tetragon runtime | op.mon.1 (detección de intrusión) | Monitorización y respuesta |
| Cifrado en reposo + etcd | mp.info.3 (cifrado), mp.si (soportes) | Dato en reposo |
La nota honesta para auditoría: el hardening reduce el riesgo, no lo elimina, y la madurez se demuestra priorizando por impacto. Un auditor competente no quiere ver las nueve capas a medias; quiere ver que el egress-deny del activo crítico (el corpus) y la gestión de secretos están sólidos antes que el mTLS perfecto entre servicios de baja sensibilidad. Para el contexto de gestión y gobernanza, ver también ISO/IEC 42001 como AIMS y el mapeo del EU AI Act sobre la arquitectura.
Aplicado al clúster genérico 4×H100
En un despliegue real sobre 4×H100 SXM 80GB, no se endurecen las nueve capas a la vez. El orden, priorizado por impacto:
- Egress-deny sobre vLLM, TEI y la base vectorial, primero. Es la barrera que impide que el corpus salga del perímetro, y se pone en cuanto los servicios arrancan. Permite egress por FQDN a
huggingface.cosolo durante la descarga inicial del modelo; después, cero. Es la capa de mayor retorno por hora invertida. - Secretos del motor de inferencia y de las bases, fuera de git. El token de Hugging Face que usa vLLM para descargar el modelo, las contraseñas de la base vectorial y de la base de estado, la clave maestra del gateway: a sealed-secrets o, si ya hay requisito de rotación, a ESO + Vault. Nunca en el
values.yamlen claro. - NetworkPolicy default-deny + la whitelist de 6 aristas. El gateway y la base vectorial son los servicios más expuestos —el gateway porque recibe todo el tráfico, la base vectorial porque custodia el RAG embebido—. Cerrar todo lo que no sea la whitelist recorta el pivoteo lateral del $\sim N^2$ a las 6 aristas reales.
- Pod Security
restricteden el namespace de inferencia, incluido el pod de vLLM con GPU (no necesita privilegios para usar la H100). - cosign + admission para que solo entren imágenes firmadas; Trivy en el pipeline de GitOps de Flux.
- Tetragon en observación, baseline, y luego enforcement sobre el egress de los pods sensibles.
- Cifrado en reposo de los volúmenes de las bases y de
etcd.
El gateway y la base vectorial son los dos que endurezco primero dentro de la whitelist: el gateway por ser la cara expuesta, la base vectorial por contener el activo que el egress-deny protege. El resto se construye encima, capa a capa, asumiendo siempre que la anterior puede fallar.
Lo que el hardening NO resuelve
Para cerrar con honestidad, lo que estas capas no cubren y necesita otras piezas:
- Ataques a nivel de prompt (jailbreak, inyección indirecta vía el corpus RAG): eso es trabajo de guardrails y LLM Guard, no de NetworkPolicy.
- Agentes con permisos legítimos que hacen algo dañino: el aislamiento de runtime del post de aislar agentes acota qué puede tocar un agente, pero un permiso concedido es un permiso usable.
- El factor humano: un secreto bien gestionado pero compartido por Slack sigue filtrado. La rotación acota la ventana, no elimina el error.
- Vulnerabilidades zero-day en los propios componentes: Trivy detecta lo conocido; lo desconocido pasa hasta que se publica el CVE.
El hardening es un multiplicador del coste de atacar, no un muro infranqueable. Su valor está en hacer que un compromiso individual quede acotado, detectado y sin salida — y eso, para un sistema soberano que custodia datos sensibles, es exactamente el objetivo.
Ver también
- GitOps del stack de inferencia con Flux — la pieza hermana: GitOps reconcilia el estado, y comparte con este post el problema huevo-gallina de los secretos.
- Controles técnicos: ENS × ISO 42001 × EU AI Act — el mapeo detallado de cada capa de hardening a medida ENS, control 42001 y artículo del AI Act.
- ISO/IEC 42001: el AIMS del LLM on-premise — el sistema de gestión que enmarca el hardening como control documentado.
- EU AI Act: mapeo sobre la arquitectura LLM on-premise — los artículos de robustez y ciberseguridad (Art. 15) que estas capas satisfacen.
- LLM Guard: fundamentos — la capa de seguridad a nivel de prompt/contenido que el hardening de infraestructura no cubre.
- Guardrails y safety en LLMs — el WAF semántico complementario a la NetworkPolicy.
- Aislar agentes de IA: del workstation al clúster — el modelo de amenaza del aislamiento de runtime.
- Runbook: enjaular al agente de IA con bubblewrap y Tetragon — el procedimiento operativo de Tetragon (observar primero, bloquear después) referenciado en la capa 6.