# セキュリティ設計書

## 概要

本ドキュメントは、Kubernetes プロジェクト（kubernetes-master）におけるセキュリティ設計を記載する。Kubernetes の API サーバ（kube-apiserver）を中心とした認証・認可・暗号化・入力検証・監査ログの各セキュリティ機構について、ソースコードから読み取れる設計内容を整理する。

## 認証設計

### 認証方式

Kubernetes API サーバは、プラガブルな認証チェーンを採用しており、複数の認証方式を同時に有効化できる。認証チェーンは `unionauth.New()` によって連結され、いずれかの認証方式が成功すれば認証済みとなる。

主な認証方式は以下の通りである。

| 認証方式 | 実装パッケージ | 概要 |
| --- | --- | --- |
| X.509 クライアント証明書 | `apiserver/pkg/authentication/request/x509` | mTLS によるクライアント証明書認証。CA バンドルを用いて検証し、CommonName をユーザ名として抽出する |
| Bearer Token（Webhook） | `apiserver/plugin/pkg/authenticator/token/webhook` | TokenReview API を通じた外部 Webhook によるトークン検証 |
| Bearer Token（JWT / ServiceAccount） | `apiserver/pkg/authentication/token/jwt` | ServiceAccount トークンの JWT 検証 |
| Bearer Token（Static Token File） | `apiserver/pkg/authentication/token/tokenfile` | 静的トークンファイルによる認証（開発・テスト用途） |
| Request Header（Front Proxy） | `apiserver/pkg/authentication/request/headerrequest` | フロントプロキシ（aggregation layer）からのヘッダ情報による認証。X-Remote-User、X-Remote-Group、X-Remote-Extra- ヘッダを使用 |
| Anonymous | `apiserver/pkg/authentication/request/anonymous` | 他の認証方式が全て失敗した場合のフォールバック。条件付きで有効化可能 |
| WebSocket Protocol | `apiserver/pkg/authentication/request/websocket` | WebSocket 接続時のプロトコルベース認証 |

認証チェーンの構成順序（`DelegatingAuthenticatorConfig.New()` に基づく）:
1. Front Proxy（RequestHeader）認証
2. X.509 クライアント証明書認証
3. Bearer Token 認証（Webhook + キャッシュ）
4. Anonymous 認証（フォールバック、有効時のみ）

### セッション管理

Kubernetes API サーバはステートレスな REST API であり、リクエストごとにトークンまたは証明書による認証を行う。従来のセッション管理（Cookie ベース等）は存在しない。

| 項目 | 設定値 | 備考 |
| --- | --- | --- |
| トークンキャッシュ TTL | `CacheTTL`（設定可能） | Webhook トークン認証結果のキャッシュ有効期限。`cache.New(tokenAuth, false, c.CacheTTL, c.CacheTTL)` で設定 |
| Webhook リトライバックオフ | Duration: 500ms, Factor: 1.5, Jitter: 0.2, Steps: 5 | `DefaultAuthWebhookRetryBackoff()` によるデフォルト値 |
| ServiceAccount トークン有効期限 | バインドトークンは時間制限付き（ProjectedVolume 経由） | TokenRequest API により有効期限付きトークンを発行 |

## 認可設計

### 権限体系

Kubernetes は RBAC（Role-Based Access Control）を主要な認可方式として採用している。`RBACAuthorizer` が `authorizer.Authorizer` インターフェースを実装する。

| ロール種別 | スコープ | 説明 |
| --- | --- | --- |
| Role | Namespace スコープ | 特定の Namespace 内のリソースに対する権限を定義 |
| ClusterRole | クラスタ全体 | クラスタ全体のリソースおよび非リソース URL に対する権限を定義 |
| RoleBinding | Namespace スコープ | Role/ClusterRole をユーザ・グループ・ServiceAccount に紐付け |
| ClusterRoleBinding | クラスタ全体 | ClusterRole をユーザ・グループ・ServiceAccount にクラスタ全体で紐付け |

認可判定の結果は3値で表現される（`authorizer.Decision`）:
- `DecisionAllow`: 許可
- `DecisionDeny`: 拒否
- `DecisionNoOpinion`: 判定なし（次の認可モジュールに委譲）

### アクセス制御

RBAC による認可判定は、`RBACAuthorizer.Authorize()` メソッドで以下の属性に基づいて行われる:

