Imagínate: vas a una entrevista, y el entrevistador pregunta: «¿Cómo proteges tus secretos en los microservicios?» Te pones a sudar nervioso, porque justo ayer por accidente commiteaste tus application.properties con el login y la contraseña de la base de datos en un repositorio público en GitHub. Suena aterrador, ¿no? Pero esto le pasa incluso a desarrolladores con experiencia.
En el mundo de los microservicios los secretos están por todas partes: variables de entorno, archivos de configuración, bases de datos, API keys, access tokens y mucho más. Los problemas principales incluyen:
- Filtración de datos confidenciales. Cuando los secretos se almacenan en el código o en el sistema de control de versiones (sí, eso es mala idea).
- Necesidad de gestionar secretos de forma centralizada. Imagínate que tienes 50 microservicios y decides cambiar una API key. ¿Pesadilla? Sí.
- Seguridad del acceso. Incluso si configuras bien la gestión de secretos, hace falta controlar quién y qué puede obtener.
Tarea: organizar una gestión segura de secretos
Ya hemos conocido HashiCorp Vault e integrado con él. Ahora veamos qué enfoques e herramientas existentes nos ayudan a asegurar los datos.
Enfoques y herramientas principales
1. Almacenar secretos fuera del código
Lo más básico. En ningún caso los secretos deben estar en repositorios de código! En su lugar utiliza:
- HashiCorp Vault — almacenamiento centralizado.
- AWS Secrets Manager o Azure Key Vault para servicios en la nube.
- Variables de entorno. Sí, a veces es aceptable, pero ten cuidado.
Ejemplo de mala práctica:
// Error grave: nunca hagas esto!
String dbPassword = "super_secret_password";
Ejemplo de buena práctica con variables de entorno:
String dbPassword = System.getenv("DB_PASSWORD");
O usando Vault con Spring:
// La configuración se lee automáticamente gracias a Spring Cloud Vault
@Value("${db.password}")
private String dbPassword;
2. Minimizar el acceso a datos confidenciales
Hagamos una analogía. No le darías acceso a tu cuenta bancaria a todos tus amigos, ¿verdad? Lo mismo con los secretos. Usa:
- Rolling tokens. Permiten cambiar secretos con frecuencia.
- Control de acceso basado en roles (RBAC). Por ejemplo, en HashiCorp Vault puedes configurar que los servicios tengan acceso solo a lo necesario.
- Auditoría de acceso. Cualquier acceso a los secretos debe registrarse. Si Petya accidentalmente pidió la contraseña de la base de producción, tienes que saberlo.
Ejemplo de configuración de una policy en Vault:
path "secret/data/my-service" {
capabilities = ["read"]
}
3. Cifrado de secretos
Si los secretos se transmiten o almacenan, deben estar cifrados. Usa:
- Spring Cloud Vault para leer valores cifrados.
- BCrypt o AES para cifrado local.
Ejemplo: cifrado en el lado del cliente.
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class EncryptionExample {
public static void main(String[] args) throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecretKey secretKey = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
String plaintext = "¡Esto es un secreto!";
byte[] encryptedData = cipher.doFinal(plaintext.getBytes());
System.out.println("Encrypted: " + new String(encryptedData));
}
}
4. Uso del versionado de secretos
HashiCorp Vault, AWS Secrets Manager y otras herramientas soportan gestión de versiones de secretos. Esto permite actualizar tokens de forma segura.
Ejemplo:
- Se actualizó el secreto en Vault.
- Los microservicios se cambiaron automáticamente a la nueva versión.
5. Actualizar secretos "al vuelo"
Usa Spring Cloud Bus y enfoques event-driven para notificar a otros servicios cuando un secreto cambia.
Ejemplo:
@RefreshScope // Actualiza automáticamente los campos cuando cambia la configuración
@RestController
public class ExampleController {
@Value("${some.secret}")
private String someSecret;
@GetMapping("/secret")
public String getSecret() {
return someSecret;
}
}
Problemas al almacenar secretos y sus soluciones
¿Cuántas veces oímos: "He commiteado un secreto en el repositorio"? Esto le pasa incluso a desarrolladores con experiencia. Aquí está lo que hay que hacer:
- Escanear repositorios en busca de fugas de secretos con herramientas como GitGuardian o TruffleHog.
- Eliminar automáticamente secretos del historial de Git (si eso pasó). Por ejemplo:
git filter-branch --force --index-filter \
'repo-cleanup-command' --prune-empty --tag-name-filter cat -- --all
Herramientas y métodos para garantizar la seguridad
Uso de proveedores de secretos
- HashiCorp Vault para gestión centralizada.
- AWS Secrets Manager — ideal en infraestructuras en la nube de AWS.
- Kubernetes Secrets para clusters de Kubernetes.
Mejores prácticas de seguridad
- Separación de roles: tokens distintos para desarrollo, testing y producción.
- Servicios autónomos: cada microservicio gestiona solo sus secretos.
- No uses "default secrets". Es como dejar las llaves de casa bajo el felpudo.
Ejemplo de uso de HashiCorp Vault en Spring
Configurar Vault
- Instala y arranca Vault.
- Crea un secreto:
vault kv put secret/myapp db.password=supersecretpassword - Configura Spring Boot para trabajar con Vault:
spring: cloud: vault: uri: http://127.0.0.1:8200 authentication: TOKEN token: <tu token> - Lee el secreto en el código:
@Value("${db.password}") private String dbPassword; @GetMapping("/password") public String getPassword() { return dbPassword; }
Errores típicos y cómo evitarlos
Uno de los errores más comunes es commitear un secreto en el repositorio. Usa .gitignore o escáneres especializados para evitarlo.
Otro error es dar permisos "a todo el mundo". Siempre limita el acceso y usa políticas RBAC.
Y claro, no olvides actualizar los secretos regularmente. Un token que no se ha actualizado en años es un error grave.
En este punto deberías entender cómo gestionar correctamente los secretos y garantizar la seguridad en microservicios. Ahora estás listo para el siguiente paso — profundizar en los perfiles de configuración en Spring Boot!
GO TO FULL VERSION