
チーム向けのモダンなgitベースのage暗号化シークレット管理ツール。
cottage は、チームが age暗号化されたシークレットをgitリポジトリで管理するためのGitOpsツールです。
シークレットの暗号化/復号化、受信者の管理、リポジトリ外へのシークレットの保持を可能にしながら、VCSを介した簡単な共有を実現するシンプルなワークフローを提供します。cottageはまた、暗号化されたシークレットの編集済みプレビューを生成して可視性を高め、永続的および一時的な復号化ワークフローの両方をサポートし、シークレットが平文でコミットされることを確実に防ぎます。

.gitignoreを自動的に更新します。ctg diffがローカルで変更されたシークレットと追跡された暗号化対応物の差分を表示する一方で、git diffをクリーンでレビュー可能に保ちます。ctg decrypt/syncは復号化されたシークレットをディスク上に保持します。ctg run(ショートカットctgx)とctg editは操作前にシークレットを復号化し、事前にディスク上に存在していた場合は保持し、そうでない場合は操作後に自動的にクリーンアップします。ctg encrypt --clean、ctg run --clean、およびctg edit --cleanは、事前に存在していた場合でも復号化されたファイルがディスクからクリーンアップされることを保証します。ctg envは復号化されたシークレットを環境変数として注入してコマンドを実行し、ディスクに一切書き込みません。# 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
Dockerイメージとしても利用可能です:
# Docker
docker run --rm -v $PWD:/app sayanarijit/cottage --version
# Podman
podman run --rm -v $PWD:/app quay.io/sayanarijit/cottage --version
または、GitHubから最新リリースをダウンロードしてください。
Cottage VS Code拡張機能を使用して、ctgをインストールし、Copilotセーフティフックを追加し、エクスプローラーからファイルを暗号化し、.cott.ageファイルをエディタワークフローで開くことができます。
Visual Studio Marketplaceからインストールするか、vscode-plugin-cottageからローカルにビルドしてインストールしてください。
VSXファイルをダウンロードして、CursorまたはEclipse IDEにインストールしてください。VS Code拡張機能と同様に動作します。
cottage.vimプラグインを使用して、VimまたはNeovimからシークレットを暗号化/復号化します。
以下のすべての統合は、AIエージェントがctg/ctgxを直接実行したり、シークレットファイル(.cottage/内のもの、*.cott.*ファイル(暗号化された*.cott.ageブロブと編集済みの*.cott.tomlプレビュー)、およびディスク上に*.cott.age対応物がまだ存在する復号化されたファイル)を表示または編集したりするのを防ぎます。
Claude Codeを使用している場合は、シークレットを含むリポジトリに.claude/settings.jsonと.claude/hooks/deny-secrets.pyを追加して、Claude Codeセッションがシークレットを安全に処理するようにするか、claude-plugin-cottageプラグインをインストールしてください。
VS CodeでGitHub Copilotを使用している場合は、シークレットを含むリポジトリに.github/hooks/ctg-policy.jsonと.github/hooks/scripts/deny_ctg_command.pyを追加して、Copilotセッションが復号化されたファイルをクリーンアップし、直接のctgシェルコマンドをブロックし、シークレットファイルへのアクセスをブロックするようにするか、vscode-plugin-cottage拡張機能をインストールしてVS Codeから設定してください。
VS Codeは.claude/settings.jsonフック定義も読み込みます。同じリポジトリにClaudeとCopilotの両方のフックファイルを保持する場合は、同じクリーンアップフックを誤って2回実行しないように注意してください。
Codexを使用している場合は、シークレットを含むリポジトリに.codex/hooks.jsonと.codex/hooks/deny-ctg.pyを追加して、Codexセッションがシークレットを安全に処理するようにするか、codex-plugin-cottageプラグインをインストールしてください。
Codexはローカルフックが実行前にレビューされることを要求します。ファイルを追加した後、リポジトリでCodexを起動し、/hooksを使用してプロジェクトフックをレビューして信頼してください。
Antigravity (agy)を使用している場合は、シークレットを含むリポジトリに.agents/hooks.jsonと.agents/scripts/deny-ctg.pyを追加して、Antigravityセッションがシークレットを安全に処理するようにするか、agy-plugin-cottageプラグインをインストールしてください。
Cursorを使用している場合は、シークレットを含むリポジトリに.cursor/hooks.json、.cursor/hooks/deny-ctg.py、.cursor/hooks/deny-read-secrets.py、.cursor/rules/deny-ctg.mdc、および.cursorignoreを追加して、Cursorセッションがシークレットを安全に処理するようにしてください。
Cursorはフックを最初に有効にする必要があります。Cursor設定 > フックを開いてフックを有効にし、エージェントセッションを再起動してプロジェクトフックが有効になるようにしてください。.cursorignoreはさらに、シークレットファイルをCursorのインデックスとエージェントのコンテキストから除外します。
プロジェクトを初期化:
mkdir project && cd project
git init # オプション、cottageはgitと組み合わせるとより良く動作しますが必須ではありません
ctg init # .cottageディレクトリと必要なファイルを設定します
tree -a
# .
# ├ .cottage/ <- `ctg init`によって自動生成されます
# │ ├ identity <- あなたの秘密鍵です。安全に保管してください。グローバルに使用するには`~/.config/cottage/identity`に移動するか、既存の秘密鍵へのソフトリンクに置き換えてください。
# │ └ recipients/ <- チームがすべての受信者の公開鍵を保持する場所です。
# │ └ sayanarijit <- あなたの公開鍵です。コミットしてください。既存の公開鍵を使用するには、その鍵をここにコピー(ソフトリンクではなく)してください。
# ├ .git/...
# ├ .gitattributes <- git diffを汚染しないように`*.cott.age binary linguist-generated filter=cottage-encrypted -diff`を追加しました
# └ .gitignore <- 明らかな理由で`/.cottage/identity`を追加しました
# いつでも`ctg clean --all`を実行して、cottageが行ったすべてをクリーンアップできます。
シークレットを作成または編集:
# `ctg edit`は$EDITORで開く前にファイルを復号化し、保存時に再暗号化します。
# 復号化されたファイルが`ctg edit`実行前にディスク上に存在しなかった場合、実行後にクリーンアップされます。
# すでに存在していた場合は、ディスク上に保持されます。
ctg edit secret.yml
# `ctg edit`または`ctg encrypt`で`--clean`を使用すると、事前に存在していた場合でも復号化されたファイルが削除されることを保証します
ctg edit secret.yml --clean # $EDITORで開き、保存時に暗号化し、クリーンアップします
ctg encrypt secret.yml --clean # secret.ymlを暗号化してクリーンアップします
# secret.ymlを暗号化
# secret.yml.cott.ageに
# secret.yml.cott.tomlを編集
# .gitignoreを編集
# secret.ymlを削除
復号化されたシークレットでコマンドを実行:
cat secret.yml
# cat: secret.yml: No such file or directory
# `ctg run`(またはショートカット`ctgx`)はコマンド実行前にシークレットを復号化します。
# 復号化されたファイルが事前にディスク上に存在しなかった場合、コマンド終了後に自動的にクリーンアップされます。
# 事前に存在していた場合は、ディスク上に保持されます。
ctg run -- kubectl apply -f secret.yml # secret.yml.cott.ageをsecret.ymlに復号化してコマンドを実行します
ctg run -- kubectl apply -f secret.yml.cott.age # パス引数を復号化されたファイルパスに置き換えます
ctg run -- kubectl apply -f . # .内のすべての.cott.ageファイルを復号化してコマンドを実行します
ctg run -- ./deploy.sh # リポジトリ内のすべての.cott.ageファイルを復号化してコマンドを実行します
cat secret.yml
# cat: secret.yml: No such file or directory
# `--clean`を使用すると、事前に存在していた場合でも復号化されたファイルがクリーンアップされることを保証します
ctg run --clean ./deploy.sh
またはショートカットを使用:
ctgx -- ./deploy.sh
ctgx --clean -- ./deploy.sh
シークレットを環境変数として注入してコマンドを実行し、ディスクに一切書き込まない:
ctg env -- ./deploy.sh # .env.cott.age(デフォルト)からシークレットをディスクに書き込まずにエクスポートし、deploy.shを実行します
ctg env -F .env.prod.cott.age -- ./deploy.sh # .env.cott.ageの代わりに.env.prod.cott.ageからエクスポートします
ctg env -F secrets.json.cott.age -- printenv COTTAGE_SECRET # dotenv以外のファイルもサポートします。
シークレットをチームメンバーと共有するには、gitリポジトリにプッシュするだけです。
git add .
git commit -m "Add secret.yml"
git push origin main
チームメイトに.cottage/recipientsに公開鍵を追加して変更をプッシュするよう依頼してください。その後、プルして彼らのためにシークレットを再暗号化できます。
git pull origin main
ctg decrypt --skip-verify-recipients # 再暗号化のために不足しているシークレットを復号化
ctg encrypt # すべてのシークレットを再暗号化
# secret.ymlを暗号化
# secret.yml.cott.ageに
# secret.yml.cott.tomlを編集
ctg clean # オプション
# secret.ymlを削除
# 変更をレビューしてコミットしプッシュ
git add .
git commit -m "Add new recipient to secrets"
git push origin main
これでチームメイトは最新の変更をプルして自分でシークレットを復号化できます。
prekまたはpre-commitを使用して、コミット前にシークレットを自動的にチェック/暗号化し、チェックアウト後に復号化するGitフックを設定できます。
prek設定の例はこちらを参照してください。
prek.tomlファイルを追加した後、以下を実行します:
prek install
prek install --hook-type post-checkout
prek install --hook-type post-merge
prek install --hook-type post-rewrite
メタデータファイルで、シークレットをどの受信者に対して暗号化するかを注釈できます。これにより、異なる環境(例: ステージングと本番)に対して異なるシークレットを持ち、関連する受信者に対してのみ暗号化できます。
# secret.yml.cott.toml
[secret]
allow = ["sayanarijit"] # sayanarijitに対してのみ暗号化
# secret.yml.cott.toml
[secret]
deny = ["sayanarijit"] # sayanarijit以外の全員に対して暗号化
# secret.yml.cott.toml
[secret]
allow = ["env/staging/*"] # グロブパターンをサポート、env/staging内の受信者に対してのみ暗号化
deny = ["env/staging/badservice"] # badservice以外のenv/staging内の全員に対して暗号化
拒否ルールは許可ルールよりも優先されます。
詳細はメタデータ仕様を参照してください。
CIでctg verifyを実行して、暗号化されたシークレットと受信者リストがメタデータルールと一致することを検証し、改ざんを防ぐことができます。
# .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
cottageを使用すると、gitだけでなく、APIを持つ任意のプロバイダとシークレットを同期できます。
そのためには、プロジェクトルートにcottage.tomlという名前のファイルを作成し、アップストリーム設定を構成します。
cottage.tomlの例はこちら、シークレット固有のアップストリーム設定はこちらを参照してください。
プラグイン実装の例はこちらを参照してください。
ワークフローはgitと似ていますが、git pullとgit pushの代わりに、ctg pullとctg pushを実行して設定されたアップストリームとシークレットを同期します。
例:
# 最新の変更をローカルの暗号化されたシークレットにプル
# `git pull origin`と同様
ctg pull myvault
# ローカルの復号化されたシークレットとの差分を比較
ctg diff
# ローカルの復号化されたシークレットをローカルの暗号化されたシークレットと同期
ctg sync
# ローカルの暗号化されたシークレットからアップストリームへ変更をプッシュ
# `git push origin main`と同様
ctg push myvault
詳細はアップストリーム設定仕様を参照してください。
Cottageはシークレットを同期するためのさまざまなプラグインプロバイダをサポートしています。すぐに使用できるプラグインスクリプトはexamples/pluginsディレクトリにあります:
Cottage Syncを使用して、デバイス間でシークレットを同期し、CLIを必要とせずに閲覧できます。
その他の使用例については、examplesディレクトリを参照してください。
# -v、-vv、または-vvvでデバッグログを表示
ctg run -vvv -- ./deploy.sh
ageは、安全なファイル暗号化に最適化された現代的でシンプルなアルゴリズムを使用し、使いやすさと最小限の攻撃面に焦点を当てています。また、SSH RSAおよびEd25519鍵をサポートしていますが、異なる目的とスコープには異なる鍵を使用することをお勧めします。
SOPSとcottageには多くの重複する機能がありますが、cottageには以下の利点があります:
cottageはctg env APIをdotenvxから借用しています。
ctg cleanはローカルリポジトリからすべての復号化されたシークレットを削除し、AIエージェントを少しだけ安心して実行できるようにします。ctg initは任意のディレクトリをシークレットストアに変換します。git pull/diff/pushのようにctg pull/diff/pushを使用できます。