- **ユーザ情報**: ユーザ名、所属グループ、UID、Extra 情報
- **リソースリクエスト**: API グループ、リソース種別、サブリソース、リソース名、Verb（get, list, watch, create, update, patch, delete, deletecollection, proxy）
- **非リソースリクエスト**: HTTP メソッド（get, put, post, patch, delete）、パス

PolicyRule のマッチングは以下の関数で行われる:
- `rbacv1helpers.VerbMatches()`: Verb の一致判定
- `rbacv1helpers.APIGroupMatches()`: API グループの一致判定
- `rbacv1helpers.ResourceMatches()`: リソース・サブリソースの一致判定
- `rbacv1helpers.ResourceNameMatches()`: リソース名の一致判定
- `rbacv1helpers.NonResourceURLMatches()`: 非リソース URL の一致判定

また、Node 認可（`plugin/pkg/auth/authorizer/node`）により、kubelet は自ノードに関連するリソースのみへのアクセスが制限される。

`DelegatingAuthorizationOptions` では、`AlwaysAllowPaths`（認可をスキップするパス）および `AlwaysAllowGroups`（常に許可するグループ、例: `system:masters`）が設定可能である。

## 通信セキュリティ

| 項目 | 対策 |
| --- | --- |
| HTTPS | API サーバは `SecureServingOptions` により TLS 必須。`ServerCert` でサーバ証明書を設定。SNI（Server Name Indication）対応の複数証明書設定が可能 |
| TLS バージョン | `MinTLSVersion` で最小 TLS バージョンを指定可能（`crypto/tls` パッケージの定数で設定） |
| 暗号スイート | `CipherSuites` で許可する暗号スイートを制限可能 |
| HTTP/2 | `DisableHTTP2Serving` フラグで無効化可能。`HTTP2MaxStreamsPerConnection` でストリーム数を制限可能 |
| mTLS（相互 TLS） | `ClientCertificateCAContentProvider` によりクライアント証明書の CA を設定し、mTLS 認証を実現 |

## データセキュリティ

### 暗号化

Kubernetes は etcd に保存されるデータの暗号化（Encryption at Rest）を `EncryptionConfiguration` によりサポートする。

| 対象 | 暗号化方式 |
| --- | --- |
| 通信（API サーバ - クライアント間） | TLS 1.2+ (設定可能)。証明書は `SecureServingOptions.ServerCert` で管理 |
| 保存データ（etcd） | 以下の暗号化プロバイダが利用可能（`encryptionconfig` パッケージ） |

etcd 保存データの暗号化プロバイダ:

| プロバイダ | プレフィックス | 概要 |
| --- | --- | --- |
| AES-CBC | `k8s:enc:aescbc:v1:` | AES-CBC モードによる暗号化 |
| AES-GCM | `k8s:enc:aesgcm:v1:` | AES-GCM モードによる認証付き暗号化 |
| Secretbox | `k8s:enc:secretbox:v1:` | NaCl Secretbox による暗号化 |
| KMS v1 | `k8s:enc:kms:v1:` | 外部 KMS プロバイダ連携（v1 API） |
| KMS v2 | `k8s:enc:kms:v2:` | 外部 KMS プロバイダ連携（v2 API）。DEK/Seed の TTL 管理あり（デフォルト 3分） |
| Identity | なし | 暗号化なし（平文保存） |

KMS v2 プロバイダのヘルスチェック設定:
- 正常時ポーリング間隔: 1分（`kmsv2PluginHealthzPositiveInterval`）
- 異常時ポーリング間隔: 10秒（`kmsv2PluginHealthzNegativeInterval`）
- DEK/Seed 最大 TTL: 3分（`kmsv2PluginWriteDEKSourceMaxTTL`）

### 機密情報管理

- **ServiceAccount トークン**: `v1.SecretTypeServiceAccountToken` 型の Secret として管理。`IsServiceAccountToken()` 関数で検証。バインドトークン（ProjectedVolume）による時間制限付きトークンの利用を推奨
- **暗号化キー**: EncryptionConfiguration ファイルで管理。Base64 エンコードされた鍵を使用し、SHA-256 ハッシュで鍵の一意性を検証
- **External JWT**: `staging/src/k8s.io/externaljwt` パッケージにより外部 JWT 署名の統合をサポート

