
cottage v0.6.7
Un moderno gestor de secretos cifrados con age basado en git para equipos.
cottage es una herramienta GitOps para que los equipos gestionen secretos cifrados con age en repositorios git.
Proporciona un flujo de trabajo sencillo para cifrar/descifrar secretos, gestionar destinatarios y mantener los secretos fuera del repositorio, a la vez que permite compartirlos fácilmente a través de VCS. cottage también genera vistas previas censuradas de los secretos cifrados para una mejor visibilidad y admite flujos de trabajo de descifrado tanto persistentes como temporales, garantizando que los secretos nunca se confirmen en texto plano.

- Características
- Instalación
- Integraciones con editores
- Integraciones con agentes de IA
- Inicio rápido
- GitOps
- Git Hooks
- Control de acceso
- Cualquier proveedor como upstream
- Sincronización con cualquier dispositivo
- Más información
- Solución de problemas
- Comparación
Características
- A prueba de exposiciones: Utiliza el sistema de tipos de Rust para asegurar que los errores nunca puedan exponer secretos accidentalmente.
- Amigable para equipos: Comparte claves públicas (destinatarios) en el repositorio, mantén las claves privadas (identidades) en local.
- Control de acceso: Reglas sencillas de permitir/denegar para controlar qué secretos se cifran para qué destinatarios.
- Gestiona .gitignore: Actualiza automáticamente
.gitignorepara mantener los secretos sin cifrar fuera del repositorio. - Vistas previas: Genera vistas previas censuradas con marca de tiempo de los secretos cifrados para una mejor visibilidad.
- Diffs enriquecidos: Mantiene el git diff limpio y revisable, mientras que
ctg diffmuestra el diff de los secretos modificados localmente con sus contrapartes cifradas rastreadas. - Verificación de checksum: Evita manipulaciones verificando que los secretos cifrados y las listas de destinatarios coincidan con los metadatos.
- Git hooks: Configura fácilmente git hooks para comprobar/cifrar secretos automáticamente antes del commit y descifrarlos después del checkout.
- Flujo de trabajo de secretos persistentes:
ctg decrypt/syncmantiene los secretos descifrados en disco. - Ciclo de vida de limpieza inteligente:
ctg run(atajoctgx) yctg editdescifran los secretos antes de la operación, manteniéndolos en disco si ya estaban presentes de antemano o limpiándolos automáticamente después si no lo estaban. - Limpieza al finalizar:
ctg encrypt --clean,ctg run --cleanyctg edit --cleangarantizan que los archivos descifrados se limpien del disco incluso si ya estaban presentes antes. - Flujo de trabajo de inyección de entorno:
ctg envinyecta los secretos descifrados como variables de entorno para ejecutar un comando, sin escribirlos en disco en absoluto. - Tubería segura de secretos:
ctg cat PATHdescifra en memoria e imprime a stdout para canalizar directamente a stdin de otras herramientas. - Limpieza:
ctg cleanelimina todos los secretos descifrados del repositorio local para que puedas ejecutar tus agentes de IA con un poco menos de preocupación. - Compatible con jj y directorios no-git:
ctg initconvierte cualquier directorio en un almacén de secretos. - Sincronización con cualquier proveedor: Te permite configurar cualquier proveedor con una API como upstream, y empezar a usar
ctg pull/diff/pushcomogit pull/diff/push. - Sincronización con cualquier dispositivo: Los secretos cifrados con cottage y gestionados en un repositorio git se pueden sincronizar entre dispositivos con Cottage Sync.
Instalación
# rust: cargo-binstall/cargo
cargo binstall --locked cottage
cargo install --locked cottage
# python: pip/uv/uvx
pip install cottage
uv pip install cottage
uvx --from cottage ctg --version
# node: yarn/pnpm/npx
yarn global add @sayanarijit/cottage
pnpm add -g @sayanarijit/cottage
npx -p @sayanarijit/cottage ctg --version
También disponible como imágenes docker:
# Docker
docker run --rm -v $PWD:/app sayanarijit/cottage --version
# Podman
podman run --rm -v $PWD:/app quay.io/sayanarijit/cottage --version
O descarga la última versión desde GitHub.
Integraciones con editores
Extensión de VS Code
Usa la extensión Cottage para VS Code para instalar ctg, añadir hooks de seguridad de Copilot, cifrar archivos desde el Explorador y abrir archivos .cott.age a través del flujo de trabajo del editor.
Instálala desde el Visual Studio Marketplace, o constrúyela e instálala localmente desde vscode-plugin-cottage.
Extensión de Cursor y Eclipse
Descarga el archivo VSX e instálalo en tu Cursor o Eclipse IDE. Funciona de forma similar a la extensión de VS Code.
Plugin de Vim
Usa el plugin cottage.vim para cifrar/descifrar secretos desde Vim o Neovim.
Integraciones con agentes de IA
Todas las integraciones a continuación evitan que los agentes de IA ejecuten ctg/ctgx directamente y que vean o editen archivos de secretos: cualquier cosa dentro de .cottage/, cualquier archivo *.cott.* (blobs cifrados *.cott.age y vistas previas censuradas *.cott.toml), y cualquier archivo descifrado que todavía tenga una contraparte *.cott.age en disco.
Integración con Claude Code
Si usas Claude Code, añade .claude/settings.json y .claude/hooks/deny-secrets.py a tus repositorios con secretos para que las sesiones de Claude Code gestionen los secretos de forma segura, o instala el plugin claude-plugin-cottage.
Integración con GitHub Copilot
Si usas GitHub Copilot en VS Code, añade .github/hooks/ctg-policy.json y .github/hooks/scripts/deny_ctg_command.py a tus repositorios con secretos para que las sesiones de Copilot limpien los archivos descifrados, bloqueen los comandos de shell ctg directos y bloqueen el acceso a los archivos de secretos, o instala la extensión vscode-plugin-cottage para configurarlo desde VS Code.
VS Code también carga las definiciones de hooks de .claude/settings.json. Si mantienes tanto los archivos de hooks de Claude como los de Copilot en el mismo repositorio, asegúrate de no ejecutar accidentalmente el mismo hook de limpieza dos veces.
Integración con Codex
Si usas Codex, añade .codex/hooks.json y .codex/hooks/deny-ctg.py a tus repositorios con secretos para que las sesiones de Codex gestionen los secretos de forma segura, o instala el plugin codex-plugin-cottage.
Codex requiere que los hooks locales se revisen antes de ejecutarse. Después de añadir los archivos, inicia Codex en el repositorio y usa /hooks para revisar y confiar en los hooks del proyecto.
Integración con Antigravity (agy)
Si usas Antigravity (agy), añade .agents/hooks.json y .agents/scripts/deny-ctg.py a tus repositorios con secretos para que las sesiones de Antigravity gestionen los secretos de forma segura, o instala el plugin agy-plugin-cottage.
Integración con Cursor
Si usas Cursor, añade .cursor/hooks.json, .cursor/hooks/deny-ctg.py, .cursor/hooks/deny-read-secrets.py, .cursor/rules/deny-ctg.mdc y .cursorignore a tus repositorios con secretos para que las sesiones de Cursor gestionen los secretos de forma segura.
Cursor requiere que los hooks se habiliten primero. Abre Cursor Settings > Hooks y habilita los hooks, luego reinicia la sesión del agente para que los hooks del proyecto surtan efecto. .cursorignore además mantiene los archivos de secretos fuera de la indexación de Cursor y del contexto del Agente.
Inicio rápido
Inicializar proyecto:
mkdir project && cd project
git init # Optional, cottage works better with git but it's not required
ctg init # Sets up the .cottage directory and necessary files
tree -a
# .
# ├ .cottage/ <- Auto-generated by `ctg init`
# │ ├ identity <- Your private key, keep it safe. Move it to `~/.config/cottage/identity` to use it globally, or replace it with a soft link to one of your existing private keys.
# │ └ recipients/ <- This is where your team keeps the public keys of all the recipients.
# │ └ sayanarijit <- Your public key. Commit it. To use an existing public key, just copy (don't softlink) that key here.
# ├ .git/...
# ├ .gitattributes <- Added `*.cott.age binary linguist-generated filter=cottage-encrypted -diff` to avoid polluting git diff
# └ .gitignore <- Added `/.cottage/identity` for obvious reasons
# You can run `ctg clean --all` anytime to clean up everything cottage ever did.
Crear o editar un secreto:
# `ctg edit` decrypts the file before opening in $EDITOR and re-encrypts upon save.
# If the decrypted file was not present on disk before running `ctg edit`, it is cleaned up afterwards.
# If it was already present, it is kept on disk.
ctg edit secret.yml
# Use `--clean` with `ctg edit` or `ctg encrypt` to ensure decrypted files are deleted even if present before
ctg edit secret.yml --clean # Opens in $EDITOR, encrypts on save, and cleans up
ctg encrypt secret.yml --clean # Encrypts secret.yml and cleans up
# encrypt secret.yml
# into secret.yml.cott.age
# edit secret.yml.cott.toml
# edit .gitignore
# delete secret.yml
Ejecutar un comando con secretos descifrados:
cat secret.yml
# cat: secret.yml: No such file or directory
# `ctg run` (or shortcut `ctgx`) decrypts secrets before running the command.
# If the decrypted files were not present on disk beforehand, they are automatically cleaned up after the command finishes.
# If they were already present beforehand, they are kept on disk.
ctg run -- kubectl apply -f secret.yml # decrypts secret.yml.cott.age to secret.yml and runs the command
ctg run -- kubectl apply -f secret.yml.cott.age # also replaces the path argument with the decrypted file path
ctg run -- kubectl apply -f . # decrypts all .cott.age files in . and runs the command
ctg run -- ./deploy.sh # decrypts all .cott.age files in repo and runs the command
cat secret.yml
# cat: secret.yml: No such file or directory
# Use `--clean` to ensure decrypted files are cleaned up even if they were present before
ctg run --clean ./deploy.sh
O usa el atajo:
ctgx -- ./deploy.sh
ctgx --clean -- ./deploy.sh
Leer y canalizar un secreto descifrado sin escribirlo en disco:
ctg cat secret.yml.cott.age
ctg cat secret.yml | kubectl apply -f -
ctg cat .env.prod | docker run --rm --env-file /dev/stdin my-image:latest
Ejecutar un comando con secretos inyectados como variables de entorno, sin escribirlos en disco en absoluto:
ctg env -- ./deploy.sh # Export secrets from .env.cott.age (default) without writing them to disk, then run deploy.sh
ctg env -F .env.prod.cott.age -- ./deploy.sh # exports from .env.prod.cott.age instead of .env.cott.age
ctg env -F secrets.json.cott.age -- printenv COTTAGE_SECRET # Also supports non-dotenv files.
GitOps
Para compartir tus secretos con los miembros del equipo, simplemente haz push al repositorio git.
git add .
git commit -m "Add secret.yml"
git push origin main
Pide a tus compañeros de equipo que añadan sus claves públicas a .cottage/recipients y hagan push de los
cambios. Luego puedes hacer pull y volver a cifrar los secretos para ellos.
git pull origin main
ctg decrypt --skip-verify-recipients # Decrypt missing secrets for re-encryption
ctg encrypt # Re-encrypt all secrets
# encrypt secret.yml
# into secret.yml.cott.age
# edit secret.yml.cott.toml
ctg clean # optional
# delete secret.yml
# review changes, commit and push
git add .
git commit -m "Add new recipient to secrets"
git push origin main
Ahora tus compañeros de equipo pueden hacer pull de los últimos cambios y descifrar los secretos por sí mismos.
Git Hooks
Puedes usar prek o pre-commit para configurar git hooks que comprueben/cifren secretos automáticamente antes del commit y los descifren después del checkout.
Consulta la configuración de ejemplo de prek aquí.
Después de añadir el archivo prek.toml, ejecuta:
prek install
prek install --hook-type post-checkout
prek install --hook-type post-merge
prek install --hook-type post-rewrite
Control de acceso
Reglas
En el archivo de metadatos, puedes anotar para qué destinatarios debe cifrarse el secreto. Esto te permite tener diferentes secretos para diferentes entornos (por ejemplo, staging vs producción) y cifrarlos solo para los destinatarios relevantes.
# secret.yml.cott.toml
[secret]
allow = ["sayanarijit"] # Only encrypt for sayanarijit
# secret.yml.cott.toml
[secret]
deny = ["sayanarijit"] # Encrypt for everyone except sayanarijit
# secret.yml.cott.toml
[secret]
allow = ["env/staging/*"] # Supports glob patterns, only encrypt for recipients in env/staging
deny = ["env/staging/badservice"] # Encrypt for everyone in env/staging except badservice
Las reglas de denegación tienen prioridad sobre las reglas de permiso.
Consulta la especificación de metadatos para más detalles.
Verificación
Puedes ejecutar ctg verify en CI para verificar que los secretos cifrados y las listas de destinatarios coincidan con las reglas de metadatos, para evitar manipulaciones.
# .github/workflows/cottage-verify.yml
name: Cottage Verify
on: [push, pull_request]
permissions:
contents: read
jobs:
verify-secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Verify secrets
run: docker run --rm -v "${{ github.workspace }}:/app" ghcr.io/sayanarijit/cottage verify
Cualquier proveedor como upstream
Con cottage, puedes sincronizar secretos con cualquier proveedor que tenga una API, no solo git.
Para ello, crea un archivo llamado cottage.toml en la raíz del proyecto y configura los ajustes del upstream.
Consulta el ejemplo de cottage.toml aquí y la configuración de upstream específica del secreto aquí.
Consulta un ejemplo de implementación de plugin aquí.
El flujo de trabajo es similar a git, pero en lugar de git pull y git push, ejecutas ctg pull y ctg push para sincronizar secretos con el upstream configurado.
Ejemplo:
# Pull latest changes into local encrypted secrets
# Similar to `git pull origin`
ctg pull myvault
# Compare diff with local decrypted secrets
ctg diff
# Sync local decrypted secrets with local encrypted secrets
ctg sync
# Push changes from local encrypted secrets to upstream
# Similar to `git push origin main`
ctg push myvault
Consulta la especificación de configuración de upstream para más detalles.
Plugins de ejemplo
Cottage admite varios proveedores de plugins para sincronizar tus secretos. Hay scripts de plugins listos para usar disponibles en el directorio examples/plugins:
- 1Password
- AWS Secrets Manager
- Azure Key Vault
- Bitwarden
- Dashlane
- Doppler
- ejson
- GitHub Secrets
- Google Cloud Secret Manager
- HashiCorp Vault (también consulta Vault en Kubernetes)
- Keeper Security
- KeePass (Passhole)
- LastPass
- pass (password-store)
- Proton Pass
- System Keyring
- Zoho Vault
Sincronización con cualquier dispositivo
Usa Cottage Sync para sincronizar tus secretos entre tus dispositivos y navegar sin necesidad de la CLI.
Más información
Consulta el directorio examples para más ejemplos de uso.
Solución de problemas
# See debug logs with -v, -vv or -vvv
ctg run -vvv -- ./deploy.sh
Comparación
age vs otros cifrados
age utiliza un algoritmo moderno y sencillo optimizado para el cifrado seguro de archivos, con un enfoque en la usabilidad y una superficie de ataque mínima. También admite claves SSH RSA y Ed25519, aunque se recomienda usar claves diferentes para propósitos y ámbitos separados.
cottage vs SOPS
Aunque SOPS y cottage tienen muchas características superpuestas, cottage tiene las siguientes ventajas:
- Gestiona automáticamente .gitignore para garantizar que los secretos sin cifrar nunca se confirmen en git.
- Al ser los secretos cifrados archivos .age puros cifrados con age, permite una mejor interoperabilidad con un ecosistema más amplio de herramientas.
- Diffs más limpios - a diferencia de SOPS, que genera diffs para cada valor de cada secreto, incluso si el cambio real es solo añadir/eliminar un destinatario, cottage solo genera un diff por archivo, señalando explícitamente el cambio en el checksum de destinatarios.
cottage vs dotenvx
cottage toma prestada la API ctg env de dotenvx.
- Admite cualquier tipo de archivo, no solo archivos dotenv.
- Gestiona múltiples secretos en un repositorio.
- Reglas de control de acceso para cifrar secretos para destinatarios específicos.
- Diffs más limpios - consulta cottage vs SOPS.
cottage vs agebox
agebox es muy similar a cottage en su filosofía central pero carece de muchas características.
