767 - Gestión de secretos extrema. SOPS + AGE + RUST (Más rápido que nunca)
Descubre cómo migrar de Pass a Sops y Age para gestionar contraseñas en Linux. Optimiza tu terminal con crypta (Rust) y automatiza secretos con Jinja.
En el episodio 765, te hablé de sops y age, y las ventajas que tenía frente a opciones como pass, para gestionar tus contraseñas y secretos de forma segura. Pero me quedé a medias, porque si bien te presenté a estas dos excelentes herramientas, me quedó mostrarte el proceso de migración y como he terminado integrando estas dos herramientas para susitituir a pass. Así, en este episodio te voy a contar con todo lujo de detalles como he hecho esta migración y como he integrado sops y age en mis flujos de trabajo diarios.

Gestión de secretos extrema. SOPS + AGE + RUST (Más rápido que nunca)
Un poquito de contexto
Si no escuchaste el episodio 765, te recomiendo que lo hagas antes de continuar con este. En ese episodio te hablé de sops y age, dos herramientas que he empezado a usar para gestionar mis secretos y contraseñas de forma segura. En ese episodio te conté las ventajas que tienen estas herramientas frente a otras opciones como pass, pero me quedé a medias, porque no te mostré como he integrado estas herramientas en mis flujos de trabajo diarios.
sops es una herramienta implementada por Mozilla que permite cifrar y descifrar archivos de configuración de forma sencilla. age es una herramienta de cifrado simple y segura que se integra perfectamente con sops. Juntas, estas herramientas me permiten gestionar mis secretos de forma segura y eficiente.
Versionado de secretos
pass utiliza git para gestionar el versionado de los secretos, lo cual es una ventaja significativa. Sin embargo, sops no tiene esa integración nativa con git. Afortunadamente, podemos utilizar git junto con sops para lograr un versionado efectivo de nuestros secretos.
Para esto, simplemente cree el directorio ~/.secrets y dentro de él inicialicé un repositorio git:
mkdir -p ~/.secrets
cd ~/.secrets
git init
git config diff.sops.textconv "sops -d"
echo "*.yml diff=sops" > .gitattributes
cat < EOF >> .sops.yaml
creation_rules:
- path_regex: .*\.yml$
age: "agexxxxxxxxxxxx"
EOF
Con esto y respecto a git, haces lo siguiente,
textconv. Le dice a Git que, cuando necesite comparar archivos (hacer un git diff), use el comando sops -d para descifrarlos temporalmente en memoria..gitattributes. Indica que todos los archivos .yml deben usar ese filtro «sops».- Resultado: Cuando ejecutes git diff, verás los cambios en el texto real de la contraseña en lugar de ver un bloque de datos cifrados ilegibles.
Y respecto a la política de cifrado,
path_regex. Indica que cualquier archivo que termine en .yml será procesado por SOPS.age. Define la clave pública (tu agexxxxxxxxxxxx) que se usará para cifrar los archivos. A partir de ahora, cuando hagas sops archivo.yml, SOPS sabrá exactamente qué clave usar sin que tengas que pasársela como parámetro cada vez.
El flujo de trabajo
Para trabajar con sops y age, el flujo de trabajo es bastante sencillo. Aquí te dejo los pasos básicos que sigo,
- Crear un secreto:
sops secrets.ymlabrirá tu $EDITOR, escribes en YAML, y al guardar se cifra automáticamente. - Para ver el contenido descifrado:
sops -d secrets.yml. - Para hace un commit:
git add . && git commit -m "Añadido nuevo secreto". Aquí la gran ventaja es que aunque el archivo en disco está cifrado gracias al paso anterior, tu historial de Git, te será tremendamente útil.
UN CRUD de secretos
Por gandulería, decidí hacer un CRUD de secretos para lo que he hecho cuatro scripts en fish muy facilones que me permiten gestionar mis secretos de forma sencilla. Estos scripts los puedes encontrar en el repositorio de dotfiles en GitHub.
secret-add: Añade un nuevo secreto.secret-show: Muestra un secreto descifrado.secret-rm: Elimina un secreto.secret-get: Copia un secreto al portapapeles.secret-ls: Lista todos los secretos disponibles.
Y un par de ayudas para gestionar el repositorio de secretos,
secret-push: Hace un push de los cambios al repositorio remoto.secret-pull: Hace un pull de los cambios del repositorio remoto.secret-sync: Hace un pull y un push para sincronizar los cambios.
Si le das un vistazo a estos scripts, verás que son bastante sencillos y utilizan comandos básicos de sops y git para gestionar los secretos.
Templates, secretos y doftiles
Para ponerle la guinda al pastel, he integrado sops con dotfiles para gestionar mis secretos de configuración. Para esto, utilizo plantillas en mis archivos de configuración que son procesadas por dotfiles para reemplazar los valores secretos con los valores descifrados por sops.
Por un lado tengo un script que he llamado unjinja que es el que se encarga de procesar las plantillas y reemplazar los valores secretos. Este script utiliza sops -d para descifrar los secretos y luego utiliza jinja2 para procesar las plantillas.
function unjinja --description="Fill scripts"
set -l STORE $HOME/.secrets/secrets.yml
if not test -f $store
echo "Error: No se encontró el almacén de contraseñas en $store" >&2
return 1
end
sops -d $STORE | yq -r 'to_entries | .[] | select(.key != "sops") | ((.key | ascii_upcase) + " " + (.value | tostring))' | while read -l key value
echo "✅ Loading $key"
set -gx $key $value
end
echo "🚀 Secretos cargados"
yadm list -a | while read -l item
if [ $(path extension $item) = ".jinja" ]
set jinja $(path normalize ~/"$item")
set output $(path change-extension '' "$jinja")
jinrender --jinja "$jinja" --output "$output"
end
end
echo "📝 Templates configurados"
# unset variables
set -e (sops -d $STORE | yq -r 'keys | .[] | select(. != "sops") | ascii_upcase')
echo "🧹 Secreto descargados"
end
Como ves la operación es bastante sencilla. Primero, descifra el archivo de secretos y carga las variables de entorno con los valores secretos. Luego, procesa cada archivo de plantilla en el repositorio de dotfiles y genera los archivos de configuración finales con los valores secretos reemplazados.
Esta herramienta la tengo anclada a yadm mediante un hook que hace que cada vez que hago un yadm pull, se ejecuta unjinja para actualizar los archivos de configuración con los valores secretos más recientes.
De esta forma, cuando modifico un template de mis dotfiles, puedo simplemente hacer un yadm commit y yadm push, y los cambios se aplicarán automáticamente en mis sistemas cuando haga un yadm pull. O si lo quiero aplicar inmediatamente, ejecutando unjinja manualmente.
crypta
Es una herramienta de línea de comandos (CLI) que permite almacenar contraseñas, claves API o archivos de configuración de forma encriptada. Sus pilares principales son:
- Seguridad robusta: Utiliza SOPS y Age con encriptación AES-256-GCM.
- Sincronización Git: Permite subir tus secretos encriptados a un repositorio Git de forma automática, facilitando el respaldo y el uso en diferentes máquinas.
- Versatilidad: Puede copiar secretos al portapapeles o escupirlos directamente a la consola (
stdout) para usarlos en scripts.
Instalación
Tienes dos formas principales de instalarlo en tu sistema:
- Desde el binario que hay en el repositorio, simplemente descarga y da permisos
- Desde el código fuente
- Clona el repositorio:
git clone https://github.com/yourusername/crypta.git. - Entra a la carpeta:
cd crypta. - Compila:
cargo build --release. - Mueve el binario a tu ruta de sistema:
sudo cp target/release/crypta /usr/local/bin/.
Importante: Crypta requiere una clave de Age para funcionar. Debes generarla y configurar la variable de entorno
SOPS_AGE_KEY_FILEen tu archivo de configuración de shell (.bashrc,.zshrc, etc.).
Cómo se utiliza
Crypta utiliza comandos intuitivos y alias cortos para mayor rapidez.
Almacenar secretos
- Desde la terminal (stdin): Ideal para textos largos o archivos.
echo "mi-secreto" | crypta store MI_CLAVE.
- Como argumento directo:
crypta set MI_CLAVE "mi-secreto".
Recuperar secretos
- Al portapapeles: (Uso manual)
crypta get MI_CLAVE.
- A la consola (stdout): (Para scripts o variables)
crypta lookup MI_CLAVE.
Gestión y Sincronización
- Listar claves: Para ver qué tienes guardado, usa
crypta list. - Eliminar: Para borrar un secreto, usa
crypta delete MI_CLAVE. - Sincronizar: Para subir/bajar cambios de tu repositorio Git configurado:
crypta sync "Mensaje de commit".
Comandos Rápidos (Resumen)
| Acción | Comando | Alias |
| Guardar (stdin) | store | s |
| Guardar (argumento) | set | se |
| Copiar (portapapeles) | get | g |
| Mostrar (stdout) | lookup | l |
| Listar | list | ls |
| Sincronizar Git | sync | sy |