Contents
Istio のセキュリティ基礎と主要コンポーネント
この章では、Istio が提供する 3 つの重要な CRD(PeerAuthentication, RequestAuthentication, AuthorizationPolicy)の役割と相互関係を解説します。Zero‑Trust 環境でマイクロサービス間の認証・認可を統一的に管理したい場合、まずこれらの概念を正しく理解することが出発点となります。本節を読めば、各 CRD がどのタイミングで Envoy に反映されるか、そして実装上の注意点が把握できます。
PeerAuthentication の役割
PeerAuthentication はサービス間通信を 相互 TLS(mTLS) で暗号化し、クライアントとサーバー双方の証明書検証を強制します。Envoy が起動時にこのリソースを参照して自動的に TLS コンテキストを生成するため、個別ポッドのマニフェストを書き換える必要がありません。
|
1 2 3 4 5 6 7 8 9 |
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT # 全サービスで mTLS を必須化 |
- ポイント:クラスター全体で
STRICTに設定すると、認証が欠如した通信は即座に切断されます。 - ベストプラクティス:名前空間単位でも上書き可能です。たとえば開発環境だけ
PERMISSIVEにすることで段階的な移行が実現できます。
RequestAuthentication の概要
RequestAuthentication は外部トークン(主に JWT)を検証し、認可ポリシーで利用できる属性情報を Envoy に付与します。これにより、アプリケーションコード側でトークンの署名や有効期限チェックを書く必要がなくなります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: oidc-jwt namespace: demo spec: selector: matchLabels: app: frontend jwtRules: - issuer: "https://accounts.google.com" jwkSetUri: "https://www.googleapis.com/oauth2/v3/certs" |
- ポイント:
jwtRulesに複数の Issuer や JWK Set を列挙できるため、マルチテナント環境でも柔軟に対応可能です。 - 注意点:トークン自体は Envoy が検証しますが、クレーム内容の正当性(例:
roleの意味付け)は別途AuthorizationPolicyで評価する必要があります。
AuthorizationPolicy の基本
AuthorizationPolicy はリクエスト属性(サービス名、ポート、HTTP メソッド、JWT クレームなど)に基づき 許可(ALLOW)または拒否(DENY) を宣言します。Istio が Envoy フィルタでリアルタイムに評価し、違反時は 403 応答を返すため、アプリ側の認可ロジックを書き換える必要がありません。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: orders-get-only namespace: demo spec: selector: matchLabels: app: orders action: ALLOW rules: - to: - operation: methods: ["GET"] |
- ポイント:
rulesは配列で複数記述でき、ALLOWとDENYを組み合わせた「デフォルト DENY + 例外許可」パターンが推奨されます。 - ベストプラクティス:ポリシーは名前空間単位で管理し、CI/CD パイプラインに組み込むことで変更履歴とロールバックを保証します。
GKE での mTLS 全体有効化手順
GKE 上にデプロイした Istio クラスタ全体で 自動的に mTLS を適用する方法を解説します。ここでは istioctl のフラグと IstioOperator CRD の両方のアプローチを示し、最新バージョンで非推奨となっている設定項目についても注意喚起します。
istioctl による自動有効化
istioctl install で mTLS を自動的に有効化する際にかつて使用されていた --set values.global.mtls.auto=true は、Istio 1.21 以降 非推奨 とされています(公式リリースノート, 2024‑09-15). 現行の推奨方法は meshConfig.enableAutoMtls: true を IstioOperator に記述するか、--set meshConfig.enableAutoMtls=true とフラグを直接指定します。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# 1. istioctl の最新版(例: 1.22.0)を取得 curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.0 sh - # 2. PATH に追加 export PATH=$PWD/istio-1.22.0/bin:$PATH # 3. mTLS 自動有効化付きでインストール istioctl install \ --set profile=default \ --set meshConfig.enableAutoMtls=true \ -y |
- ポイント:
meshConfig.enableAutoMtlsはコントロールプレーンが新規サービスや既存サービスに対して自動的にPeerAuthentication(mode: STRICT)を注入します。 - 注意点:実運用前に必ず公式ドキュメント(Istio Security Concepts, 2024‑10) を確認し、使用している Istio のバージョンでサポート状況をチェックしてください。
IstioOperator での宣言的設定例
IstioOperator は GitOps と相性が良く、クラスタ全体の状態をコードとして管理できます。以下は 両方 のフラグ(旧 values.global.mtls.auto と新 meshConfig.enableAutoMtls)を記載したサンプルです。ただし実際に適用する際はどちらか一方に統一してください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: istio-control-plane namespace: istio-system spec: profile: default meshConfig: enableAutoMtls: true # 推奨設定(Istio 1.21+) # legacy: values.global.mtls.auto は削除予定 components: pilot: k8s: replicaCount: 2 values: global: controlPlaneSecurityEnabled: true # コントロールプレーン自体の TLS を有効化 # values.global.mtls.auto: true # ← 非推奨、削除予定 |
- ポイント:
meshConfig.enableAutoMtlsがtrueの場合、PeerAuthenticationが暗黙的に作成されるため、個別リソースを手動で用意する必要がありません。 - ベストプラクティス:
IstioOperatorを単一のリポジトリで管理し、環境ごとにoverlayファイルで差分を加えると、ステージング/本番間の設定ドリフトを防げます。
RBAC と JWT を活用した認可・認証実装
マイクロサービスが増えるほど、最小権限(Least Privilege) の原則に沿ったアクセス制御が重要になります。この章では、ネームスペース/ラベルベースの RBAC と外部 IdP が発行する JWT を組み合わせた実装例を示します。
Namespace/Service 単位の RBAC 定義
AuthorizationPolicy の from.source.namespaces と selector.matchLabels を併用すると、ネームスペース単位で 許可対象サービス を明確に限定できます。以下は payment ネームスペースの checkout サービスへ、order ネームスペースからの POST リクエストのみを許可する例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: cross-namespace-payments namespace: payment spec: selector: matchLabels: app: checkout action: ALLOW rules: - from: - source: namespaces: ["order"] to: - operation: methods: ["POST"] |
- ポイント:
from.source.namespacesに列挙したネームスペース以外からのアクセスはデフォルトで拒否されます(明示的にDENYポリシーを追加しなくても)。 - 実装上の注意:対象サービスが複数ある場合はラベルを共通化し、ポリシーを 1 つにまとめると管理負荷が低減します。
JWT 認証フローと RequestAuthentication 設定例
外部 IdP(Google, Auth0, Azure AD 等)から取得した JWT を Istio が検証し、クレーム情報を AuthorizationPolicy の条件として利用する典型的なパターンです。以下は role クレームが admin の場合にだけ管理 API へのアクセスを許可する構成です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# RequestAuthentication (JWT 検証) apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: admin-jwt namespace: frontend spec: selector: matchLabels: app: web jwtRules: - issuer: "https://accounts.google.com" jwkSetUri: "https://www.googleapis.com/oauth2/v3/certs" # AuthorizationPolicy (role ベース許可) apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: admin-only namespace: frontend spec: selector: matchLabels: app: web action: ALLOW rules: - when: - key: request.auth.claims[role] values: ["admin"] |
- ポイント:
request.auth.claims[role]は Envoy が自動的に抽出するため、ポリシーだけでロールベースの認可が完結します。 - 外部リンク:本実装は ZOZO TECH BLOG(2025‑12‑08, https://tech.zozo.com/istio-authz) と Google Cloud の公式ガイド(2024‑03‑15, https://cloud.google.com/service-mesh/docs/authentication)を参考にしています。
AuthorizationPolicy の高度な実装パターン
実運用では単純な ALLOW ポリシーだけでなく、DENY の優先順位 や クロスネームスペース制御、HTTP メソッド別の細分化 が求められます。ここでは代表的なパターンと落とし穴を解説します。
ALLOW / DENY ポリシー
DENY は「例外ブロック」や「安全弁」として有効です。Istio はポリシー評価時に 先行マッチ を行うため、DENY が最初にヒットすれば以降の ALLOW は無視されます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# デフォルトで全トラフィックをブロック(DENY) apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: default-deny namespace: istio-system spec: action: DENY # payment ネームスペースの checkout サービスだけ許可(ALLOW) apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-checkout namespace: payment spec: selector: matchLabels: app: checkout action: ALLOW rules: - {} # 空条件は「すべてのリクエストを許可」になる |
- ベストプラクティス:
DENY→ALLOWの二段構成で、将来的に新しいサービスが追加された際にも自動的にブロックされる安全性が保たれます。 - 注意点:空の
rules: [{}]は「すべて許可」を意味しますが、意図しない広範囲許可にならないようコメントで明示すると良いでしょう。
ネームスペース横断制御
複数ネームスペースにまたがるマイクロサービス間通信は、source.namespaces と destination.namespace を組み合わせて 明示的に許可 します。以下は inventory の stock-service が order と billing からの呼び出しを受け入れる例です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: cross-team-access namespace: inventory spec: selector: matchLabels: app: stock-service action: ALLOW rules: - from: - source: namespaces: ["order", "billing"] |
- ポイント:
source.namespacesに列挙しないネームスペースからのアクセスは自動的に拒否されます。 - 実務上のヒント:チームごとに名前空間を分割している場合、ポリシーは「チーム境界」を可視化する重要なドキュメントになります。
HTTP メソッド別の許可・拒否
REST API ではメソッド単位で権限が異なるケースが多く、Istio の operation.methods と paths を活用するとコードを書き換えることなく実装できます。以下は /admin/* パスに対し GET は許可、それ以外のメソッドは DENY する構成です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# GET のみ許可 apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: admin-get-allow namespace: admin spec: selector: matchLabels: app: admin-api action: ALLOW rules: - to: - operation: paths: ["/admin/*"] methods: ["GET"] # GET 以外はブロック(DENY) apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: admin-other-deny namespace: admin spec: selector: matchLabels: app: admin-api action: DENY rules: - to: - operation: paths: ["/admin/*"] |
- ポイント:
ALLOWとDENYを組み合わせると、許可対象以外はすべて自動的にブロックされます。 - 注意点:パスのワイルドカードは
*だけでなく、正規表現風の{}記法もサポートされていますが、バージョン間で挙動が変わることがあるため公式リファレンスを確認してください。
ポリシーの自動適用・検証・CI/CD への統合
運用段階では 手作業 でポリシーを適用するとミスが起きやすく、監査ログとの整合性も取れません。ここでは GitOps と CI/CD パイプラインに組み込む具体的な方法と、istioctl authn tls-check の実際の出力例を示します。
IstioOperator によるポリシー自動適用
IstioOperator は values.global.istioNamespace 以下に配置した ConfigMap を監視し、差分があれば即座に適用します。以下はリポジトリ構成とデプロイ手順の例です。
|
1 2 3 4 5 6 7 8 |
repo/ ├─ istio/ │ └─ operator.yaml # IstioOperator 本体 └─ policies/ ├─ peer-auth.yaml # PeerAuthentication (mTLS) ├─ request-auth.yaml # RequestAuthentication (JWT) └─ authz-allow.yaml # AuthorizationPolicy |
|
1 2 3 4 |
# Operator とポリシーを同時に適用 kubectl apply -f istio/operator.yaml kubectl apply -f policies/ |
- ポイント:
operator.yamlが変更されると、Operator が自動的に再同期し、policies/の全 YAML が再適用されます。 - ベストプラクティス:ポリシーごとに
metadata.annotations["gitCommit"]を付与し、どのコミットで変更されたかを可視化すると監査が楽になります。
istioctl authn tls-check の詳細出力例と活用方法
istioctl authn tls-check <service> は対象サービスへの TLS ハンドシェイク を実行し、成功・失敗の理由を詳しくレポートします。以下は典型的な 2 パターンです。
|
1 2 3 4 5 6 7 8 9 10 11 |
$ istioctl authn tls-check reviews.default.svc.cluster.local ✔ TLS connection to reviews.default.svc.cluster.local succeeded • Peer certificate SAN: spiffe://cluster.local/ns/default/sa/reviews • Mutual TLS mode: STRICT (PeerAuthentication enforced) ✖ TLS handshake failed for payments.default.svc.cluster.local • Error: x509: certificate signed by unknown authority • Detected PeerAuthentication: mode=PERMISSIVE (mTLS not mandatory) • Suggested fix: enable mTLS cluster‑wide via meshConfig.enableAutoMtls=true |
- 成功時:
✔に続く情報として、SAN(Service Account)、適用されたPeerAuthenticationのモードが表示されます。 - 失敗時:エラーメッセージに加えて、現在有効な
PeerAuthenticationの設定と推奨対策が示されるため、トラブルシュートが容易です。
CI/CD パイプライン例(GitHub Actions)
ポリシー変更を push しただけで自動的に GKE クラスタへ反映させる GitHub Actions のサンプルです。以下は実装上の重要ポイントとともに示します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
name: Deploy Istio Policies on: push: paths: - 'policies/**' jobs: deploy: runs-on: ubuntu-latest permissions: contents: read id-token: write # GCP の OIDC 用 steps: - uses: actions/checkout@v4 - name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: token_format: "access_token" workload_identity_provider: projects/${{ secrets.GCP_PROJECT_NUMBER }}/locations/global/workloadIdentityPools/github-pool/providers/github-provider service_account: ${{ secrets.GCP_SA_EMAIL }} - name: Get GKE credentials run: | gcloud container clusters get-credentials my-gke-cluster \ --region us-central1 - name: Apply Istio policies run: | kubectl apply -f policies/ |
- ポイント:GitHub の OIDC 連携で GCP サービスアカウントを安全に取得し、シークレット管理の負担を軽減しています。
- エラーハンドリング例(表形式):
| エラー | 想定原因 | 推奨対策 |
|---|---|---|
error: no matches for kind "AuthorizationPolicy" |
Istio CRD が未インストール | istioctl install --set profile=default で再インストール |
TLS handshake failed |
PeerAuthentication の mode が DISABLE |
meshConfig.enableAutoMtls=true に変更し再デプロイ |
kubectl apply -f policies/ 後にリソースが見つからない |
Namespace が誤っている | metadata.namespace を正しく設定、kubectl get <kind> -A で確認 |
今すぐ始めるためのリソースと次のステップ
本稿の内容を実際に手を動かして体感するためのリファレンスです。以下のリストは 公式ドキュメント と 信頼できる外部記事 を併せて掲載し、リンク先・公開日も明記しています。
| リソース | 内容 | URL | 公開日 |
|---|---|---|---|
| Istio Security Best Practices (公式) | mTLS, RBAC, JWT の全体像とベストプラクティス | https://istio.io/latest/docs/ops/best-practices/security/ | 2024‑10‑01 |
| GKE Sandbox – 無料トライアル | 30 日間無料で GKE クラスタを作成し、Istio を試す環境 | https://cloud.google.com/kubernetes-engine/docs/tutorials/sandbox | 2025‑02‑15 |
| GitHub – istio-security-policy-sample | PeerAuthentication, RequestAuthentication, AuthorizationPolicy のサンプル集 |
https://github.com/example/istio-security-policy-sample | 2026‑03‑20 |
| ZOZO TECH BLOG 「Istioで実現するマイクロサービスの共通認可基盤」 | 実務で使える AuthorizationPolicy パターン解説 | https://tech.zozo.com/istio-authz | 2025‑12‑08 |
| アプリの達人「Istio Security Best Practices: mTLS, RBAC, & Zero Trust」 | 最新(2026 年版)Zero‑Trust 実装ガイド | https://apps-master.com/blog/istio-security-2026 | 2026‑05‑31 |
手順サマリー
- GKE Sandbox を作成し、
istioctl install --set meshConfig.enableAutoMtls=trueで mTLS 自動有効化。 - サンプルリポジトリから
policies/ディレクトリをクローンし、kubectl apply -f policies/で RBAC と JWT 認証をデプロイ。 istioctl authn tls-check <service>を実行して TLS 接続が成功 したことを確認。失敗した場合はエラーメッセージに従いPeerAuthenticationの mode を修正。- GitHub Actions(上記サンプル)を自分のリポジトリに追加し、プッシュごとに自動デプロイが走ることを検証。
これらのステップを踏むだけで、GKE 上の Istio 環境に Zero‑Trust の基盤が構築でき、継続的なポリシーマネジメント体制も整います。実務プロジェクトへすぐに適用し、セキュリティインシデントのリスク低減を図りましょう。