Files
claude-code/values.yaml
T
claude c31dd5875c
Helm Chart Release / release-chart (push) Successful in 7s
Build Session Image / build-push (push) Successful in 2m5s
feat: git identity を Web UI から登録・削除できるようにする (v2.1.263-f)
helm --set-file ではなく UI から SSH 秘密鍵 + known_hosts / HTTPS トークンを登録可能に。

- git.guiIdentities.enabled(既定 true)。UI に「認証情報」カード(一覧/追加/削除)
- GET/POST/DELETE /api/identities。登録分はセッション NS の Secret
  (ラベル identity-source=gui / identity-type)として保存。Helm 管理分と同一覧に統合
- manager.py: resolve_identity / list_identities / create_gui_identity / delete_gui_identity。
  build_pod と create_session は Helm 管理 + GUI 登録の両方を解決。
  /api/config の identities を {name,type,source} 配列に変更
- rbac.yaml: guiIdentities.enabled 時のみ manager Role に同 NS secrets の CRUD を付与
- 秘密鍵はリクエストボディで manager へ届くため README に経路 TLS 必須を明記
- helm lint / template 検証済み
2026-09-09 12:47:50 +09:00

414 lines
18 KiB
YAML
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-code — Claude Code リモート実行 Helm チャート
# --------------------------------------------------------------------------
# 構成:
# gateway ... 受付 nginx。ブラウザ ↔ セッションの単一入口。認証・WebSocket
# プロキシ・アクティビティ計測を担う。
# manager ... 制御プレーン(Python 標準ライブラリのみ)。セッションの
# 作成/一覧/破棄 API、Web UI、アイドル回収ループ。
# session ... セッションごとに作られる使い捨て Pod。Alpine ベースで
# git clone → 編集 → 検証 → push を行い、claude を ttyd 経由で
# ブラウザに提供する。アイドルで自動破棄。
#
# セキュリティ上の注意(必読):
# - この values.yaml に平文の API キー / SSH 秘密鍵 / トークンを書かない。
# Git にコミットしない。実値は CI の --set / --set-file か existingSecret で注入する。
# - セッション Pod は API サーバーへアクセスできない(SA トークン非マウント)。
# - セッション Pod の egress は Git ホストと api.anthropic.com のみに制限される
# (networkPolicy.enabled: true のとき)。
# - 詳細は README.md「セキュリティモデル」を参照。
# ==========================================================================
nameOverride: ""
fullnameOverride: ""
# --------------------------------------------------------------------------
# image: すべて Alpine ベース / linux/arm64 対応イメージ
# --------------------------------------------------------------------------
image:
# 受付 nginx(非 root 版)
gateway:
registry: docker.io
repository: nginxinc/nginx-unprivileged
tag: "1.31.5-alpine"
pullPolicy: IfNotPresent
# 制御プレーン(Python 標準ライブラリのみ・追加 pip 不要)
manager:
registry: docker.io
repository: library/python
tag: "3.14-alpine"
pullPolicy: IfNotPresent
# セッションの使い捨てコンテナ。
# 既定は CI(session-image.yaml)がビルドする事前ビルドイメージ
# (git + openssh + ttyd + node + @anthropic-ai/claude-code 同梱、非 root 実行)。
# restricted PodSecurity / readOnlyRootFilesystem 下で確実に動くのはこの方式。
#
# 事前ビルドを使わず素の node:alpine 等を指定することも可能だが、その場合
# ブート時に $HOME へ claude を npm インストールし、ttyd が同梱されていないと
# 起動に失敗する(apk は非 root では不可)。フォールバック例:
# registry: docker.io / repository: library/node / tag: "22-alpine"
session:
registry: git.cafepieters.com
repository: helmchart/claude-code/session
tag: "2.1.263"
pullPolicy: IfNotPresent
imagePullSecrets: []
# --------------------------------------------------------------------------
# gateway: 受付・ルーティング
# --------------------------------------------------------------------------
gateway:
replicaCount: 1
# gateway コンテナの待受ポート(Service / Ingress のバックエンド)
port: 8080
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
cpu: 250m
memory: 128Mi
# --------------------------------------------------------------------------
# manager: 制御プレーン
# --------------------------------------------------------------------------
manager:
# debug | info | warning | error
logLevel: info
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 500m
memory: 256Mi
# --------------------------------------------------------------------------
# sessionsNamespace: セッション Pod を隔離するネームスペース
# --------------------------------------------------------------------------
sessionsNamespace:
# 空 = リリース先ネームスペースを使う。セキュリティ上、専用ネームスペースを推奨。
name: "claude-code-sessions"
# true ならこのチャートがネームスペースを作成し PodSecurity ラベルを付与する。
# 既存ネームスペースを使う場合は false にし、下記ラベルを手動で付与すること。
create: true
# PodSecurity admission レベル(restricted 準拠のセッション Pod を強制)
podSecurityLevel: restricted
# セッション NS 全体の使用量上限(暴走・過剰生成のブラスト半径を限定)
resourceQuota:
enabled: true
# 省略値は session.maxSessions と session.resources から算出される。
# 明示指定するとそのまま ResourceQuota.spec.hard になる。
hard: {}
# requests.cpu: "4"
# requests.memory: 8Gi
# limits.cpu: "16"
# limits.memory: 32Gi
# セッション NS のコンテナ既定値 / 上限
limitRange:
enabled: true
max:
cpu: "4"
memory: 4Gi
default:
cpu: "1"
memory: 1Gi
defaultRequest:
cpu: 100m
memory: 256Mi
# --------------------------------------------------------------------------
# auth: ブラウザからのアクセス認証
# --------------------------------------------------------------------------
auth:
# token : Bearer トークン / Cookie / ?token= で検証(既定)
# basic : HTTP Basic 認証(htpasswd)
# forward : 外部認証プロキシ(oauth2-proxy 等)へ auth_request を委譲
# none : 認証なし(信頼済みネットワーク限定・非推奨)
mode: token
token:
# 空なら install 時に自動生成される(helm get manifest で参照可能なため、
# 運用では existingSecret を使うのが望ましい)。
value: ""
existingSecret: ""
existingSecretKey: "token"
basic:
# `htpasswd -nbB user pass` の出力を1行以上。existingSecret 優先。
users: []
existingSecret: ""
existingSecretKey: "htpasswd"
forward:
# nginx auth_request の転送先(例: http://oauth2-proxy.auth.svc.cluster.local:4180/oauth2/auth)
url: ""
# 未認証時のリダイレクト先(任意)
signInUrl: ""
# --------------------------------------------------------------------------
# anthropic: Claude Code の認証情報
# --------------------------------------------------------------------------
anthropic:
# authMode:
# credentials : ~/.claude/.credentials.json 全体(refreshToken 込み)を注入(推奨)。
# 各セッションはこのファイルを $HOME/.claude/.credentials.json に配置し、
# claude が自身でアクセストークンをリフレッシュする。加えて下記
# refresher CronJob がクラスタ内で Secret を最新に保つ。
# → API 課金なし。トークンが定期的に変わっても再デプロイ不要。
# oauth : CLAUDE_CODE_OAUTH_TOKEN を注入(`claude setup-token` の単発トークン。
# refreshToken を含まないため自動更新されない)。
# apiKey : ANTHROPIC_API_KEY を注入(API 従量課金)。
authMode: credentials
apiKey: ""
oauthToken: ""
# credentials モード: claude ログイン済みマシンの ~/.claude/.credentials.json の中身。
# 例: {"claudeAiOauth":{"accessToken":"...","refreshToken":"...","expiresAt":...,
# "scopes":["user:inference","user:profile"],"subscriptionType":"max"}}
# 注入は平文で書かず: --set-file anthropic.credentialsJson=$HOME/.claude/.credentials.json
credentialsJson: ""
# 上記の代わりに既存 Secret を参照
existingSecret: ""
existingSecretKeyApiKey: "ANTHROPIC_API_KEY"
existingSecretKeyOauthToken: "CLAUDE_CODE_OAUTH_TOKEN"
existingSecretKeyCredentials: ".credentials.json"
# 全セッションへ渡す追加環境変数(例: ANTHROPIC_BASE_URL / ANTHROPIC_MODEL)
extraEnv: {}
# ---- refresher: credentials モードのトークン自動更新 CronJob ----
# Secret 内の refreshToken を使って新しい accessToken を取得し、Secret を書き戻す。
# これで自マシンがオフラインでも新規セッションは常に有効なトークンで起動できる。
# ⚠ Claude Code CLI の OAuth クライアント値(tokenUrl / clientId)に依存する。
# これらは非公式であり、仕様変更で動かなくなる可能性がある。その場合でも
# セッション内 claude の自己リフレッシュは独立して機能する。
refresher:
enabled: true
schedule: "*/30 * * * *" # 30 分ごと
# 期限まで残りこの秒数を切っていたら更新する(十分な余裕を持たせる)
refreshIfExpiresInSeconds: 3600
tokenUrl: "https://console.anthropic.com/v1/oauth/token"
clientId: "9d1c250a-e61b-44d9-88ed-5944d1962f5e"
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 200m
memory: 96Mi
# --------------------------------------------------------------------------
# git: 接続先ホストと認証アイデンティティ
# --------------------------------------------------------------------------
git:
# チェックアウトを許可するホスト allow-list。manager はこれ以外のホストを拒否する。
allowedHosts:
- github.com
- gitlab.com
- 192.168.9.65
- git.cafepieters.com
# allow-list を無効化し任意 URL を許可する(非推奨)
allowArbitraryRepos: false
# コミット時の既定 author(セッション作成時に上書き可)
defaultAuthorName: "Claude"
defaultAuthorEmail: "claude@cafepieters.com"
# GUI(Web UI)からの認証情報 identity 登録を許可する。
# 有効にすると、UI の「認証情報」カードから SSH 秘密鍵 + known_hosts / HTTPS トークンを
# 登録・削除できる。登録内容はセッション NS の Secret として保存される。
# トレードオフ:
# - manager にセッション NS の secrets への get/list/create/update/delete 権限が付く
# (同 NS には Claude 認証情報 Secret も存在する点に留意)。
# - 秘密鍵はブラウザ→gateway→manager をリクエストボディで通る。経路の TLS
# (Ingress の tls / LB の TLS 終端)を必ず有効にすること。
# 下の git.identities(Helm 管理)は常に読み取り専用で UI に表示される。
guiIdentities:
enabled: true
# 認証アイデンティティ(Helm 管理)。セッション作成時に名前で選択する。
# GitHub / Gitea / GitLab など SSH または HTTPS トークンで認証する任意のホストに対応。
# GUI から登録したものと合わせて使える(同名は不可)。
identities: {}
# gitea-ssh:
# type: ssh # ssh | https-token
# # --- ssh のとき ---
# sshPrivateKey: "" # PEM 形式。existingSecret 優先
# knownHosts: "" # `ssh-keyscan <host>` の出力(必須/ホスト鍵TOFUを無効化)
# # --- 既存 Secret を使う場合 ---
# existingSecret: ""
# existingSecretKeyPrivateKey: "id"
# existingSecretKeyKnownHosts: "known_hosts"
# github-https:
# type: https-token
# username: "x-access-token" # GitHub は任意文字列、Gitea はユーザー名
# token: "" # PAT。existingSecret 優先
# existingSecret: ""
# existingSecretKeyToken: "token"
# --------------------------------------------------------------------------
# session: 使い捨てセッションの挙動とライフサイクル
# --------------------------------------------------------------------------
session:
# ブート完了後に `claude` を自動起動する(false ならログインシェルで待受)
autoStartClaude: true
# リポジトリを clone する作業ディレクトリ
workspaceDir: /workspace
# ttyd の待受ポート(Pod 内からのみ到達可能)
ttydPort: 7681
# ブート時に追加インストールする apk パッケージ(言語ランタイム等)
extraApkPackages: []
# インストールする @anthropic-ai/claude-code のバージョン(空 = チャート appVersion)
claudeCodeVersion: ""
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: "2"
memory: 2Gi
ephemeral-storage: 4Gi
# ---- lifecycle: 破棄条件 ----
# 無通信がこの秒数継続したセッションを破棄する(Pod 内ウォッチドッグ + manager 回収)
idleTimeoutSeconds: 1800
# 生成からの最大寿命(Pod の activeDeadlineSeconds)。到達で強制終了。
maxLifetimeSeconds: 43200
reaper:
# manager 内アイドル回収ループの実行間隔
intervalSeconds: 60
# 終了済み(Succeeded / Failed)セッション Pod を回収せず残す秒数。
# 死因を UI の「ログ」ボタンや kubectl logs で確認できるよう猶予を持たせる。
# 0 にすると即回収(旧挙動)。
terminatedRetentionSeconds: 900
# 予備の孤児掃除 CronJob(manager 障害時の保険)
cronjob:
enabled: true
schedule: "*/15 * * * *"
# 同時に存在できるセッション数の上限(manager が enforce)
maxSessions: 10
# ---- verify / push ----
# セッション内の `claude-verify` が実行するコマンド(例: "npm test" / "make check")
verifyCommand: ""
autoPush:
# true でもデフォルトブランチや protectedBranches への push、--force は禁止。
enabled: false
branchPrefix: "claude/"
protectedBranches:
- main
- master
- develop
- release
# セッション Pod への追加メタデータ / スケジューリング
podLabels: {}
podAnnotations: {}
nodeSelector: {}
tolerations: []
# セッション Pod の優先度クラス(任意)
priorityClassName: ""
# --------------------------------------------------------------------------
# networkPolicy: 通信制限(CNI が NetworkPolicy 対応であること)
# --------------------------------------------------------------------------
networkPolicy:
enabled: true
# DNS 解決を許可する kube-dns の namespace セレクタ
dnsNamespaceSelector:
kubernetes.io/metadata.name: kube-system
# api.anthropic.com / GitHub は IP 固定できないため、既定でセッションの
# 443/tcp(HTTPS git・Claude API)と 22/tcp(SSH git)の外向きを許可する。
# 完全に閉じる場合は egress プロキシを用意し false にする。
allowInternetHttps: true
allowSshGit: true
# allowInternetHttps 時に egress から除外する CIDR(SSRF 対策)。
# クラウドのメタデータ IP は既定で遮断。自クラスターの Pod/Service CIDR を
# 追加すると、セッションから内部サービスへの到達を防げる。
blockedEgressCIDRs:
- 169.254.169.254/32
# 追加で許可する egress(社内ミラー / プロキシ用)
sessionEgressExtra: []
# - cidr: 10.0.0.0/8
# ports:
# - protocol: TCP
# port: 443
# --------------------------------------------------------------------------
# ingress / service
# --------------------------------------------------------------------------
ingress:
enabled: false
className: ""
annotations: {}
# nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
# nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
hosts:
- host: claude-code.example.com
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: claude-code-tls
# hosts:
# - claude-code.example.com
service:
# LoadBalancer : ローカルネットワークの LB(kube-vip / MetalLB / Cilium LB-IPAM 等)から
# IP を払い出し、その IP で管理画面へアクセスする(Ingress 不要・既定)
# ClusterIP : Service IP のみ。port-forward か Ingress 経由でアクセス
# NodePort : 各ノードの高位ポートで公開
type: LoadBalancer
port: 80
# NodePort を固定したい場合のみ(type: NodePort)
nodePort: null
# Service に付与するアノテーション。kube-vip で VIP を指定する例:
# kube-vip.io/loadbalancerIPs: "192.168.9.50"
# kube-vip.io/vipHost: "cpi11"
# MetalLB でプールを指定する例:
# metallb.universe.tf/address-pool: "lan"
annotations: {}
# 払い出す IP を直接指定(LB 実装が対応していれば)。annotations 指定を推奨。
loadBalancerIP: ""
loadBalancerClass: ""
# 接続元をローカルネットワークに限定する(LB 実装が対応していれば)。
# Ingress を張らない構成では、ここで許可レンジを絞ることが第一の防御線になる。
loadBalancerSourceRanges: []
# - 192.168.9.0/24
# - 10.0.0.0/8
# Local にすると実クライアント IP を保持する(kube-proxy/LB 実装依存)
externalTrafficPolicy: ""
# Service 自体への追加ラベル
labels: {}
# --------------------------------------------------------------------------
# 制御プレーンの Pod / コンテナセキュリティ
# --------------------------------------------------------------------------
podSecurityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
containerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# 全リソースへ付与する追加ラベル / アノテーション
commonLabels: {}
commonAnnotations: {}
podDisruptionBudget:
enabled: false
minAvailable: 1