CoffeeTest
PodcastBlogContraseñaDonar
CoffeeTestLet's talk about QA and code. Join us cup by cup.
    Desarrollo

    Kubernetes Secrets: el caos silencioso que nadie configura bien

    CoffeeTest Team
    26 de abril de 2026

    ⏱️ Tiempo de lectura estimado: 7 minutos

    ¿Alguna vez has hecho un kubectl describe pod en producción y visto una variable de entorno con una contraseña en texto plano? Yo sí. Y no fue un proyecto pequeño. Fue un servicio que procesaba pagos. El silencio en el canal de Slack después de ese hallazgo fue ensordecedor.

    La gestión de secretos en Kubernetes es uno de esos temas que todo el mundo aplaza hasta que no puede aplazarlo más. Y el problema no es que sea difícil — es que parece fácil al principio, y eso es exactamente lo que lo hace peligroso.

    Por qué los Kubernetes Secrets por defecto son una trampa disfrazada de solución

    Cuando alguien empieza con Kubernetes, aprende rápido sobre los Secrets. Creas un objeto, metes tu contraseña codificada en base64, lo referencias en el pod y listo. Funciona. El cluster arranca. Todo verde.

    El problema es que base64 no es cifrado. Es codificación. Cualquier persona con acceso al cluster puede hacer kubectl get secret mi-secreto -o jsonpath='{.data.password}' | base64 -d y ver tu contraseña en texto plano. Sin esfuerzo. En segundos.

    Y ojo que el problema se multiplica cuando los Secrets se almacenan en etcd — la base de datos interna de Kubernetes — sin cifrado en reposo por defecto. En la mayoría de instalaciones estándar, si alguien tiene acceso físico o lógico a etcd, tiene acceso a todo.

    Ahora bien, esto no significa que Kubernetes sea inseguro. Significa que la configuración por defecto no está pensada para producción con datos sensibles, y hay que hacer trabajo adicional.

    El error más común: meter secretos en el repositorio

    Antes de hablar de soluciones, hay que nombrar al elefante en la sala. He visto equipos completos — buenos equipos, con gente inteligente — cometer el error de commitear archivos .env o manifiestos YAML con secretos directamente en el repositorio. A veces en repos privados, a veces no.

    Un repo privado no es una bóveda. Los tokens de acceso se rotan, los permisos cambian, los colaboradores van y vienen. Si el secreto está en el historial de git, está comprometido para siempre. No hay git push --force que lo borre de todos los clones existentes.

    La regla es simple: ningún valor sensible toca el repositorio. Nunca. Ni en ramas de desarrollo.

    Tres patrones que realmente funcionan para gestionar secretos en Kubernetes

    El ecosistema tiene varias soluciones maduras. No hay una sola respuesta correcta — depende del tamaño del equipo, la infraestructura existente y cuánto dolor estás dispuesto a asumir en la configuración inicial.

    1. Sealed Secrets: cifrado que vive en el repo

    Sealed Secrets, de Bitnami, es una de mis opciones favoritas para equipos que quieren GitOps sin comprometer seguridad. La idea es ingeniosa: usas una CLI (kubeseal) para cifrar el secreto con la clave pública del cluster. El resultado es un SealedSecret — un objeto que sí puedes commitear en git porque solo el cluster puede descifrarlo.

    En mi experiencia, esto funciona muy bien para equipos medianos que ya usan ArgoCD o Flux. El flujo queda limpio: el desarrollador cifra el secreto localmente, lo commitea, el operador de CD lo aplica, y Kubernetes lo descifra internamente.

    El punto débil: si pierdes la clave privada del cluster, pierdes el acceso a todos los secretos cifrados. El backup de esa clave es crítico y no es negociable.

    2. External Secrets Operator: la solución enterprise sin el drama

    Si tu organización ya usa HashiCorp Vault, AWS Secrets Manager, Azure Key Vault o GCP Secret Manager, External Secrets Operator (ESO) es probablemente la respuesta correcta.

    ESO actúa como un puente: defines un ExternalSecret en Kubernetes que apunta a un secreto en tu proveedor externo, y el operador se encarga de sincronizarlo periódicamente como un Secret nativo. Tu aplicación no sabe la diferencia — sigue consumiendo un Secret de Kubernetes normal.

    Lo que me gusta de este enfoque es que centraliza la gestión de secretos en una herramienta dedicada, con auditoría, rotación automática y control de acceso granular. Lo que no me gusta: añade una dependencia externa y si esa dependencia falla, tus pods no pueden arrancar. El monitoring de esa integración es tan importante como la integración misma.

    3. Vault Agent Injector: para cuando necesitas control total

    HashiCorp Vault con el Agent Injector es la opción más potente y la más compleja. En lugar de sincronizar secretos como objetos de Kubernetes, el agente los inyecta directamente en el sistema de archivos del pod en tiempo de ejecución. Los secretos nunca persisten en etcd.

    Esto es especialmente útil para secretos de vida corta — tokens que expiran en minutos, certificados dinámicos, credenciales de bases de datos generadas al vuelo. Vault puede generar una contraseña única por cada conexión de base de datos, y revocarla cuando el pod muere.

    Dicho esto, configurar Vault correctamente requiere tiempo. No es algo que montas en una tarde. Si tu equipo no tiene experiencia con Vault, espera al menos una semana de trabajo dedicado antes de tenerlo estable en producción.

    Cifrado en reposo en etcd: el paso que todos olvidan

    Independientemente de la herramienta que elijas, hay una configuración base que deberías activar en cualquier cluster que maneje datos sensibles: el cifrado en reposo de etcd.

    Kubernetes soporta esto nativamente a través del EncryptionConfiguration. Puedes configurar el API server para que cifre los Secrets antes de escribirlos en etcd usando AES-CBC o AES-GCM. No es magia — si alguien tiene acceso al API server con los permisos correctos, sigue pudiendo leer los secretos. Pero protege contra acceso directo a los archivos de etcd.

    Si estás en un managed Kubernetes (EKS, GKE, AKS), revisa la documentación del proveedor porque suelen tener opciones específicas para habilitar esto, y a veces están desactivadas por defecto.

    Una cosa que cambia todo: RBAC aplicado a Secrets

    Todo lo anterior pierde valor si cualquier ServiceAccount en el cluster puede listar y leer todos los Secrets. El RBAC de Kubernetes te permite ser quirúrgico: que el pod A solo pueda leer el secreto A, y nada más.

    Algo que me ha funcionado bien es aplicar el principio de mínimo privilegio de forma estricta: cada aplicación tiene su propio ServiceAccount, ese ServiceAccount tiene acceso únicamente a los Secrets que necesita, y nadie más. Cuando hay un incidente de seguridad, el radio de explosión queda contenido.

    Revisa los ClusterRoles existentes en tu cluster. Si ves secrets: ["*"] en algún Role que no es el del sistema, es hora de tener una conversación con el equipo.


    Antes de irte

    Si llevas tiempo sabiendo que la gestión de secretos en tu cluster no está bien y lo has ido dejando para después, te entiendo perfectamente. Es uno de esos temas que siempre cede ante las features urgentes y los bugs de producción. Pero también es el tipo de deuda técnica que cuando cobra, cobra con intereses.

    Elige una sola cosa de las que leíste hoy — aunque sea revisar quién tiene acceso a tus Secrets con RBAC — y hazla esta semana. Los cambios grandes siempre empiezan por algo pequeño y concreto.

    #Kubernetes
    #DevOps
    #Seguridad
    #Secrets
    #CI/CD
    #Infraestructura
    #HashiCorp Vault
    #GitOps

    💬 Comentarios