765 - Adiós a PASS y GPG. Por qué me pasé a Age y SOPS
Descubre cómo gestionar tus secretos en Linux con Age y SOPS, una alternativa moderna y rápida a pass para cifrar archivos YAML, JSON y Docker.
Hace ya un par de años, que cambié la gestión de mis contraseñas locales a pass. El objetivo, es no tener las contraseñas directamente en scripts o en variables de entorno, si no tenerlas cifradas. Inicialmente utilizaba gopass, hasta que me di cuenta, que era un simple envoltorio de pass y que realmente no me aportaba nada. Y todo recayó en pass, y la verdad es que he estado muy satifsecho con él, salvo en ocasiones puntuales, donde ya había observado que era realmente lento. Además me encontraba que las contraseñas se encontraban en distintos archivos, lo cual no me terminaba de convencer. Así, que en estos últimos días le he dado una vuelta a todo esto y he migrado a una combinación de herramientas de las que te voy a hablar en este episodio.

Adiós a PASS y GPG. Por qué me pasé a Age y SOPS
Templates y variables de entorno
Para que comprendas el problema que estaba teniendo quiero ponerte en contexto. Estoy utilizando yadm para gestionar mis dotfiles. Así, tengo algunos archivos de configuración que contienen variables de entorno, como por ejemplo el archivo .env para mis proyectos en Docker. Estos archivos contienen credenciales, claves API, y otros secretos que no quiero que estén en texto plano en mi repositorio Git.
Para resolver este problema implementé una herramienta que llamé jinrender, que no es ni mas ni menos que un motor de plantillas basado en Jinja2, que me permite renderizar mis archivos de configuración a partir de plantillas y variables de entorno. Pero claro, el problema de fondo sigue ahí: ¿cómo gestiono esos secretos de forma segura?
Lo que hice fue un script en bash que cargaba todas las contraseñas de pass en variables de entorno, y luego ejecutaba jinrender para generar los archivos finales. Y justo aquí es donde viene el problema, esto no es ni mucho menos un proceso rápido.
Age
¿Qué es Age?. Age, definido como Actual Good Encryption, se presenta como el sucesor espiritual de PGP. Es una herramienta de cifrado moderna, con claves pequeñas y seguras, diseñada para ser simple.
El funcionamiento de age es muy similar al de herramientas clásicas como Openssl o GPG. Puedes cifrar archivos utilizando una clave pública y descifrarlos con la clave privada correspondiente. La gran ventaja de age es su simplicidad y eficiencia.
El flujo es realmente sencillo,
- Generas las llaves. Esto en general solo lo tienes que hacer una vez, y es tan sencillo como ejecutar
age-keygen -o key.txt. - Para cifrar un archivo tienes que utilizar la clave pública. Por ejemplo,
age -r <tu_clave_pública> -o archivo.cifrado archivo.txt. Si el archivo lo quieres copiar directamente en un correo en un archivo de texto tienes que utilizar la opción-ade archivo ASCII. - Para descifrar el archivo, utilizas tu clave privada con
age -d -i key.txt archivo.cifrado > archivo.txt.
También puedes cifrar archivos utilizando contraseñas en lugar de claves públicas/privadas, pero en mi caso prefiero utilizar el sistema de claves.
Y entre otras características puedes cifrar para varios destinatarios utilizando la opción -r múltiples veces, o incluso utilizar claves SSH para cifrar archivos, o las claves de GitHub.
SOPS
¿Que es SOPS? SOPS, o Secrets Operations, es una herramienta desarrollada por Mozilla para gestionar secretos en archivos de configuración. La idea principal detrás de SOPS es permitirte cifrar solo los valores sensibles dentro de un archivo de configuración, dejando la estructura del archivo intacta y legible.
Aquí es donde reside toda la magia. SOPS no cifra el archivo entero, ino solo los valores de un archivo YAML, JSON o ENV, dejando las claves visibles. Esto te permite ver la estructura en Git pero no los secretos.
Pero sobre todo, lo mas interesante para mi, es que tienes todas tus credenciales en un único archivo, y puedes editarlas de forma segura utilizando SOPS.
Instalación y configuración
En el caso concreto de ArchLinux, los puedes instalar ambos desde los repositorios oficiales, con lo que la instlación es tan sencilla como,
sudo pacman -S age sops
Una vez instalados, viene el momento de la configuración. Para ello hay que decirle a SOPS como tiene que realizar todas las operaciones de cifrado y descifrado utilizando Age. El primer paso es crear el archivo de configuración,
mkdir -p ~ /.config/sops/age
Una vez creado el directorio, generamos nuestra clave privada con,
age-keygen -o ~/.config/sops/age/key.txt
Aquí llega un momento clave y es, ¿que hacer con ese archivo key.txt? Mi recomendación es que lo guardes en tu sistema de contraseñas habitual, y que hagas copias de seguridad en lugares seguros. Además, es importante que añadas este archivo a tu .gitignore para evitar subirlo a ningún repositorio. Por ejemplo utilizando bitwarden.
A continuación, establecemos la variable de entorno SOPS_AGE_KEY_FILE para que SOPS sepa dónde encontrar nuestra clave privada de Age. Esto lo podemos hacer añadiendo la siguiente línea a nuestro archivo .bashrc o .zshrc,
export SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/key.txt"
o en fish
set -x SOPS_AGE_KEY_FILE $HOME/.config/sops/age/key.txt
Por último, podemos crear un archivo .sops.yaml en nuestro directorio de configuración de SOPS para definir reglas de cifrado automáticas. Por ejemplo, podemos crear el archivo ~/.config/sops/.sops.yaml con el siguiente contenido,
creation_rules:
# Regla para archivos de producción
- path_regex: production/.*\.yaml$
age: "age1v58p79m..." # Tu clave del servidor VPS
# Regla para archivos de desarrollo o locales
- path_regex: dev/.*\.yaml$
age: "age1lorenzo..." # Tu clave personal de Arch Linux
# Regla general por defecto (si no coincide lo anterior)
- path_regex: .*\.yaml$
age: "age1lorenzo...,age1v58p79m..." # Cifrar para ambos
Uso y funcionamiento
Pongamos que tienes un directorio en el que necesitas unos secretos. El primero es crear un archivo YAML con las reglas, un archivo .sops.yaml, como el que te muestro a continuación,
creation_rules:
- path_regex: .*\.yml|.*\.env|.*\.json$
age: "age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Ahora ya puedes crear cualquier archivo de configuración, por ejemplo secrets.yml. Para esto simplemente tienes que ejecutar sops secrets.yml, y SOPS se encargará de descifrar el archivo en memoria y abrirlo en tu editor de texto predeterminado (en mi caso Neovim). Una vez que termines de editar el archivo y lo cierres, SOPS lo volverá a cifrar automáticamente.
Y ¿como extraigo un valor concreto de ese archivo? Pues es tan sencillo como utilizar el comando sops -d --extract '["api_key"]' secrets.yml, que descifra el archivo y extrae solo el valor asociado a la clave api_key. Esto es especialmente útil para scripts de automatización en Rust o Bash, donde necesitas acceder a secretos específicos sin descifrar todo el archivo.
Una opción para Docker
Si no tienes activado Docker Swarm, o todavía no has pasado a Podman, y quieres utilizar SOPS en tus contenedores Docker, puedes hacerlo con el siguiente script en bash que te permite pasar las variables sin crear en disco,
#!/usr/bin/env bash
# Nombre del archivo de secretos
SECRETS_FILE="secrets.enc.env"
# Comprobamos si el archivo existe
if [[ ! -f "$SECRETS_FILE" ]]; then
echo "❌ Error: No se encuentra $SECRETS_FILE"
exit 1
fi
echo "🔓 Descifrando secretos y levantando contenedores..."
# Usamos la sustitución de procesos para pasar las variables a docker-compose
# sin crear un archivo físico en el disco.
docker-compose --env-file <(sops -d "$SECRETS_FILE") up -d
if [ $? -eq 0 ]; then
echo "🚀 Stack levantado correctamente."
else
echo "💥 Error al levantar el stack."
fi
Conclusión y siguiente epsiodio
La gran ventaja de este duo dinámico es que ahora tengo todos mis secretos centralizados en un único archivo cifrado, lo que facilita su gestión y mejora la seguridad. Además, el proceso de integración con mis scripts y configuraciones es mucho más fluido y rápido. En el próximo episodio, te contaré cómo he migrado de pass a SOPS y Age para la gestión de mis contraseñas y secretos en mis dotfiles, y verás lo rápido que es.