Service Mesh (ASM) は、アプリケーションコードから身分認証および権限付与機能を切り離し、メッシュインフラストラクチャに移行することで、クラウドネイティブアプリケーションに対してゼロトラストセキュリティを適用します。ASM を通じてセキュリティポリシーを定義し、いつでも更新して即座に有効化できます。アプリケーションを再デプロイする必要はありません。
マイクロサービスにおけるゼロトラストの重要性
マイクロサービスは、優れた拡張性、俊敏性、個別のスケーリング、ビジネスロジックの隔離、独立したライフサイクル管理、分散開発の容易さといったメリットを提供しますが、同時に攻撃対象領域も拡大します。各サービスが潜在的なターゲットとなります。Kubernetes はマイクロサービスをホストおよびオーケストレーションするための優れたプラットフォームですが、デフォルトでは Kubernetes クラスター内のサービス間通信はプレーンテキスト HTTP で行われます。境界ベースのセキュリティだけでは、この内部トラフィックを保護できません。攻撃者がいずれかのサービスを侵害した場合、ネットワーク上の他の任意のサービスへ横方向に移動することが可能になります。
ゼロトラストは、すべてのリクエストに対して明示的な認証を要求し、すべてのアクセスに対して最小権限の原則を適用することで、この課題に対処します。レイヤー 3 でトラフィックを制御する Kubernetes ネットワークポリシーに加え、ASM はピア認証、リクエスト認証、権限付与ポリシー、および Open Policy Agent (OPA) ベースのきめ細かなアクセス制御をより上位のレイヤーで提供します。
ASM によるゼロトラストの実装
ASM は、アプリケーションコードを変更することなくマイクロサービスを保護します。ゼロトラストシステムには次の 4 つの柱があります。
| 柱 | 機能 |
|---|---|
| ワークロード ID | 各ワークロードに一意で SPIFFE 準拠の ID を割り当てます。この ID は、すべての認証および権限付与判断の基盤となります。 |
| 証明書管理 | ワークロード ID を埋め込んだ TLS X.509 証明書を発行し、証明書および秘密鍵を自動的にローテーションします。すべてのサイドカープロキシはこれらの証明書を使用します。 |
| ポリシー実施 | Istio のロールベースアクセス制御 (RBAC) ポリシーおよび OPA ベースのきめ細かな権限付与ポリシーをサポートします。 |
| 可観測性 | ポリシー実行に関するログおよびメトリックを収集し、各ポリシーの有効性を分析できます。 |

