Files
claude-code/CLAUDE.md
T
claude 528a48b667
Helm Chart Release / release-chart (push) Successful in 9s
Build Session Image / build-push (push) Successful in 2m8s
feat: credentials 認証モードとトークン自動リフレッシュ CronJob を追加 (v2.1.263-b)
トークンが定期的に失効・ローテーションしても再デプロイ不要にする。

- anthropic.authMode: credentials(新既定)
  ~/.claude/.credentials.json 全体(refreshToken 込み)を Secret に格納。
  セッション Pod にはファイルとしてマウントし $HOME/.claude へコピー(書き込み可)、
  セッション内 claude が refreshToken で自己更新
- anthropic.refresher CronJob(credentials 時・既定有効, files/token-refresher.py)
  Secret 内 refreshToken で OAuth トークンを更新し Secret を書き戻す。
  専用 SA + resourceNames 限定 Role で該当 Secret の get/patch のみ。
  tokenUrl/clientId は Claude Code CLI の非公式値(values 上書き可)
- manager.py build_pod: credentials は envFrom を使わずファイルマウント +
  SEED_CREDENTIALS_FILE。apiKey/oauth は従来どおり envFrom
- Secret に helm.sh/resource-policy: keep(credentials 時)で refresher の書込を保持
- fix: values.schema.json の $schema 行を削除(一部の Helm で
  "no schema with key or ref https://json-schema.org/draft-07/schema#" エラー)
- helm lint / template(credentials/apiKey/oauth)検証済み
2026-09-08 15:18:21 +09:00

