<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Tomofumi Chiba - Leaves</title>
    <link>https://leaves.chiba.dev/users/chiba</link>
    <description>Tomofumi Chiba - Leaves</description>
    <image><url>https://leaves.chiba.dev/favicon.ico</url></image>
    
    <item>
      <title>SOPS | Tomofumi Chiba - Leaves</title>
      <link>https://leaves.chiba.dev/posts/456</link>
      <pubDate>Thu, 12 Nov 2026 03:51:07 GMT</pubDate>
      <guid>456</guid>
      <description>### SOPS

SOPS は CNCF のプロジェクトとして管理されているツールです。Kubernetes と同じ CNCF の傘下にあります。

#### Install for Ubuntu
```
$ 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

$ sudo apt update
$ sudo apt install age
```
```
$ ssh-keygen -t ed25519 -f ~/.ssh/sops_ed25519 -N &quot;&quot;
```
- 秘密鍵の管理
- ローカル開発環境用の secret も外部サーバにアクセスしている場合は、暗号化して git 管理しておく
---
以下、Claude さんまとめ
# SOPS + ssh-keygen 運用まとめ

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

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

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

## 4. 日常の使い方
```bash
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` の例:
```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 のどちらで使うかが決まっていれば、その構成に合わせた設定例も出せます。</description>
    </item>
    <item>
      <title>Spring Boot 4 にしたら 400 Bad Request が出るようになった | Tomofumi Chiba - Leaves</title>
      <link>https://leaves.chiba.dev/posts/455</link>
      <pubDate>Mon, 02 Nov 2026 09:20:11 GMT</pubDate>
      <guid>455</guid>
      <description>#### Spring Boot 4 にしたら 400 Bad Request が出るようになった

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

ログが表示されないので何が起きているか気づけない。
`ResponseEntityExceptionHandler` を継承したクラスを作り `handleHttpMessageNotReadable` メソッドを Override すればロギングを追加できる。
```java
@Override
protected ResponseEntity&lt;Object&gt; handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers,
                                                              HttpStatusCode status, WebRequest request) {
    log.warn(&quot;うおおおおお&quot;, ex);
    return super.handleHttpMessageNotReadable(ex, headers, status, request);
}
```</description>
    </item>
    <item>
      <title>chatbot | Tomofumi Chiba - Leaves</title>
      <link>https://leaves.chiba.dev/posts/454</link>
      <pubDate>Sat, 17 Oct 2026 02:32:18 GMT</pubDate>
      <guid>454</guid>
      <description>chatbot

- chatbot backend
  - AI Gateway, LLM
  - Tool
    - APIs
    - DB
    - ベクトルDB(RAG, ナレッジ)</description>
    </item>
    <item>
      <title>Leaves CLI alias | Tomofumi Chiba - Leaves</title>
      <link>https://leaves.chiba.dev/posts/449</link>
      <pubDate>Sun, 11 Oct 2026 13:23:20 GMT</pubDate>
      <guid>449</guid>
      <description>Leaves CLI alias

```
alias s=&apos;docker run -it --rm oven/bun bunx @chibat/leaves&apos;
```
</description>
    </item>
    <item>
      <title>あえて WSL1 をインストールする | Tomofumi Chiba - Leaves</title>
      <link>https://leaves.chiba.dev/posts/445</link>
      <pubDate>Fri, 02 Oct 2026 10:21:06 GMT</pubDate>
      <guid>445</guid>
      <description>#### あえて WSL1 をインストールする

```
wsl --install Ubuntu --name wsl1
wsl --set-version wsl1 1
```
</description>
    </item>
  </channel>
</rss>