プロジェクトでAPIキーとかDB接続情報とか、センシティブな情報を.envファイルに書くこと、よくあるよね。でも、これをそのままGit管理するのは絶対ダメ。万が一漏れたら大変なことになる。
そこで出てくるのがsopsとageの組み合わせだよ。.envを暗号化してGit管理しつつ、デプロイ時に安全に復号する仕組みをClaude Codeに作らせてみよう。
一番雑な投げ方
まずは、とにかく目的を伝えるだけ。これだけでClaude Codeはかなり的を射たアドバイスをくれるはずだよ。
このプロジェクトの.envファイルをsopsとageで安全にGit管理したいんだけど、どうすればいい?
これだけで動く。ageキーの生成から、sopsの設定ファイル、実際の暗号化・復号コマンドまで一通り教えてくれるはず。
もうちょい具体的に投げるパターン
もう少し具体的に指示を出すと、特定のシナリオに合わせた解決策を提案してくれるよ。
新規プロジェクトで暗号化する
新しくプロジェクトを始めるなら、ageキーの生成から暗号化まで全部やってもらおう。
新しいプロジェクト始めたばかりで、まだageキーもsopsの設定ファイルもないんだ。
この.envファイルをsopsとageで暗号化して、.env.sopsとして保存できるように、必要なageキーの生成、.sops.yamlの設定、暗号化コマンドの一連の流れを教えて。
デプロイ時に復号できるように、その方法も教えてくれる?
# ここに.envの内容を貼る
LLM_BACKEND=anthropic
ANTHROPIC_API_KEY=sk-xxxxxx
DIFY_API_KEY=app-xxxxxx
デプロイ時に自動復号する
CI/CDパイプラインやデプロイサーバーで自動的に復号して使いたいなら、こんな感じで頼むのが早い。
うちの環境はDocker Composeで動いてるんだけど、既存のsecrets/app.sops(暗号化済みファイル)をビルド/起動時に復号して、アプリの環境変数として使いたいんだ。
ageキーは環境変数として渡す想定で、Docker ComposeファイルやDockerfileにどう書けばいいか、具体的な例を教えてくれる?
# 現在のdocker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "8000:8000"
environment:
- LLM_BACKEND
- ANTHROPIC_API_KEY
volumes:
- .:/app
Claude Codeに一時的に復号させる
もしどうしてもClaude Codeに一時的にファイルの中身を見せたいなら、ageキーを渡すけど、必ず「作業後には忘れる」よう指示しよう。ただし、この方法は最後の手段だと思ってね。
手元にageキーがあるんだけど、このsecrets/app.sops(暗号化済みファイル)の中身を確認したいんだ。
ageキーはこれだよ: AGE-SECRET-KEY-XXXXXXXXXXXXXXXXXXXXXXXXXX
このキーを使って復号して、中身を見せてほしい。作業が終わったら、このキーはもう忘れて、どこにも保存しないでね。
実践例 / 実録
うちのあるプロジェクトでは、LLM_BACKEND や ANTHROPIC_API_KEY とか、いろんなAPIキーを.envで管理してるんだけど、これをGiteaでGit管理したかったんだよね。
VPS上でDocker Composeを使ってデプロイするから、当然、デプロイ時にこの.envを自動で復号する必要があった。
そこでClaude Codeに雑に「sopsとageで管理したい」って投げたら、以下のような手順が出てきたよ。
-
ageキーの生成: まずはageの秘密鍵と公開鍵を生成するコマンドを教えてくれた。秘密鍵は手元で厳重に管理して、Gitには絶対入れない。
age-keygen -o key.txt # key.txt に秘密鍵が、出力に公開鍵が表示される # 公開鍵は .sops.yaml に使うよ -
.sops.yamlの作成: どのファイルをどのage公開鍵で暗号化するか設定する.sops.yamlのひな形も出してくれた。creation_rules: - path_regex: .*\.env(\.sops)?$ age: - age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # ここにageの公開鍵を書くこれで
.envや.env.sopsという名前のファイルを暗号化対象に設定できる。 -
.envの暗号化: 実際に.envを暗号化して.env.sopsとして保存するコマンド。sops --encrypt --in-place .env # .env を暗号化して .env.sops が生成されるこれで
.env.sopsはGit管理しても安全になった。元の.envはgit cleanなどで消しておくのがおすすめ。 -
デプロイ時(Docker Compose)の復号: 俺たちのデプロイ環境はVPS上のDocker Composeだったから、
docker-compose.ymlでage秘密鍵を環境変数として渡して、起動時に復号する仕組みを作った。# docker-compose.yml version: '3.8' services: app: build: . # ... entrypoint: /bin/bash -c "SOPS_AGE_KEY=$$AGE_KEY sops --decrypt secrets/app.sops > .env && uvicorn app.main:app --host 0.0.0.0 --port 8000" environment: # ... - AGE_KEY # ホストから環境変数として渡す # ...こんな感じで
entrypointで秘密鍵(AGE_KEY)をSOPS_AGE_KEYに設定してsops --decryptを実行。復号された.envをuvicornが読み込むようにしたよ。$$AGE_KEYと$が二重になってるのは、Docker Composeが環境変数を展開する都合だよ。これで、デプロイサーバーにage秘密鍵を置いておけば、安全に自動復号されるようになった。
つまずきポイント
sopsとageを使う上で、いくつかハマりやすいポイントがあったから気をつけてね。
-
ageキーの管理が肝: ageの秘密鍵は本当に大事だよ。紛失したら暗号化したファイルは二度と復号できないし、漏洩したら秘密が筒抜けになる。Gitには絶対入れずに、1Passwordとかのパスワードマネージャーで厳重に管理して。デプロイサーバーに置く場合も、アクセス権限を最小限にしよう。
-
.sops.yamlのパス設定:creation_rulesのpath_regexを間違えると、sopsがどのキーで暗号化・復号すればいいか分からなくなることがあるよ。特に.envのような拡張子のないファイルや、特定のディレクトリ配下のファイルを対象にする場合は、正規表現をしっかり確認してね。 -
CI/CD環境でのキー渡し方: CI/CDパイプラインで自動復号するなら、age秘密鍵をCI/CDサービスのSecrets機能(GitHub Actions Secretsとか)を使って環境変数として渡すのが定石だよ。 例えばGitHub Actionsなら、Workflowファイルで
AGE_KEY: ${{ secrets.AGE_SECRET_KEY }}のように設定して、sopsコマンド実行時にSOPS_AGE_KEY=$AGE_KEY sops --decrypt ...とすればOKだね。キー自体をファイルとして保存するのは避けた方が安全だよ。 -
Claude Codeへの秘密情報の取り扱い: Claude Codeにageキーのような秘密鍵を直接渡して作業させるのは、基本的には避けるべきだね。もし一時的に復号して内容を確認させたい場合でも、「作業が終わったらすぐに忘れる」よう明確に指示して、セッション限りで利用させよう。ベストプラクティスは、鍵は自分で管理し、Claude Codeには「復号するコマンドと手順」だけを教えてもらうことだよ。