118 lines
8.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md — claude-code Helm Chart
> **共通ルール(要約)** — 詳細は `P:\Claude\CLAUDE.md`(全体共通)と `P:\Claude\HelmChart\CLAUDE.md`(Helm チャート共通: リリースフロー・ワークフロー・Gitea Secrets)を参照。
> 作業前に pull / 機能変更時は README 更新 / 作業単位ごとに commit → push まで / コミットに AI クレジットを付けない / pull で入った変更を revert しない / Helm はローカル実行不可(Python のみ可)。
## リポジトリ概要
Alpine Linux ベースの軽量コンテナで **Claude Code をリモート実行** するための Helm チャート。
ブラウザ(PC / スマートフォン)からアクセスし、**セッションごとに独立した使い捨て Pod** で
Git リポジトリ(GitHub / Gitea など互換 Git 全般)をチェックアウト・編集・検証・プッシュする。
一定時間アイドルなセッション Pod は自動破棄される。Raspberry Pi などの ARM ベアメタル運用を想定。
- **Gitea リポジトリ**: `ssh://git@192.168.9.65/helmchart/claude-code`
- **Helm リポジトリ**: `https://git.cafepieters.com/api/packages/helmchart/helm`
- **セッションイメージ**: `git.cafepieters.com/helmchart/claude-code/session:<appVersion>`(CI で publish)
> **注意**: セッション Pod は Gitea からリポジトリ単体を clone するため、`P:\Claude` の上位階層 CLAUDE.md は届かない。各リポジトリの CLAUDE.md 先頭に「共通ルール(要約)」を置く理由はこれ。
## アーキテクチャ(要点)
| コンポーネント | 実体 | 役割 |
|---|---|---|
| `gateway` | `nginxinc/nginx-unprivileged:alpine` | 単一入口。認証(token/basic/forward)、WebSocket リバースプロキシ、アクティビティ計測 |
| `manager` | `python:3.x-alpine`(標準ライブラリのみ) | セッション CRUD API、Web UI、アイドル/寿命回収ループ。in-cluster SA で K8s API を直接操作 |
| `session` | Alpine + node + git + ttyd + claude-code | セッションごとに作られる使い捨て Pod。`git clone` → `claude`(ttyd) → `claude-verify`/`claude-push` |
| `reaper` CronJob | `manager` イメージ `--reap-once` | manager 障害時の保険となる孤児掃除 |
- 制御プレーンはリリース NS、セッション Pod は専用 NS(`sessionsNamespace.name`)に分離。
- manager の RBAC はセッション NS の `pods` / `services` に限定した Role のみ(ClusterRole 不使用)。
- セッション Pod は **API サーバー到達不可**(`automountServiceAccountToken: false`)、
非 root / `readOnlyRootFilesystem` / drop ALL caps / seccomp RuntimeDefault、
egress は DNS + git ホスト + `api.anthropic.com` のみ(NetworkPolicy)。
- ファイル実体は `files/`(`.Files.Get` で ConfigMap 化): `manager.py` / `session-entrypoint.sh`
/ `gateway.conf.template` / `gateway-entrypoint.sh` / `Dockerfile.session`。
## README 更新時の追加事項
- values の新設キー、挙動変更、セキュリティ影響は README の該当セクションと values リファレンス表へ反映する。
- 手動リリース(`-a` 等)時は対応する `CHANGELOG-<version>.md` を追加し、README の「バージョン履歴」にも 1 行追加する(このリポジトリの慣行)。
## リリースフロー(組織ルールとの差分)
- **バージョン番号**: `Chart.yaml` の `version` / `appVersion` は
**主アプリ = Claude Code CLI(`@anthropic-ai/claude-code` の npm 最新版)と同一**にする。
- **ワークフロー(3 本)**
- `helm-release.yaml` — `main` への push で発火。`helm lint` の後、`Chart.yaml` の version が
未リリース(Gitea リリース・Package Registry 双方に存在しない)なら タグ + Gitea リリース +
チャート publish。リリース済みなら lint のみで終了(再 publish しない)。
- `image-update-and-release.yaml` — 毎週月曜 3:00 JST。npm の Claude Code 最新版と
base image(nginx / python)の最新 Alpine タグを確認。Claude Code 更新時は
`values.yaml` / `Chart.yaml` / README 履歴を更新しコミット → タグ + リリース + publish。
base image のみ更新時は `values.yaml` を更新してコミットのみ(**リリースなし**)。
- `session-image.yaml` — `files/Dockerfile.session` 等の変更、または上記による `Chart.yaml`
更新で発火。セッションイメージを `linux/amd64,linux/arm64` でビルドして
Gitea Container Registry(`helmchart/claude-code/session:<appVersion>` + `latest`)へ push。
- **手動リリース(臨時)**: 例 `2.1.259` → `2.1.259-a` → `2.1.259-b`。
## 改修履歴
### 認証情報の credentials モード + トークン自動リフレッシュ(2026-09-08, v2.1.263-b)
**背景**: サブスクリプションのアクセストークンは定期的に失効・ローテーションする。単発
トークン注入では失効のたびに `helm upgrade` が必要だった。
**症状**: あわせて、一部の Helm バージョンで `values.schema.json` の
`$schema: https://json-schema.org/draft-07/schema#` が
`no schema with key or ref ...` エラーになる不具合。
**修正内容**:
- `anthropic.authMode: credentials`(新既定): `~/.claude/.credentials.json` 全体を Secret に
格納 →(a)セッション Pod にファイルとしてマウントし `$HOME/.claude` へコピー、セッション内
`claude` が `refreshToken` で自己更新。(b)`anthropic.refresher` CronJob
(`files/token-refresher.py`、専用 SA + `resourceNames` 限定 Role で該当 Secret の get/patch のみ)
がクラスタ内で `accessToken` を定期更新し Secret を書き戻す。`tokenUrl` / `clientId` は
Claude Code CLI の非公式値で values 上書き可。
- `manager.py` の `build_pod`: credentials モードは `envFrom` を使わずファイルマウント +
`SEED_CREDENTIALS_FILE` env。apiKey/oauth は従来どおり `envFrom`。
- Secret に `helm.sh/resource-policy: keep`(credentials 時)。
- `values.schema.json` の `$schema` 行を削除(他チャートと同じ。Helm は draft-07 で検証)。
**対象ファイル**: `values.yaml`, `values.schema.json`, `templates/secret-anthropic.yaml`,
`templates/deployment.yaml`, `templates/configmap-manager.yaml`, `templates/token-refresher.yaml`(新規),
`templates/NOTES.txt`, `files/manager.py`, `files/session-entrypoint.sh`,
`files/token-refresher.py`(新規), `examples/loadbalancer-oauth.values.yaml`, `README.md`,
`Chart.yaml`, `CHANGELOG-2.1.263-b.md`
### Service の LoadBalancer 対応 + サブスクリプション認証手順の明文化(2026-09-08, v2.1.263-a)
**背景**: Ingress を張らずに、ローカルネットワークの LB(kube-vip 等)から払い出した IP で
管理画面へアクセスしたい、という運用要望。あわせて「Claude の API 課金を使わず、ローカルの
Claude Code と同様にサブスクリプションで使いたい」という確認があった。
**修正内容**:
- `templates/service.yaml` を書き換え、`service.type: LoadBalancer` を既定化。
`service.annotations`(kube-vip の `kube-vip.io/loadbalancerIPs` / `vipHost` 等)、
`loadBalancerIP` / `loadBalancerClass` / `loadBalancerSourceRanges` /
`externalTrafficPolicy` / `nodePort` / `labels` を追加。Ingress 機能は変更なし(併用可)。
- `values.yaml` の `service:` ブロック拡張、`values.schema.json` に対応プロパティ追加。
- `templates/NOTES.txt` に LoadBalancer の EXTERNAL-IP 案内を追加。
- `examples/loadbalancer-oauth.values.yaml` を追加(Ingress 無効 + LB + source range +
`authMode: oauth`)。
- README に「Claude 認証(API 課金なし / サブスクリプション)」「管理画面へのアクセス
(LoadBalancer / Ingress)」セクションを追加。サブスクリプション認証は
`claude setup-token` → `anthropic.authMode: oauth`(`CLAUDE_CODE_OAUTH_TOKEN` を
セッション Pod に注入)で、ローカル実行の Claude Code と同一挙動。
**対象ファイル**: `templates/service.yaml`, `values.yaml`, `values.schema.json`,
`templates/NOTES.txt`, `examples/loadbalancer-oauth.values.yaml`, `README.md`, `Chart.yaml`,
`CHANGELOG-2.1.263-a.md`
### 初版(2026-09-03, v2.1.259)
チャート新規作成。gateway + manager + 使い捨て session Pod + reaper CronJob の構成で、
ブラウザからの Claude Code リモート実行、GitHub/Gitea 両対応、アイドル自動破棄、
NetworkPolicy / RBAC 最小化 / restricted PodSecurity を実装。
**対象ファイル**: 全ファイル(初期コミット)