Contents
1. Zero Trust の基本概念と Istio での対応
Zero Trust の核は以下の 3 原則です。
- 最小特権 (Least Privilege) – 必要最低限のアクセスだけを許可する。
- 常時検証 (Continuous Verification) – リクエスト毎に認証・認可と通信暗号化を行う。
- 可視化 (Visibility) – 全トラフィックとポリシー評価結果を監査ログとして残す。
| NIST SP 800‑204 要素 | Istio が提供する機能 | 主な CRD |
|---|---|---|
| 認証 (Authentication) | 相互 TLS (mTLS) | PeerAuthentication |
| 認可 (Authorization) | RBAC / 属性ベース認可 | AuthorizationPolicy |
| アイデンティティ管理 | 外部 OIDC プロバイダー連携 | RequestAuthentication |
| 監査・可視化 | テレメトリ、ログ、サービスマップ | Telemetry v2、Kiali、Grafana |
ポイント:このマッピングをベースに「認証 → 認可 → 外部 IdP」の順でポリシーを構築すれば、Zero Trust が Kubernetes クラスタ全体に浸透します。
2. mTLS の有効化と自動証明書ローテーション(Istio 1.21+)
2‑1. 全トラフィックへの mTLS 適用
Istio 1.21 以降では Citadel が廃止され、組み込みの内部 CA がデフォルトで有効になります。PeerAuthentication に STRICT モードを設定すれば、クラスタ全体で即座に相互 TLS が強制されます。
|
1 2 3 4 5 6 7 8 9 |
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default-mtls namespace: istio-system # クラスタ全体へ継承 spec: mtls: mode: STRICT # 非暗号化トラフィックはブロック |
2‑2. 証明書の自動ローテーション
- デフォルト有効期間は 90 日(
defaultCertificateValidityDurationの既定値)です。 - ローテーションは内部 CA が証明書残存期限の 30 日前に新しい証明書を発行し、Envoy がシームレスに切り替えます。
- カスタマイズが必要な場合は
MeshConfigのdefaultCertificateAuthorityセクションでvalidityDurationを上書きできます。
|
1 2 3 4 5 6 7 |
apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: meshConfig: defaultCertificateAuthority: validityDuration: 180d # 任意に延長(例:180日) |
根拠:公式リファレンス「Istio Security – Certificate Management」(2024‑03) に記載されています。
3. AuthorizationPolicy と PeerAuthentication による RBAC 設計
3‑1. デフォルト deny の適用と例外許可
Zero Trust の「最小特権」を実装する基本戦略は Namespace 単位でデフォルト deny を設定し、必要な通信だけを明示的に許可することです。
|
1 2 3 4 5 6 7 8 |
# Namespace デフォルト deny(空の spec がすべて拒否) apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: prod-team-a spec: {} |
許可ルール例:frontend → backend
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-frontend-to-backend namespace: prod-team-a spec: selector: matchLabels: app: backend rules: - from: - source: principals: ["cluster.local/ns/prod-team-a/sa/frontend"] |
JWT クレームベースの認可例
|
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-admins namespace: prod-team-a spec: rules: - when: - key: request.auth.claims[role] values: ["admin"] |
ポイント:
PeerAuthenticationがSTRICTの場合、上記ポリシーは認証済みのリクエストだけが対象になるため、攻撃面が大幅に削減されます。
4. OPA Gatekeeper / Open Policy Agent と Istio ポリシーの自動適用
手作業で AuthorizationPolicy を管理するとヒューマンエラーが起きやすくなります。Gatekeeper は Kubernetes の Admission Control にフックし、Rego で記述したポリシー違反をデプロイ時に検出できます。
4‑1. ConstraintTemplate(MeshPolicy)例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: meshpolicy spec: crd: spec: names: kind: MeshPolicy targets: - target: admission.k8s.gatekeeper.sh rego: | package meshpolicy # PeerAuthentication が STRICT であることを必須化 violation[{"msg": msg}] { input.review.object.kind == "PeerAuthentication" not input.review.object.spec.mtls.mode == "STRICT" msg := sprintf("Namespace %s の PeerAuthentication は STRICT に設定してください", [input.review.object.metadata.namespace]) } |
4‑2. Constraint(必須ポリシー適用)
|
1 2 3 4 5 6 7 8 9 10 |
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: MeshPolicy metadata: name: require-strict-mtls spec: match: kinds: - apiGroups: ["security.istio.io"] kinds: ["PeerAuthentication"] |
CI/CD パイプラインに kubectl apply -f constrainttemplate.yaml と constraint.yaml を組み込めば、プルリクエスト時に自動で検証が走り、違反があればマージを阻止できます。
効果:組織全体で「必ず mTLS(STRICT)」「AuthorizationPolicy が存在する」などのベースラインをコード化し、継続的に適用できるようになります。
5. 外部認証プロバイダー統合と GKE における PSA の活用
5‑1. OIDC / Keycloak 連携手順
Istio の RequestAuthentication が外部 IdP の JWKs を自動取得・キャッシュするため、トークンローテーションや鍵のロールオーバーが発生しても設定変更は不要です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: keycloak-jwt namespace: prod-team-a spec: selector: matchLabels: app: backend jwtRules: - issuer: "https://keycloak.example.com/auth/realms/myrealm" jwksUri: "https://keycloak.example.com/auth/realms/myrealm/protocol/openid-connect/certs" |
続いて、JWT クレームに基づく RBAC を設定します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-readers namespace: prod-team-a spec: selector: matchLabels: app: backend rules: - when: - key: request.auth.claims[role] values: ["reader"] |
5‑2. PodSecurityAdmission (PSA) の正しい設定例
古くなった PodSecurityPolicy は非推奨です。GKE では PodSecurityAdmission が標準で提供され、enforce, warn, audit の3段階でポッドのセキュリティコンテキストを制御します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: policy/v1 kind: PodSecurityConfiguration metadata: name: restricted-psa spec: enforcementPolicy: mode: enforce # 強制モード enforceVersion: "v1.24" # Kubernetes バージョンに合わせる defaults: privileged: false runAsNonRoot: true readOnlyRootFilesystem: true seLinuxOptions: level: "s0:c123,c456" |
上記設定をクラスター全体で有効化するには、GKE の --enable-pod-security-policy フラグは不要です。代わりに次のコマンドで PSA を適用します。
|
1 2 |
kubectl apply -f psa-restricted.yaml |
5‑3. NetworkPolicy と PSA の二層防御
NetworkPolicy がレイヤ 3/4 のトラフィック制御、PSA がポッドのランタイム属性を保証することで、Istio サイドカー以外のコンテナが不必要に外部へ通信したり、特権モードで実行されたりするリスクを排除できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-egress-except-istio namespace: prod-team-a spec: podSelector: {} # 全 Pod が対象 policyTypes: - Egress egress: - to: - ipBlock: cidr: 10.0.0.0/8 # クラスタ内部 IP のみ許可 ports: - protocol: TCP port: 15001 # Istio Envoy の admin ポート |
まとめ:OIDC によるユーザー認証、PSA と NetworkPolicy による Pod レベルの防御を組み合わせれば、Zero Trust がネットワーク層から実行環境まで一貫して適用されます。
6. 監査ログ・テレメトリの収集と可視化、サイドカー自動インジェクション
6‑1. メトリクスとログの可視化基盤
Istio が出力する主要メトリクス(例:istio_requests_total, istio_authentication_policy_allow/deny)は Prometheus にスクレイプし、Grafana ダッシュボード と Kiali のサービスマップ で可視化します。
Prometheus 設定抜粋
|
1 2 3 4 5 6 7 8 9 10 11 |
- job_name: 'istio-mesh' kubernetes_sd_configs: - role: pod namespaces: names: - istio-system relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: "true" |
Grafana ダッシュボード例
公式ダッシュボード ID 7639(Istio Mesh Overview)をインポートし、istio_requests_total の成功率や istio_authentication_policy_deny をリアルタイムで監視します。
Kiali デプロイ
|
1 2 |
kubectl apply -f https://raw.githubusercontent.com/kiali/kiali/v1.78/operator/kiali-operator.yaml |
Kiali UI の Policies タブで現在有効な AuthorizationPolicy と対象ワークロードを一目で確認できます。
6‑2. 安全なサイドカー自動インジェクション
Istio の自動インジェクションは Namespace ラベル と Sidecar カスタムリソース によって制御します。誤ってテスト環境に注入しないよう、対象 Namespace だけにラベルを付与しましょう。
|
1 2 |
kubectl label namespace prod-team-a istio-injection=enabled |
Sidecar CRD で通信範囲を限定
|
1 2 3 4 5 6 7 8 9 10 11 12 |
apiVersion: networking.istio.io/v1beta1 kind: Sidecar metadata: name: default namespace: prod-team-a spec: egress: - hosts: - "*/backend" # backend サービスへの外部呼び出しだけ許可 inboundTrafficPolicy: mode: STRICT # 未許可ポートはすべてブロック |
この構成により、prod-team-a のみが自動的に Envoy を持ち、かつアウトバウンドは backend に限定されます。
最終ポイント:Prometheus + Grafana + Kiali でリアルタイム監視し、Namespace ラベルと Sidecar CRD でサイドカーの範囲を厳格に管理すれば、Zero Trust の「可視化」+「最小特権」が実装完了です。
まとめ
- 認証 –
PeerAuthentication(STRICT)で全サービス間の mTLS を自動ローテーション(90 日)と共に有効化。 - 認可 – Namespace デフォルト deny と属性ベース
AuthorizationPolicyによる最小特権実装。 - 外部 IdP 連携 – OIDC (
RequestAuthentication) と JWT クレームで細粒度のアクセス制御。 - ポリシー自動化 – Gatekeeper の ConstraintTemplate/Constraint で組織全体のベースラインをコード化。
- Pod セキュリティ – PodSecurityAdmission (PSA) と NetworkPolicy による二層防御。
- 可視化・運用 – Prometheus‑Grafana‑Kiali の統合と Sidecar カスタムリソースで安全かつ監査可能な環境を構築。
この手順に沿って Istio を設定すれば、Zero Trust がクラスタ全体に浸透し、攻撃面の縮小と運用可視性が同時に実現できます。