
Um moderno gerenciador de segredos criptografados com age, baseado em git, para equipes.
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://s13.gifyu.com/images/b7mxd.webp">
<source media="(prefers-color-scheme: light)" srcset="https://s13.gifyu.com/images/b7mxl.webp">
<img alt="The cottage logo" width="600" src="https://assets.kitploit.com/production/public/readmes/7490/2c8e4c6f8fa352cb9dcf2d8f22c3d84926c09a69fca9a6632d008c61b5417c28.webp">
</picture>
</p>
[](https://github.com/sayanarijit/cottage/actions/workflows/cottage-verify.yml)
[](https://crates.io/crates/cottage)
[](https://pypi.org/project/cottage/)
[](https://www.npmjs.com/package/@sayanarijit/cottage)
[](https://hub.docker.com/r/sayanarijit/cottage)
**cott*age*** é uma ferramenta GitOps para equipes gerenciarem segredos [criptografados com age](https://age-encryption.org/) em repositórios git.
Ela fornece um fluxo de trabalho simples para criptografar/descriptografar segredos, gerenciar destinatários e manter
os segredos fora do repositório, permitindo ainda o compartilhamento fácil via VCS. O cottage também
gera prévias censuradas de segredos criptografados para melhor visibilidade e suporta fluxos de trabalho de descriptografia
persistentes e temporários, garantindo que os segredos nunca sejam commitados
em texto simples.

1. [Recursos](#features)
2. [Instalação](#installation)
3. [Integrações com Editores](#editor-integrations)
1. [Extensão para VS Code](#vs-code-extension)
2. [Extensão para Cursor e Eclipse](#cursor-and-eclipse-extension)
3. [Plugin para Vim](#vim-plugin)
4. [Integrações com Agentes de IA](#ai-agent-integrations)
1. [Integração com Claude Code](#claude-code-integration)
2. [Integração com GitHub Copilot](#github-copilot-integration)
3. [Integração com Codex](#codex-integration)
4. [Integração com Antigravity (agy)](https://github.com/sayanarijit/cottage/blob/main/%3C#antigravity-(agy)-integration>)
5. [Integração com Cursor](#cursor-integration)
5. [Início Rápido](#quick-start)
6. [GitOps](#gitops)
7. [Git Hooks](#git-hooks)
8. [Controle de Acesso](#access-control)
1. [Regras](#rules)
2. [Verificação](#verification)
9. [Qualquer Provedor como Upstream](#any-provider-as-upstream)
1. [Plugins de exemplo](#example-plugins)
10. [Sincronize com qualquer dispositivo](#sync-with-any-device)
11. [Saiba Mais](#learn-more)
12. [Solução de Problemas](#troubleshooting)
13. [Comparação](#comparison)
1. [age vs Outras Criptografias](#age-vs-other-encryption)
2. [cottage vs SOPS](#cottage-vs-sops)
3. [cottage vs dotenvx](#cottage-vs-dotenvx)
4. [cottage vs agebox](#cottage-vs-agebox)
## Recursos
- **Seguro contra exposição**: Usa o sistema de tipos do Rust para garantir que bugs nunca exponham segredos acidentalmente.
- **Amigável para equipes**: Compartilhe chaves públicas (destinatários) no repositório, mantenha chaves privadas (identidades) localmente.
- **Controle de Acesso**: Regras simples de permitir/negar para controlar quais segredos são criptografados para quais destinatários.
- **Gerencia .gitignore**: Atualiza automaticamente o `.gitignore` para manter segredos não criptografados fora do repositório.
- **Prévias**: Gera prévias censuradas com timestamp de segredos criptografados para melhor visibilidade.
- **Diffs ricos**: Mantém o git diff limpo e revisável, enquanto `ctg diff` mostra o diff de segredos modificados localmente com suas contrapartes criptografadas rastreadas.
- **Verificação de checksum**: Impede adulteração verificando que os segredos criptografados e as listas de destinatários correspondem aos metadados.
- **Git hooks**: Configure facilmente git hooks para verificar/criptografar segredos automaticamente antes do commit e descriptografá-los após o checkout.
- **Fluxo de trabalho de segredos persistentes**: `ctg decrypt/sync` mantém segredos descriptografados no disco.
- **Ciclo de vida de limpeza inteligente**: `ctg run` (atalho `ctgx`) e `ctg edit` descriptografam segredos antes da operação, mantendo-os no disco se já estavam presentes antes ou limpando-os automaticamente depois, caso não estivessem.
- **Limpeza ao concluir**: `ctg encrypt --clean`, `ctg run --clean` e `ctg edit --clean` garantem que arquivos descriptografados sejam removidos do disco mesmo se já estavam presentes antes.
- **Fluxo de trabalho de injeção de ambiente**: `ctg env` injeta segredos descriptografados como variáveis de ambiente para executar um comando, sem gravá-los no disco.
- **Piping seguro de segredos**: `ctg cat PATH` descriptografa em memória e imprime na stdout para piping direto via stdin para outras ferramentas.
- **Limpeza**: `ctg clean` exclui todos os segredos descriptografados do repositório local para que você possa executar seus agentes de IA com um pouco menos de preocupação.
- **Suporta jj e diretórios não-git**: `ctg init` transforma qualquer diretório em um armazenamento de segredos.
- **Sincronize com qualquer provedor**: Permite configurar qualquer provedor com uma API como upstream e começar a usar `ctg pull/diff/push` como `git pull/diff/push`.
- **Sincronize com qualquer dispositivo**: Segredos criptografados com cottage e gerenciados em um repositório git podem ser sincronizados entre dispositivos com o [Cottage Sync](https://cottage-sync.github.io).
## Instalação
```bash
# 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
```
Também disponível como imagens docker:
```bash
# Docker
docker run --rm -v $PWD:/app sayanarijit/cottage --version
# Podman
podman run --rm -v $PWD:/app quay.io/sayanarijit/cottage --version
```
Ou baixe a versão mais recente do [GitHub](https://github.com/sayanarijit/cottage/releases).
## Integrações com Editores
### Extensão para VS Code
Use a [extensão Cottage para VS Code](https://github.com/sayanarijit/vscode-plugin-cottage) para instalar o `ctg`, adicionar hooks de segurança do Copilot, criptografar arquivos pelo Explorer e abrir arquivos `.cott.age` através do fluxo de trabalho do editor.
[](https://marketplace.visualstudio.com/items?itemName=sayanarijit.vscode-plugin-cottage)
Instale-a pelo [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=sayanarijit.vscode-plugin-cottage), ou compile e instale localmente a partir de [`vscode-plugin-cottage`](https://github.com/sayanarijit/vscode-plugin-cottage).
### Extensão para Cursor e Eclipse
Baixe o [arquivo VSX](https://open-vsx.org/extension/sayanarijit/vscode-plugin-cottage) e instale-o no seu Cursor ou Eclipse IDE. Funciona de forma semelhante à extensão do VS Code.
### Plugin para Vim
Use o plugin [cottage.vim](https://github.com/sayanarijit/cottage.vim) para criptografar/descriptografar segredos no Vim ou Neovim.
[](https://asciinema.org/a/1264076)
## Integrações com Agentes de IA
Todas as integrações abaixo impedem que agentes de IA executem `ctg`/`ctgx` diretamente e visualizem ou editem arquivos de segredos: qualquer coisa dentro de `.cottage/`, qualquer arquivo `*.cott.*` (blobs criptografados `*.cott.age` e prévias censuradas `*.cott.toml`) e qualquer arquivo descriptografado que ainda tenha uma contraparte `*.cott.age` no disco.
### Integração com Claude Code
Se você usa o Claude Code, adicione [`.claude/settings.json`](https://github.com/sayanarijit/cottage/blob/main/.claude/settings.json) e [`.claude/hooks/deny-secrets.py`](https://github.com/sayanarijit/cottage/blob/main/.claude/hooks/deny-secrets.py) aos seus repositórios com segredos para que as sessões do Claude Code lidem com segredos com segurança, ou instale o plugin [claude-plugin-cottage](https://github.com/sayanarijit/claude-plugin-cottage).
### Integração com GitHub Copilot
Se você usa o GitHub Copilot no VS Code, adicione [`.github/hooks/ctg-policy.json`](https://github.com/sayanarijit/cottage/blob/main/.github/hooks/ctg-policy.json) e [`.github/hooks/scripts/deny_ctg_command.py`](https://github.com/sayanarijit/cottage/blob/main/.github/hooks/scripts/deny_ctg_command.py) aos seus repositórios com segredos para que as sessões do Copilot limpem arquivos descriptografados, bloqueiem comandos shell diretos do `ctg` e bloqueiem o acesso a arquivos de segredos, ou instale a extensão [vscode-plugin-cottage](https://github.com/sayanarijit/vscode-plugin-cottage) para configurar isso pelo VS Code.
O VS Code também carrega as definições de hooks de [`.claude/settings.json`](https://github.com/sayanarijit/cottage/blob/main/.claude/settings.json). Se você mantiver os arquivos de hooks do Claude e do Copilot no mesmo repositório, certifique-se de não executar acidentalmente o mesmo hook de limpeza duas vezes.
### Integração com Codex
Se você usa o Codex, adicione [`.codex/hooks.json`](https://github.com/sayanarijit/cottage/blob/main/.codex/hooks.json) e [`.codex/hooks/deny-ctg.py`](https://github.com/sayanarijit/cottage/blob/main/.codex/hooks/deny-ctg.py) aos seus repositórios com segredos para que as sessões do Codex lidem com segredos com segurança, ou instale o plugin [codex-plugin-cottage](https://github.com/sayanarijit/codex-plugin-cottage).
O Codex exige que hooks locais sejam revisados antes de serem executados. Após adicionar os arquivos, inicie o Codex no repositório e use `/hooks` para revisar e confiar nos hooks do projeto.
### Integração com Antigravity (agy)
Se você usa o Antigravity (`agy`), adicione [`.agents/hooks.json`](https://github.com/sayanarijit/cottage/blob/main/.agents/hooks.json) e [`.agents/scripts/deny-ctg.py`](https://github.com/sayanarijit/cottage/blob/main/.agents/scripts/deny-ctg.py) aos seus repositórios com segredos para que as sessões do Antigravity lidem com segredos com segurança, ou instale o plugin [agy-plugin-cottage](https://github.com/sayanarijit/agy-plugin-cottage).
### Integração com Cursor
Se você usa o Cursor, adicione [`.cursor/hooks.json`](https://github.com/sayanarijit/cottage/blob/main/.cursor/hooks.json), [`.cursor/hooks/deny-ctg.py`](https://github.com/sayanarijit/cottage/blob/main/.cursor/hooks/deny-ctg.py), [`.cursor/hooks/deny-read-secrets.py`](https://github.com/sayanarijit/cottage/blob/main/.cursor/hooks/deny-read-secrets.py), [`.cursor/rules/deny-ctg.mdc`](https://github.com/sayanarijit/cottage/blob/main/.cursor/rules/deny-ctg.mdc) e [`.cursorignore`](https://github.com/sayanarijit/cottage/blob/main/.cursorignore) aos seus repositórios com segredos para que as sessões do Cursor lidem com segredos com segurança.
O Cursor exige que os hooks sejam habilitados primeiro. Abra Cursor Settings > Hooks e habilite os hooks, depois reinicie a sessão do agente para que os hooks do projeto entrem em vigor. O `.cursorignore` também mantém arquivos de segredos fora da indexação do Cursor e do contexto do Agente.
## Início Rápido
Inicialize o projeto:
```bash
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`
# │ └ 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 that key here.
# ├ .git/...
# └ .gitattributes <- Added `*.cott.age binary linguist-generated filter=cottage-encrypted -diff` to avoid polluting git diff
# Your private key is stored safely in `~/.config/cottage/identity/<dirname>/<timestamp>.key`.
# You can run `ctg clean --all` anytime to clean up everything cottage ever did.
```
Crie ou edite um segredo:
```bash
# `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
```
Execute um comando com segredos descriptografados:
```bash
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
```
Ou use o atalho:
```bash
ctgx -- ./deploy.sh
ctgx --clean -- ./deploy.sh
```
Leia e faça pipe de um segredo descriptografado sem gravá-lo no disco:
```bash
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
```
Execute um comando com segredos injetados como variáveis de ambiente, sem gravar no disco:
```bash
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 compartilhar seus segredos com membros da equipe, basta fazer push para o repositório git.
```bash
git add .
git commit -m "Add secret.yml"
git push origin main
```
Peça aos seus colegas de equipe para adicionar suas chaves públicas em `.cottage/recipients` e fazer push das
alterações. Depois você pode fazer pull e recriptografar os segredos para eles.
```bash
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
```
Agora seus colegas de equipe podem fazer pull das últimas alterações e descriptografar os segredos por conta própria.
## Git Hooks
Você pode usar [prek](https://github.com/j178/prek) ou [pre-commit](https://pre-commit.com/) para configurar git hooks que verificam/criptografam segredos automaticamente antes do commit e os descriptografam após o checkout.
Veja o [exemplo de configuração do prek aqui](https://github.com/sayanarijit/cottage/blob/main/examples/prek.toml).
Após adicionar o arquivo `prek.toml`, execute:
```bash
prek install
prek install --hook-type post-checkout
prek install --hook-type post-merge
prek install --hook-type post-rewrite
```
## Controle de Acesso
### Regras
No arquivo de metadados, você pode anotar para quais destinatários o segredo deve ser criptografado.
Isso permite ter segredos diferentes para ambientes diferentes (por exemplo, staging vs produção) e criptografá-los apenas para os destinatários relevantes.
```toml
# secret.yml.cott.toml
[secret]
allow = ["sayanarijit"] # Only encrypt for sayanarijit
```
```toml
# secret.yml.cott.toml
[secret]
deny = ["sayanarijit"] # Encrypt for everyone except sayanarijit
```
```toml
# 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
```
Regras de negação têm precedência sobre regras de permissão.
Veja a [especificação de metadados](https://github.com/sayanarijit/cottage/blob/main/SPECIFICATION.md#secretmetadata) para mais detalhes.
### Verificação
Você pode executar `ctg verify` em CI para verificar que os segredos criptografados e as listas de destinatários correspondem às regras de metadados, para prevenir adulteração.
```yaml
# .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
```
## Qualquer Provedor como Upstream
Com o cottage, você pode sincronizar segredos com qualquer provedor que tenha uma API, não apenas git.
Para isso, crie um arquivo chamado `cottage.toml` na raiz do projeto e configure as definições de upstream.
Veja o [exemplo de `cottage.toml` aqui](https://github.com/sayanarijit/cottage/blob/main/cottage.toml) e a [configuração de upstream específica de segredo aqui](https://github.com/sayanarijit/cottage/blob/main/examples/secrets/secret.json.cott.toml).
Veja um [exemplo de implementação de plugin aqui](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-vault-in-kubernetes.py).
O fluxo de trabalho é semelhante ao git, mas em vez de `git pull` e `git push`, você executa `ctg pull` e `ctg push` para sincronizar segredos com o upstream configurado.
Exemplo:
```bash
# 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
```
Veja a [especificação de configuração de upstream](https://github.com/sayanarijit/cottage/blob/main/SPECIFICATION.md#upstreamconfig) para mais detalhes.
### Plugins de exemplo
O Cottage suporta vários provedores de plugins para sincronizar seus segredos. Scripts de plugins prontos para uso estão disponíveis no diretório [examples/plugins](https://github.com/sayanarijit/cottage/blob/main/examples/plugins):
- [1Password](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-onepassword.py)
- [AWS Secrets Manager](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-aws-secretsmanager.py)
- [Azure Key Vault](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-azure-keyvault.py)
- [Bitwarden](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-bitwarden.py)
- [Dashlane](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-dashlane.py)
- [Doppler](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-doppler.py)
- [ejson](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-ejson.py)
- [GitHub Secrets](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-github-secrets.py)
- [Google Cloud Secret Manager](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-gcp-secretmanager.py)
- [HashiCorp Vault](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-vault.py) (veja também [Vault in Kubernetes](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-vault-in-kubernetes.py))
- [Keeper Security](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-keeper.py)
- [KeePass (Passhole)](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-passhole.py)
- [LastPass](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-lastpass.py)
- [pass (password-store)](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-pass.py)
- [Proton Pass](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-protonpass.py)
- [System Keyring](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-keyring.py)
- [Zoho Vault](https://github.com/sayanarijit/cottage/blob/main/examples/plugins/cottage-plugin-zoho-vault.py)
## Sincronize com qualquer dispositivo
Use o [Cottage Sync](https://cottage-sync.github.io) para sincronizar seus segredos entre seus dispositivos e navegar sem precisar da CLI.
## Saiba Mais
Veja o diretório [examples](https://github.com/sayanarijit/cottage/blob/main/examples) para mais exemplos de uso.
## Solução de Problemas
```bash
# See debug logs with -v, -vv or -vvv
ctg run -vvv -- ./deploy.sh
```
## Comparação
### age vs Outras Criptografias
[age](https://age-encryption.org) usa um algoritmo moderno e simples, otimizado para criptografia segura de arquivos, com foco em usabilidade e superfície de ataque mínima. Ele também [suporta chaves SSH RSA e Ed25519](https://words.filippo.io/using-ed25519-keys-for-encryption/), embora seja recomendado usar chaves diferentes para propósitos e escopos separados.
### cottage vs SOPS
Embora [SOPS](https://getsops.io/) e cottage tenham muitos recursos sobrepostos, o cottage tem as seguintes vantagens:
- Gerencia automaticamente o .gitignore para garantir que segredos não criptografados nunca sejam commitados no git.
- Segredos criptografados sendo arquivos .age puros criptografados com age, permite melhor interoperabilidade com um ecossistema mais amplo de ferramentas.
- Diffs mais limpos - ao contrário do SOPS, que gera diffs para cada valor de cada segredo, mesmo que a alteração real seja apenas adicionar/remover um destinatário, o cottage gera apenas um diff por arquivo, apontando explicitamente a mudança no checksum dos destinatários.
### cottage vs dotenvx
O cottage empresta a API `ctg env` do [dotenvx](https://dotenvx.com).
- Suporta qualquer tipo de arquivo, não apenas arquivos dotenv.
- Gerencia múltiplos segredos em um repositório.
- Regras de controle de acesso para criptografar segredos para destinatários específicos.
- Diffs mais limpos - veja [cottage vs SOPS](#cottage-vs-sops).
### cottage vs agebox
[agebox](https://github.com/slok/agebox) é muito semelhante ao cottage em filosofia central, mas carece de muitos [recursos](#features).