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)検証済み
This commit is contained in:
@@ -119,41 +119,63 @@ manager / gateway / session-entrypoint の実体は `files/` にあり、`.Files
|
||||
**サブスクリプション認証(Pro / Max プラン)** で動かせます。セッション内の `claude` の
|
||||
挙動・機能はローカル実行と同一です(同じ CLI・同じログイン方式)。
|
||||
|
||||
1. 手元の PC(Claude にログイン済み)で長期トークンを発行:
|
||||
`anthropic.authMode` は 3 つ:
|
||||
|
||||
```bash
|
||||
claude setup-token
|
||||
```
|
||||
| モード | 注入するもの | トークン更新 | 課金 |
|
||||
|---|---|---|---|
|
||||
| **`credentials`(既定・推奨)** | `~/.claude/.credentials.json` 全体(`refreshToken` 込み) | セッション内 `claude` が自己更新 **+** クラスタ内 refresher CronJob が Secret を自動更新 | サブスクリプション枠(API 課金なし) |
|
||||
| `oauth` | `CLAUDE_CODE_OAUTH_TOKEN`(`claude setup-token` の単発トークン) | 自動更新なし(`refreshToken` を含まない)。失効したら手動再投入 | サブスクリプション枠 |
|
||||
| `apiKey` | `ANTHROPIC_API_KEY`(`sk-ant-...`) | — | API 従量課金 |
|
||||
|
||||
ブラウザで承認すると `CLAUDE_CODE_OAUTH_TOKEN` として使える長期トークンが表示されます。
|
||||
### `credentials` モードの使い方(推奨)
|
||||
|
||||
2. それをチャートに渡す(`authMode: oauth`):
|
||||
1. **claude にログイン済みの手元 PC** の認証情報ファイルをそのまま渡します
|
||||
(このファイルには `accessToken` と、それを更新するための `refreshToken` が入っています):
|
||||
|
||||
```bash
|
||||
# 場所: Linux/macOS = ~/.claude/.credentials.json
|
||||
# Windows = %USERPROFILE%\.claude\.credentials.json
|
||||
# (macOS でキーチェーン保存の場合は Keychain の "Claude Code" 項目を書き出す)
|
||||
helm upgrade --install claude-code cafepieters/claude-code -n claude-code --create-namespace \
|
||||
-f examples/loadbalancer-oauth.values.yaml \
|
||||
--set anthropic.oauthToken="<発行されたトークン>"
|
||||
--set-file anthropic.credentialsJson="$HOME/.claude/.credentials.json"
|
||||
```
|
||||
|
||||
Secret にしておく場合:
|
||||
2. これだけで **トークンが定期的に変わっても再デプロイは不要** です。仕組み:
|
||||
|
||||
- セッション Pod は生成のたびに Secret を読むため、常に最新の認証情報で起動します。
|
||||
- **セッション内の `claude`** は、`accessToken` が失効していれば `refreshToken` で
|
||||
自動更新します(そのセッションの間だけ有効。`$HOME/.claude/.credentials.json` に書き戻す)。
|
||||
- **refresher CronJob**(`anthropic.refresher`、既定 30 分ごと)が、Secret 内の
|
||||
`refreshToken` を使ってクラスタ内で `accessToken` を更新し、**Secret 自体を書き戻します**。
|
||||
これにより手元 PC がオフラインでも、新規セッションは常に有効なトークンで起動できます。
|
||||
|
||||
3. 既存 Secret を使う場合:
|
||||
|
||||
```bash
|
||||
kubectl -n claude-code-sessions create secret generic claude-oauth \
|
||||
--from-literal=CLAUDE_CODE_OAUTH_TOKEN="<トークン>"
|
||||
# values: anthropic.existingSecret=claude-oauth
|
||||
kubectl -n claude-code-sessions create secret generic claude-creds \
|
||||
--from-file=.credentials.json="$HOME/.claude/.credentials.json"
|
||||
# values: anthropic.existingSecret=claude-creds
|
||||
# (refresher に patch させるため RBAC はこの Secret 名に限定して付与される)
|
||||
```
|
||||
|
||||
| 方式 | values | 認証情報 | 課金 |
|
||||
|---|---|---|---|
|
||||
| **サブスクリプション(推奨)** | `anthropic.authMode: oauth` | `anthropic.oauthToken`(`claude setup-token`) | Claude プランの利用枠を消費(API 課金なし) |
|
||||
| API キー | `anthropic.authMode: apiKey` | `anthropic.apiKey`(`sk-ant-...`) | API 従量課金 |
|
||||
### 注意 / 制約
|
||||
|
||||
- トークンは **セッション NS の Secret** に保存され、セッション Pod へ環境変数
|
||||
`CLAUDE_CODE_OAUTH_TOKEN` として注入されます(`values.yaml` に平文で書かない)。
|
||||
- 利用枠はローカルの Claude Code と共有です。複数セッションを同時に走らせると
|
||||
プランのレート上限に早く達する点に注意してください。
|
||||
- トークンには有効期限があります。失効したら `claude setup-token` で再発行し
|
||||
`helm upgrade --set anthropic.oauthToken=...`(または Secret 更新 + Pod 再起動)します。
|
||||
- 利用枠はローカルの Claude Code と共有です。同時セッションを増やすとプランの
|
||||
レート上限に早く達します。
|
||||
- `session.maxLifetimeSeconds`(既定 12h)が `accessToken` の寿命より長いと、長時間
|
||||
セッションが自分でトークンを更新し、`refreshToken` のローテーションで refresher 側の
|
||||
値が一時的に古くなることがあります。refresher は短い周期(既定 30 分)で追従します。
|
||||
- **refresher は Claude Code CLI の OAuth クライアント値(`anthropic.refresher.tokenUrl` /
|
||||
`clientId`)に依存します。これらは非公式で、仕様変更により動かなくなる可能性があります。**
|
||||
その場合でもセッション内 `claude` の自己更新は独立して機能します(新規セッションの
|
||||
起動時トークンが古い場合のみ影響)。不要なら `anthropic.refresher.enabled: false`。
|
||||
- refresher の権限は **セッション NS の認証情報 Secret 1 個への `get` / `patch` のみ**
|
||||
(`resourceNames` で限定した Role)。
|
||||
- `refreshToken` 自体が失効・失効させられた場合は、手元 PC で `claude` に再ログインして
|
||||
`--set-file anthropic.credentialsJson=...` で再投入します。
|
||||
- Secret の中身は refresher が書き換えます。`helm upgrade` で `--set-file` を付けない限り
|
||||
Helm は Secret の値を上書きしません(`helm.sh/resource-policy: keep` + 3-way merge)。
|
||||
|
||||
## 管理画面へのアクセス(LoadBalancer / Ingress)
|
||||
|
||||
@@ -226,7 +248,8 @@ ingress:
|
||||
- LoadBalancer 実装(kube-vip / MetalLB / Cilium LB-IPAM など) … 既定
|
||||
- Ingress コントローラー … `ingress.enabled: true` の場合
|
||||
- どちらも無い場合は `service.type: ClusterIP` + `kubectl port-forward` で利用可
|
||||
- Claude の認証情報 … `claude setup-token` の OAuth トークン(推奨)または `ANTHROPIC_API_KEY`
|
||||
- Claude の認証情報 … `~/.claude/.credentials.json`(既定 `credentials` モード・推奨)
|
||||
または `claude setup-token` の OAuth トークン、`ANTHROPIC_API_KEY`
|
||||
|
||||
### Helm リポジトリから
|
||||
|
||||
@@ -242,16 +265,17 @@ helm upgrade --install claude-code cafepieters/claude-code \
|
||||
### ローカル LB の IP + サブスクリプション認証(API 不要・推奨構成)
|
||||
|
||||
```bash
|
||||
claude setup-token # 手元の PC で長期 OAuth トークンを発行
|
||||
|
||||
# 手元の PC は claude にログイン済みであること(~/.claude/.credentials.json が存在)
|
||||
helm upgrade --install claude-code cafepieters/claude-code \
|
||||
-n claude-code --create-namespace \
|
||||
-f examples/loadbalancer-oauth.values.yaml \
|
||||
--set anthropic.oauthToken="<発行されたトークン>" \
|
||||
--set-file anthropic.credentialsJson="$HOME/.claude/.credentials.json" \
|
||||
--set-file git.identities.gitea-ssh.sshPrivateKey=P:/Claude/.ssh/id_claude \
|
||||
--set-file git.identities.gitea-ssh.knownHosts=./known_hosts.gitea
|
||||
```
|
||||
|
||||
以降トークンが変わっても再デプロイは不要です(refresher CronJob が Secret を追従更新)。
|
||||
|
||||
`examples/loadbalancer-oauth.values.yaml` は Ingress 無効・`service.type: LoadBalancer` +
|
||||
kube-vip の VIP 指定 + `loadBalancerSourceRanges` によるローカルセグメント限定の構成です。
|
||||
|
||||
@@ -352,14 +376,23 @@ ssh-keyscan 192.168.9.65 > known_hosts.gitea
|
||||
|
||||
### anthropic — Claude Code 認証情報
|
||||
|
||||
詳細は [Claude 認証(API 課金なし / サブスクリプション)](#claude-認証api-課金なし--サブスクリプション) を参照。
|
||||
|
||||
| キー | 既定 | 説明 |
|
||||
|---|---|---|
|
||||
| `anthropic.authMode` | `apiKey` | `apiKey`(`ANTHROPIC_API_KEY`)/ `oauth`(`CLAUDE_CODE_OAUTH_TOKEN`) |
|
||||
| `anthropic.authMode` | `credentials` | `credentials`(`~/.claude/.credentials.json`・推奨)/ `oauth`(`CLAUDE_CODE_OAUTH_TOKEN`)/ `apiKey`(`ANTHROPIC_API_KEY`) |
|
||||
| `anthropic.credentialsJson` | `""` | `--set-file anthropic.credentialsJson=$HOME/.claude/.credentials.json` で注入 |
|
||||
| `anthropic.apiKey` / `anthropic.oauthToken` | `""` | `--set` / `--set-file` で注入 |
|
||||
| `anthropic.existingSecret` | `""` | 既存 Secret を使う(キー名は `existingSecretKeyApiKey` / `existingSecretKeyOauthToken`) |
|
||||
| `anthropic.existingSecret` | `""` | 既存 Secret を使う(キー名は `existingSecretKeyCredentials`(既定 `.credentials.json`)/ `...ApiKey` / `...OauthToken`) |
|
||||
| `anthropic.refresher.enabled` | `true` | `credentials` モードで、Secret 内 `refreshToken` を使いトークンを定期更新する CronJob を作成 |
|
||||
| `anthropic.refresher.schedule` | `*/30 * * * *` | refresher CronJob のスケジュール |
|
||||
| `anthropic.refresher.refreshIfExpiresInSeconds` | `3600` | `accessToken` の残り寿命がこの秒数未満なら更新 |
|
||||
| `anthropic.refresher.tokenUrl` / `clientId` | Claude Code CLI の公開値 | OAuth トークンエンドポイントとクライアント ID(**非公式・仕様変更で要更新**) |
|
||||
| `anthropic.extraEnv` | `{}` | 全セッションへ渡す追加 env(例 `ANTHROPIC_BASE_URL`、Bedrock/Vertex 切替など) |
|
||||
|
||||
Secret は **セッション NS** に作成され、セッション Pod へ `envFrom` で注入されます。
|
||||
Secret は **セッション NS** に作成されます。`credentials` モードはファイルとしてマウントし
|
||||
セッション起動時に `$HOME/.claude/.credentials.json` へコピー(書き込み可能)、
|
||||
`apiKey` / `oauth` モードは `envFrom` で環境変数として注入します。
|
||||
|
||||
### git — 接続先と認証アイデンティティ
|
||||
|
||||
@@ -492,6 +525,7 @@ docker buildx build --platform linux/amd64,linux/arm64 \
|
||||
|
||||
| バージョン | Claude Code | 変更内容 |
|
||||
|---|---|---|
|
||||
| 2.1.263-b | 2.1.263 | `anthropic.authMode: credentials`(既定)を追加。`~/.claude/.credentials.json` 全体を注入し、セッション内 `claude` の自己更新に加え、クラスタ内 refresher CronJob(`refreshToken` で Secret を定期更新)でトークン失効に自動追従。→ トークンが変わっても再デプロイ不要。refresher の RBAC は認証情報 Secret 1 個の get/patch に限定 |
|
||||
| 2.1.263-a | 2.1.263 | Service を `LoadBalancer` 対応(kube-vip 等でローカル LB の IP から管理画面へアクセス、`loadBalancerSourceRanges` で接続元制限、既定を `LoadBalancer` に変更)。Ingress は従来どおり併用可。API を使わないサブスクリプション認証(`claude setup-token` → `authMode: oauth`)の手順を README に追記 |
|
||||
| 2.1.263 | 2.1.263 | 自動更新 |
|
||||
| 2.1.259 | 2.1.259 | 初版。gateway + manager + 使い捨て session Pod + reaper、GitHub/Gitea 対応、アイドル自動破棄、NetworkPolicy / RBAC 最小化 / restricted PodSecurity |
|
||||
|
||||
Reference in New Issue
Block a user