Leaves

Leaves

This website is a Microblog that allows you to post in Markdown.
Sign in with your Google account and use it.

sops

$ curl -o ~/.local/bin/sops -LO https://github.com/getsops/sops/releases/download/v3.13.3/sops-v3.13.3.linux.amd64
$ chmod +x ~/.local/bin/sops
$ ssh-keygen -t ed25519 -f ~/.ssh/sops_ed25519 -N ""

以下、Claude さんまとめ

SOPS + ssh-keygen 運用まとめ

1. 全体像

  • SOPS は YAML / JSON / ENV などの値だけを暗号化するツールで、キーは平文のまま残るため Git の diff が読めます。
  • 暗号化した Secret を Git で管理し、必要なときに復号して Kubernetes に適用します。LastPass は機械的な取得に向かないので、この用途では使いません。
  • 鍵は age 形式ですが、age-keygen の代わりに ssh-keygen で作った SSH 鍵も使えます。

2. 鍵の作成(ssh-keygen)

ssh-keygen -t ed25519 -f ~/.ssh/sops_ed25519 -N ""
  • 使えるのは ssh-ed25519 と ssh-rsa のみです(ECDSA、DSA は不可)。
  • 普段使いの鍵は流用せず、SOPS 専用の鍵を作ります。漏えい時やローテーション時の影響範囲を分けるためです。
  • パスフレーズ付きの鍵は SOPS から使いにくいため、実際に試して確認してください(-N "" はパスフレーズなしの指定です)。
  • SSH 鍵に対応しているのは比較的新しい SOPS なので、sops --version で確認してください。

3. .sops.yaml(Git で管理する)

creation_rules:
  - path_regex: .*secret.*\.yaml$
    encrypted_regex: '^(data|stringData)$'
    age: ssh-ed25519 AAAAC3Nza...(sops_ed25519.pub の中身)
  • 書くのは公開鍵とルールだけなので、Git に置いて問題ありません。チームや CI で設定が揃い、鍵の変更履歴も追えます。
  • encrypted_regex で data / stringData だけを暗号化すると、metadata などは平文のまま残ります。

4. 日常の使い方

export SOPS_AGE_SSH_PRIVATE_KEY_FILE=~/.ssh/sops_ed25519

sops -e -i secret.yaml     # 暗号化(上書き)
sops secret.yaml           # 復号 → 編集 → 再暗号化
sops -d secret.yaml        # 復号して標準出力へ
sops -d secret.yaml | kubectl apply -f -   # 手動で適用
  • 平文ファイルを作らず、sops secret.yaml で直接編集するのが安全です。

5. Git に置くもの・置かないもの

置く 置かない
.sops.yaml(公開鍵) SSH 秘密鍵(sops_ed25519)
暗号化済みの Secret マニフェスト 平文の Secret マニフェスト
age の秘密鍵(key.txt、*.agekey)

.gitignore の例:

key.txt
*.agekey
*.dec.yaml

6. 秘密鍵の管理

  • 開発マシン: ~/.ssh/ 配下に chmod 600 で置きます。
  • バックアップ: 1Password や Bitwarden のセキュアノートなど、マシンが壊れても取り出せる場所に保管します。紛失すると復号できません。
  • 複数の宛先: 普段使いの鍵とバックアップ用の鍵の両方を .sops.yaml に書いておけば、どちらか一方で復号できます。
  • CI: CI 専用の鍵を作り、CI のシークレットに登録します。開発者の鍵とは分けます。
  • Flux(クラスタ側で復号): 基本は age 形式の鍵(age.agekey)を前提にしています。SSH 鍵に対応しているかはバージョンごとのドキュメントで確認が必要で、確実に動かしたいなら age-keygen の方が無難です。

7. メンバー追加・鍵の入れ替え

  1. .sops.yaml の公開鍵を更新する
  2. sops updatekeys secret.yaml で既存ファイルを再暗号化する

.sops.yaml を変えただけでは、既存の暗号化ファイルの宛先は変わりません。

8. 鍵が漏れたとき

  1. 新しい鍵を作り、.sops.yaml の公開鍵を差し替える
  2. sops updatekeys で再暗号化する
  3. 中身の Secret(パスワードや API キー)自体も再発行する

Git の履歴には古い暗号文が残るため、漏れた鍵があれば過去のコミットから復号できます。鍵を替えるだけでは不十分です。

9. 向き・不向き

  • 向いている: 個人・小規模、GitOps、追加のサーバーやオペレーターを使いたくない場合
  • 不向き: 動的なシークレットの発行や自動ローテーションが必要な場合は、Vault や External Secrets Operator + クラウドの Secret Manager の方が向きます。
  • 鍵ファイルの管理を避けたい場合: AWS KMS や GCP KMS を使うと秘密鍵ファイルが不要になり、IAM で権限と監査を管理できます。

10. 選び方の目安

  • 手元と CI だけで使う、すでに SSH 鍵がある → ssh-keygen で十分
  • Flux などクラスタ側で自動復号したい → age-keygen の方が素直

Flux と Argo CD のどちらで使うかが決まっていれば、その構成に合わせた設定例も出せます。

Spring Boot 4 にしたら 400 Bad Request が出るようになった

複数コンストラクタを持つ request dto で パラメータを持つコンストラクタを呼び出し、エラーになっていた。
@JsonCreator でデシリアライズするコンストラクタを明示する。
Lombok の @NoArgsConstructor を使っていた場合は、 @NoArgsConstructor(onConstructor_ = @JsonCreator) と明示する。

ログが表示されないので何が起きているか気づけない。
ResponseEntityExceptionHandler を継承したクラスを作り handleHttpMessageNotReadable メソッドを Override すればロギングを追加できる。

@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers,
                                                              HttpStatusCode status, WebRequest request) {
    log.warn("うおおおおお", ex);
    return super.handleHttpMessageNotReadable(ex, headers, status, request);
}

chatbot

  • chatbot backend
    • AI Gateway, LLM
    • Tool
      • APIs
      • DB
      • ベクトルDB(RAG, ナレッジ)

Leaves CLI alias

alias s='docker run -it --rm oven/bun bunx @chibat/leaves'

あえて WSL1 をインストールする

wsl --install Ubuntu --name wsl1
wsl --set-version wsl1 1
CommentEdit1 Like