## 入出力対策

Kubernetes API サーバは、Admission Controller チェーンにより入力の検証とミューテーションを行う。

| 脅威 | 対策 |
| --- | --- |
| 不正なリクエストオブジェクト | Admission Controller の `ValidationInterface.Validate()` により、リクエストオブジェクトのバリデーションを実施。CREATE、UPDATE、DELETE、CONNECT の各操作に対応 |
| 権限昇格（Pod セキュリティ） | Pod Security Admission（`pod-security-admission`）により、Pod のセキュリティコンテキストを検証。Privileged、Baseline、Restricted の3レベルのポリシーを提供。`check_allowPrivilegeEscalation`、`check_capabilities`、`check_hostNamespaces`、`check_hostPathVolumes`、`check_hostPorts`、`check_privileged`、`check_procMount` 等のチェックを実装 |
| ミューテーション整合性 | `MutationInterface.Admit()` と `ReinvocationContext` により、Webhook によるミューテーション後の再検証を実施 |
| Webhook による拡張検証 | `admission/plugin/webhook` により、外部 Webhook での Validating / Mutating Admission を実現 |
| CEL ベースのバリデーション | `admission/plugin/cel` および `admission/plugin/policy` により、CEL（Common Expression Language）式を用いたカスタムバリデーションを実現 |
| Namespace ライフサイクル | `admission/plugin/namespace` により、削除中の Namespace へのリソース作成を防止 |
| リソースクォータ | `admission/plugin/resourcequota` により、リソースの使用量制限を強制 |

## 監査ログ

Kubernetes API サーバは、構造化された監査ログ機構を備えている。

| ログ種別 | 記録内容 | 保持期間 |
| --- | --- | --- |
| Audit Event | リクエスト受信時刻、Verb、RequestURI、UserAgent、ソース IP、ユーザ情報（Username、Groups、UID、Extra）、対象オブジェクト参照（Namespace、Name、Resource、Subresource、APIGroup、APIVersion）、Audit-ID ヘッダ | バックエンド設定に依存 |

### 監査レベル

監査ポリシー（`audit.Policy`）により、リクエストごとの監査レベルを制御する（`policyRuleEvaluator.EvaluatePolicyRule()`）。

| レベル | 説明 |
| --- | --- |
| None | 監査無効 |
| Metadata | メタデータのみ記録（デフォルト） |
| Request | メタデータ + リクエストオブジェクトを記録 |
| RequestResponse | メタデータ + リクエスト + レスポンスオブジェクトを記録 |

### 監査ステージ

監査イベントは、リクエスト処理の各ステージで生成される。ポリシーの `OmitStages` で特定ステージの監査を除外可能。

### 監査バックエンド

| バックエンド | 概要 |
| --- | --- |
| Log | ファイルへの出力。`lumberjack` によるログローテーション対応 |
| Webhook | 外部 Webhook への送信 |
| Buffered | バッチモードでのイベントバッファリング（バッファサイズ: 10000、バッチサイズ: 400、送信間隔: 30秒、スロットル: 10 QPS / バースト 15） |
| Truncate | 大きなイベントのトランケーション |

### 監査モード

| モード | 説明 |
| --- | --- |
| batch | 非同期バッチ送信 |
| blocking | 同期送信（レスポンス前にフラッシュ） |
| blocking-strict | 同期送信 + RequestReceived ステージでの失敗時にリクエスト全体を失敗させる |

## 備考

- Kubernetes はマイクロサービスアーキテクチャの基盤であり、XSS / CSRF / SQL インジェクション等の Web アプリケーション脆弱性は API サーバレベルでは直接的な対策対象ではない。API サーバは JSON/Protobuf ベースの REST API であり、ブラウザから直接利用されることを前提としていない
- CORS 設定は API サーバの起動オプションとして `--cors-allowed-origins` で制御可能であるが、ソースコード上のデフォルト設定はプロジェクト全体の設定ファイルに依存する
- NetworkPolicy リソースにより、Pod 間のネットワーク通信を制御可能（CNI プラグインの実装に依存）
- Secret リソースの管理に関しては、EncryptionConfiguration による etcd 暗号化に加え、外部シークレット管理システム（Vault 等）との連携が推奨される
