Migrando secretos de equipo a SOPS + Age: del caos al control
Cómo dejamos de pasarnos .env por Slack y migramos a un flujo de secretos cifrados con SOPS y Age integrado al CI.
El problema
Cada vez que un dev nuevo entraba al equipo, el onboarding de secretos era un ritual:
- Pedir los
.envpor Slack DM - Copiarlos a mano en cada repo
- Rezar para que estuvieran actualizados
# Lo que nadie quiere ver en su historial de Slack
cat .env | pbcopy
# "te lo mando por acá rapidito"
La solución: SOPS + Age
SOPS cifra archivos de configuración manteniendo las keys en texto plano y los values cifrados. Age es el backend de cifrado — más simple que GPG, sin keyservers.
# secrets.enc.yaml — se puede commitear sin miedo
database_url: ENC[AES256_GCM,data:abc123...,type:str]
api_key: ENC[AES256_GCM,data:def456...,type:str]
Setup inicial
# Generar key de Age
age-keygen -o keys.txt
# Crear archivo de configuración de SOPS
cat > .sops.yaml << 'EOF'
creation_rules:
- path_regex: \.enc\.(yaml|json)$
age: >-
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
EOF
# Cifrar
sops -e secrets.yaml > secrets.enc.yaml
Integración con CI
En Bitbucket Pipelines, el Age key se inyecta como variable de entorno:
# bitbucket-pipelines.yml
- step:
name: Deploy
script:
- export SOPS_AGE_KEY=$AGE_SECRET_KEY
- sops -d secrets.enc.yaml > .env
- npm run deploy
Resultado
- Zero secretos en Slack desde la migración
- Los
.enc.yamlviven en el repo — el historial de cambios queda en git - Onboarding de nuevo dev: compartir un Age key, nada más