アプリケーションレベルのセキュリティとの比較における利点
アプリケーションコード内にセキュリティを実装する方法と比較して、ASM には以下の利点があります。
| 利点 | 説明 |
|---|---|
| 独立したライフサイクル管理 | サイドカープロキシはアプリケーションとは別に管理されます。コードを再デプロイせずにセキュリティポリシーを更新できます。 |
| 即時のポリシー適用 | ポリシーを設定または更新すると、即座に有効になります。 |
| 一元的なセキュリティガバナンス | 単一のコントロールプレーンにより、セキュリティチームがエンタープライズ全体のポリシーを構築・管理・デプロイできます。開発者が各サービスにセキュリティロジックを実装する必要はありません。 |
| 組み込みの認証情報検証 | ASM は JSON Web トークン (JWT) 認証をサポートし、リクエスト内のユーザー認証情報を検証します。 |
| 多層防御 | 身分認証および権限付与を ASM インスタンス内のサービスとしてデプロイします。これらのサービスは ASM の保護(転送中暗号化、身分認証、ポリシー実施、認証情報検証)の恩恵を受けます。 |
ASM は、厳格な ID およびアクセス管理、トランスポート層セキュリティ (TLS) 暗号化、認証、権限付与、監査ログを、すべて標準機能として提供します。
セキュリティ機能
ASM は、エンドツーエンドの暗号化、サービスレベルの身分認証、およびきめ細かな権限付与ポリシーを通じて、サービス間通信を保護します。
ワークロード ID
ASM は、メッシュ内で実行中の各マイクロサービスに一意の識別子を割り当てます。サービスはこの識別子を相互認証および権限付与判断に使用します。
Kubernetes クラスター内のワークロードを管理する際、ASM はワークロードのサービストークンに基づいてサービス ID を割り当てます。サービス ID は Secure Production Identity Framework for Everyone (SPIFFE) に準拠しており、次の形式を使用します。
spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>コンソールでのワークロード ID の確認
ASM コンソールにログインします。左側のナビゲーションウィンドウで、Service Mesh > Mesh Management を選択します。
Mesh Management ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、Mesh Security Center > ワークロード ID を選択します。
ワークロード ID ページで、データプレーン ドロップダウンリストからクラスターを、名前空間 ドロップダウンリストから名前空間を選択し、ワークロード ID を表示します。
ピア認証
ピア認証は、相互 TLS (mTLS) またはサーバー側 TLS 認証を使用して、サービス間インタラクションの両方の側の ID を検証します。証明書の自動ローテーションなどの証明書ライフサイクル管理もサポートされています。動作は、どのサービスにサイドカープロキシが注入されているかによって異なります。
| サイドカー注入 | 動作 |
|---|---|
| クライアントおよびサーバーの両方 | すべての通信に対して mTLS 暗号化が有効になります。 |
| クライアントのみ | クライアントはサーバーの構成に基づいて mTLS を有効にします。 |
| サーバーのみ | デフォルトの mTLS モードは permissive です。サーバーはプレーンテキストおよび暗号化トラフィックの両方を受け入れます。strict モードに設定した場合、サイドカープロキシを持たないクライアントからのリクエストは失敗します。 |
リクエスト認証
リクエスト認証は、JWT を使用してエンドユーザーまたはシステムの認証情報を検証します。リクエスト認証ポリシーがサービスに適用されると、次のようになります。
有効な JWT を含むリクエストは許可されます。
無効な JWT を含むリクエストは拒否されます (HTTP 403)。
JWT を含まないリクエストは、デフォルトで許可されます。
すべてのリクエストに対して有効な JWT を必須とするには、リクエスト認証ポリシーと権限付与ポリシーを組み合わせてください。これにより、無効な JWT を含むリクエストおよび JWT を含まないリクエストがブロックされます。
例:サービスに対する JWT 認証の設定
この例では、Bookinfo サンプルアプリケーションをターゲットサービスとして使用し、sleep Pod をクライアントとして使用します。
前提条件
Bookinfo アプリケーションをデプロイします。詳細については、「ASM インスタンスへのアプリケーションのデプロイ」をご参照ください。
手順 1:sleep クライアントのデプロイ
次の内容で
sleep.yamlファイルを作成します。kubectl を使用して Container Service for Kubernetes (ACK) クラスターに接続し、sleep アプリケーションをデプロイします。
kubectl apply -f sleep.yaml -n default
手順 2:リクエスト認証ポリシーの作成
ASM コンソールにログインします。左側のナビゲーションウィンドウで、Service Mesh > Mesh Management を選択します。
Mesh Management ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、Mesh Security Center > RequestAuthentication を選択し、作成 をクリックします。
次のパラメーターを使用して
detailsワークロード向けの JWT ルールを定義し、作成 をクリックします。主なパラメーター:JWKS 値:詳細については、jwks.json をご参照ください。パラメーター 値 説明 issuer testing@asm.istio.ioJWT の発行者。 audiences (空白) すべてのサービスがこの JWT を使用できるようにするには、空白のままにしてください。 jwks 下記参照 JWT 署名を検証するために使用される JSON Web Key Set。 { "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"}]}
手順 3:ポリシーの検証
JWT ツールを使用して JWKS を JWT 文字列にエンコードします。期待される結果:
eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg有効な JWT を含むリクエストを送信します。期待される出力:
200。有効な JWT が受理されました。export TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep \ -- curl http://details:9080/details/1 -o /dev/null \ --header "Authorization: Bearer $TOKEN" -s -w '%{http_code}\n'無効な JWT を含むリクエストを送信します。期待される出力:
403。無効なトークンが拒否されました。kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep \ -- curl http://details:9080/details/1 -o /dev/null \ --header "Authorization: Bearer badtoken" -s -w '%{http_code}\n'JWT を含まないリクエストを送信します。期待される出力:
200。JWT がない場合、リクエストは JWT 検証をバイパスし、許可されます。kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep \ -- curl http://details:9080/details/1 -o /dev/null -s -w '%{http_code}\n'
これらの結果により、ポリシーが期待通りに動作していることが確認できました。有効な JWT は通過し、無効な JWT は拒否され、JWT を含まないリクエストは権限付与ポリシーで制限されていない限り許可されます。
権限付与ポリシー
権限付与ポリシーは、送信元 ID、ポート、IP アドレス、JWT クレームなどの条件に基づいて、どのリクエストがサービスにアクセスできるかを制御します。リクエスト認証と権限付与ポリシーを組み合わせることで、認証済みのリクエストのみがサービスに到達するように強制できます。
権限付与ポリシーは次の 3 つの部分で構成されます。
| フィールド | 目的 |
|---|---|
selector | ポリシーの対象となるワークロードを指定します。 |
action | リクエストを ALLOW または DENY するかを指定します。 |
rules | from (リクエスト送信元)、to (リクエスト操作)、および when (追加条件) を含み、アクションをトリガーするタイミングを定義します。 |
例:すべてのリクエストに対して有効な JWT を必須とする
この例は、前述のリクエスト認証設定に基づいています。JWT が有効でないリクエストをブロックする権限付与ポリシーを追加します。
前提条件
Bookinfo アプリケーションをデプロイします。詳細については、「ASM インスタンスへのアプリケーションのデプロイ」をご参照ください。
前述のリクエスト認証セクションで説明されているとおり、sleep クライアントをデプロイします。
手順 1:権限付与ポリシーの作成
ASM コンソールにログインします。左側のナビゲーションウィンドウで、Service Mesh > Mesh Management を選択します。
Mesh Management ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、Mesh Security Center > AuthorizationPolicy を選択し、YAML から作成 をクリックします。
名前空間 ドロップダウンリストから default を選択し、次の YAML を貼り付けて、作成 をクリックします。このポリシーは、リクエストプリンシパルが
testing@secure.istio.io/testing@secure.istio.ioと一致する場合にのみ、detailsサービスへのリクエストを許可します。つまり、この ID によって発行された有効な JWT をリクエストが持っている必要があります。権限付与ポリシーのフィールドの詳細については、「Authorization Policy」をご参照ください。apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-jwt namespace: default spec: action: ALLOW rules: - from: - source: requestPrincipals: - testing@secure.istio.io/testing@secure.istio.io selector: matchLabels: app: details
手順 2:ポリシーの検証
JWT を含まないリクエストを送信します。
kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep \
-- curl http://details:9080/details/1 -o /dev/null -s -w '%{http_code}\n'期待される出力:403。権限付与ポリシーにより、testing@secure.istio.io から発行された有効な JWT を含まないリクエストがブロックされます。
OPA ポリシー
Open Policy Agent (OPA) は、きめ細かなアクセス制御のための汎用ポリシーエンジンです。OPA はマイクロサービスとともに実行され、リクエストが処理される前に各リクエストをポリシーに対して評価します。
ASM は OPA と統合されているため、サービスを再デプロイせずにきめ細かなアクセス制御ポリシーを定義および動的に更新できます。詳細については、「ASM での OPA ポリシーの動的更新」をご参照ください。
OPA の詳細については、Open Policy Agent ウェブサイトをご覧ください。
アーキテクチャコンポーネント
ASM のゼロトラストアーキテクチャは、連携して動作する次の 4 つのコンポーネントで構成されます。
| コンポーネント | 役割 |
|---|---|
| 証明機関 | CA 証明書の発行およびローテーションなど、証明書のライフサイクル全体を管理します。 |
| コントロールプレーン API | 認証ポリシー、権限付与ポリシー、およびセキュアな名前解決情報を Envoy サイドカープロキシに配信します。 |
| サイドカープロキシ | 各サービスの出入りするすべてのトラフィックを保護するポリシー実施ポイント (PEP) として機能します。 |
| Envoy 拡張 | 監査およびモニタリング用のテレメトリデータを収集します。 |
各ワークロードは、その ID をエンコードした TLS X.509 証明書を受信します。ASM はこれらの証明書および秘密鍵を定期的に自動ローテーションします。秘密鍵が漏洩した場合は、攻撃対象領域を最小限に抑えるために、ASM が即座に置き換えます。
ユースケース例
イングレスゲートウェイでの IP ベースのアクセス制御。 イングレスゲートウェイに権限付与ポリシーを追加して、送信元 IP アドレスに基づいてトラフィックを許可または拒否するか、カスタムの外部認可サービスを統合します。
金融アプリケーション向けのクロスリージョンアクセス制御。 権限付与ポリシーを使用して、外部ネットワークからのクロスリージョンマルチ言語アプリケーションを保護します。エグレスゲートウェイ経由でエグレストラフィックを監査し、アプリケーションがどのサードパーティサービスにアクセスできるかを制御します。