Mejores Prácticas para la Gestión Segura de Credenciales en Jenkins
Almacene los secretos de Jenkins de forma segura con el Plugin de Credenciales, ámbito de carpeta, withCredentials, RBAC, rotación y bóvedas externas.
Mejores Prácticas para la Gestión Segura de Credenciales en Jenkins
Los trabajos de Jenkins a menudo necesitan secretos cercanos a producción: tokens de nube, contraseñas de registro, claves de despliegue, certificados de firma y credenciales de API. Si esos secretos terminan en un Jenkinsfile, registro de consola o parámetro de trabajo, su sistema CI/CD se convierte en una ruta directa hacia la vulnerabilidad.
Utilice el Plugin de Credenciales, mantenga las credenciales con un ámbito limitado e inyéctelas solo para el paso que las necesita.
El Fundamento: El Plugin de Credenciales de Jenkins
El Plugin de Credenciales es el mecanismo estándar que Jenkins utiliza para almacenar datos sensibles. Proporciona un repositorio centralizado y cifrado para las credenciales, asegurando que los secretos nunca se expongan en registros de compilación, control de versiones o archivos de configuración.
Cuando Jenkins almacena credenciales, las cifra utilizando material clave en el controlador de Jenkins, incluidos los archivos bajo JENKINS_HOME/secrets. Cualquier persona con acceso amplio al sistema de archivos del controlador y a la configuración de Jenkins puede potencialmente recuperar secretos, por lo que el acceso al sistema de archivos y del administrador debe estar estrictamente controlado.
Tipos Clave de Credenciales
Comprender los tipos de credenciales disponibles es el primer paso hacia una implementación segura. Elija el tipo que se corresponda con mayor precisión al secreto que se almacena:
- Texto Secreto: Se utiliza para valores de texto cortos y genéricos como tokens de API, claves de acceso, tokens OAuth o secretos de webhooks.
- Nombre de Usuario y Contraseña: Combinación estándar utilizada para la autenticación contra servicios como repositorios Maven, registros privados (Docker Hub, Artifactory) o aplicaciones internas.
- Nombre de Usuario SSH con Clave Privada: Esencial para acceder a agentes remotos, clonar repositorios Git privados o ejecutar comandos en infraestructura remota. La clave privada se puede introducir directamente, proporcionar como una ruta o ser gestionada por el controlador de Jenkins.
- Archivo Secreto: Se utiliza para subir archivos completos que son sensibles, como almacenes de claves, certificados (
.pem,.crt) o archivos de configuración que contienen secretos.
Consejo: Utilice siempre el tipo de credencial más granular posible. Por ejemplo, si solo necesita una clave de API, use Texto Secreto en lugar de intentar encajarla en un campo de Nombre de Usuario y Contraseña.
Principio de Mínimo Privilegio: Ámbito de las Credenciales
El ámbito de las credenciales determina dónde son accesibles dentro del entorno de Jenkins. Aplicar el principio de mínimo privilegio—otorgar solo el acceso necesario para el trabajo—es crucial.
1. Ámbito de Sistema
Las credenciales con ámbito de sistema (almacenadas bajo Administrar Jenkins > Administrar Credenciales > Jenkins) están disponibles globalmente para todos los trabajos, carpetas y pipelines en la instancia de Jenkins.
- Uso: Solo use el ámbito de Sistema para secretos requeridos por toda la operación de Jenkins, como credenciales utilizadas por plugins de configuración global o secretos necesarios para todas las conexiones de agentes.
- Advertencia: Minimice el uso del ámbito de Sistema. Cualquier trabajo comprometido podría potencialmente acceder a todos los secretos disponibles globalmente.
2. Ámbito de Carpeta
Las credenciales con ámbito de carpeta se definen dentro de una carpeta específica (creada usando el plugin de Carpeta o a través de carpetas de Organización). Estos secretos solo son visibles y utilizables por los trabajos que residen dentro de esa carpeta y sus subcarpetas.
- Recomendación: Prefiera siempre el ámbito de Carpeta. Esto compartmentaliza el acceso y limita el radio de explosión si un proyecto se ve comprometido.
Inyección Segura en Pipelines Declarativos
No codifique credenciales de forma fija en los scripts de pipeline. Las variables de entorno son aceptables solo cuando Jenkins las inyecta para un bloque estrecho y enmascara los valores de secretos conocidos en los registros.
El método seguro para acceder a las credenciales en un Pipeline Declarativo es usar el paso integrado withCredentials. Este paso carga la credencial especificada en una variable de entorno con ámbito que solo está disponible durante la ejecución del bloque.
Ejemplo 1: Inyectando Texto Secreto (Token de API)
Este ejemplo recupera de forma segura una credencial de Texto Secreto (MY_API_TOKEN) y asigna su valor a la variable interna SECRET_TOKEN. Una vez que el bloque withCredentials finaliza, SECRET_TOKEN se elimina automáticamente del entorno.
pipeline {
agent any
stages {
stage('Desplegar vía API') {
steps {
script {
withCredentials([string(credentialsId: 'MY_API_TOKEN', variable: 'SECRET_TOKEN')]) {
sh "echo 'Llamando a API externa...'"
sh '''
curl -X POST \
-H "Authorization: Bearer $SECRET_TOKEN" \
https://api.micorp.com/deploy
'''
}
}
}
}
}
}
Ejemplo 2: Inyectando Nombre de Usuario y Contraseña
Al usar credenciales de Nombre de Usuario y Contraseña, el paso withCredentials divide el secreto en dos variables: una para el nombre de usuario y otra para la contraseña, típicamente sufijadas con _USR y _PSW (o nombres personalizados).
pipeline {
agent any
stages {
stage('Iniciar Sesión en el Registro') {
steps {
withCredentials([usernamePassword(credentialsId: 'DOCKER_REGISTRY_CRED', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh '''
printf '%s' "$DOCKER_PASS" | docker login \
--username "$DOCKER_USER" \
--password-stdin mi.registro.com
'''
}
}
}
}
}
Advertencia de Seguridad: Supresión de Registros
Jenkins intenta enmascarar los valores de credenciales conocidos en los registros de compilación, pero el enmascaramiento no sustituye a los scripts cuidadosos. No imprima secretos, pase contraseñas en líneas de comandos ni ejecute rastreo de shell (
set -x) alrededor del uso de secretos.
Integración de Seguridad Avanzada
Para entornos de alta seguridad, confiar únicamente en la clave maestra local de Jenkins a menudo es insuficiente. Integrarse con un sistema de gestión de secretos externo proporciona separación de responsabilidades, auditoría centralizada y capacidades de cifrado mejoradas.
Almacenes de Credenciales Externos
Las integraciones populares incluyen:
- HashiCorp Vault: Usando el Plugin de Vault, Jenkins puede solicitar dinámicamente secretos a Vault en tiempo de ejecución. Esto significa que los secretos nunca se almacenan permanentemente en el controlador de Jenkins, solo temporalmente en memoria durante la fase de ejecución.
- AWS Secrets Manager/Azure Key Vault: Los plugins nativos de la nube permiten a los pipelines recuperar secretos directamente de estos servicios utilizando roles IAM o entidades de servicio, minimizando la exposición de credenciales estáticas.
El uso de almacenes externos se alinea con las mejores prácticas de seguridad al:
- Separar el Almacenamiento: La infraestructura de secretos está desacoplada del servidor CI/CD.
- Acceso Dinámico: Los secretos pueden rotarse con frecuencia sin requerir actualizaciones manuales de configuración de Jenkins.
- Auditoría Mejorada: Todos los intentos de acceso a secretos se registran dentro del sistema de bóveda externo.
Control de Acceso Basado en Roles (RBAC)
Implementar un plugin de RBAC (como la Estrategia de Autorización Basada en Roles) permite a los administradores controlar no solo quién puede ejecutar un trabajo, sino también quién puede configurar y ver credenciales específicas.
- Restrinja los permisos de configuración de trabajos para que solo los usuarios de confianza puedan vincular credenciales en pipelines.
- Restrinja la capacidad de modificar o crear credenciales a nivel de Sistema a un pequeño grupo de administradores de seguridad o plataforma.
Mejores Prácticas de Gestión de Credenciales
| Práctica | Descripción | Beneficio de Seguridad |
|---|---|---|
| Usar Ámbito de Carpeta | Limitar el acceso a las credenciales a los trabajos/carpetas específicos que las requieren. | Limita la exposición y el radio de explosión. |
| Evitar la Codificación Fija | Nunca coloque secretos en Jenkinsfile, scripts de compilación o control de versiones. |
Elimina la vulnerabilidad del código fuente. |
Usar withCredentials |
Inyecte secretos de forma segura en los pasos del pipeline usando la API oficial de Jenkins. | Asegura la redacción automática de registros y la limpieza del entorno. |
| Integrar Bóveda Externa | Use Vault, AWS Secrets Manager o Azure Key Vault para implementaciones empresariales. | Desacopla el almacenamiento y permite la rotación dinámica. |
| Aplicar RBAC | Use plugins de autorización para restringir quién puede configurar, ver y usar credenciales. | Aplica el principio de mínimo privilegio entre los usuarios. |
| Rotación Regular | Rote las claves de API y contraseñas regularmente (idealmente automatizado mediante una bóveda externa). | Minimiza la ventana de tiempo para que los secretos comprometidos sean explotados. |
| Asegurar el Controlador | Asegure permisos estrictos del sistema de archivos en el controlador de Jenkins para proteger master.key. |
Protege el mecanismo de cifrado central. |
Trate las credenciales de Jenkins como secretos de producción. Ámbelas estrictamente, vincúlelas brevemente, rótelas regularmente y mantenga el acceso al controlador limitado a las personas autorizadas para recuperar esos secretos.