すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:gRPC プロトコルを使用したカスタム権限付与の実装

最終更新日:Mar 11, 2026

メッシュ内のサービスが通信する場合、単純な許可/拒否ルールを超えた権限付与ロジック (カスタムヘッダーのチェック、トークンの検証、ビジネス固有のポリシーの適用など) が必要になることがよくあります。Alibaba Cloud Service Mesh (ASM) は、Envoy ext_authz フィルターを介したカスタム権限付与をサポートしており、ワークロードに到達する前にすべてのリクエストを評価する外部 gRPC サービスをデプロイできます。

このチュートリアルでは、サンプル gRPC 権限付与サービスをデプロイし、ASM に登録し、権限付与ポリシーを作成し、承認されたリクエストのみが通過することを確認する手順を説明します。

仕組み

カスタム権限付与によって保護されたサービスにリクエストが到着すると、次のようになります。

  1. サイドカープロキシはリクエストをインターセプトし、gRPC を介して外部権限付与サービスに権限付与チェックを送信します。

  2. 権限付与サービスは、リクエスト属性 (ヘッダー、パス、本文) をポリシーロジックと照合して評価します。

  3. 権限付与サービスがリクエストを承認した場合、プロキシはそれをターゲットサービスに転送します。そうでない場合、プロキシはリクエストを直ちに拒否します。

このアーキテクチャは、権限付与ロジックをアプリケーションコードから分離し、メッシュ内のすべてのサービスで一貫したアクセス制御を可能にします。

前提条件

開始する前に、以下があることを確認してください。

カスタム権限付与サービスのデプロイ

ACK クラスターに外部権限付与サービスをデプロイします。このサービスは、カスタム権限付与に関する Istio の API 仕様に準拠し、HTTP および gRPC プロトコルの両方をサポートする必要があります。

説明

サンプル権限付与サービスは、x-ext-authz: allow ヘッダーを含むリクエストのみを承認します。独自の権限付与ロジックを構築するには、GitHub のソースコードをご参照ください。

  1. ext-authz.yaml という名前のファイルを次の内容で作成します。

    ext-authz.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    # Example configurations for deploying ext-authz server separately in the mesh.
    
    apiVersion: v1
    kind: Service
    metadata:
      name: ext-authz
      labels:
        app: ext-authz
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 8000
      - name: grpc
        port: 9000
        targetPort: 9000
      selector:
        app: ext-authz
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ext-authz
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ext-authz
      template:
        metadata:
          labels:
            app: ext-authz
        spec:
          containers:
          - image: istio/ext-authz:0.6
            imagePullPolicy: IfNotPresent
            name: ext-authz
            ports:
            - containerPort: 8000
            - containerPort: 9000

    マニフェストは、istio/ext-authz:0.6 イメージを実行する Deployment と、ポート 8000 で HTTP を、ポート 9000 で gRPC を公開する Service を作成します。

  2. サービスをデプロイします。

    kubectl apply -f ext-authz.yaml

    期待される出力:

    service/ext-authz created
    deployment.apps/ext-authz created
  3. 権限付与サービスが正常に開始されたことを確認します。

    kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz

    期待される出力:

    2023/12/20 08:15:39 Starting gRPC server at [::]:9000
    2023/12/20 08:15:39 Starting HTTP server at [::]:8000

    gRPC サーバーと HTTP サーバーの両方が実行されている必要があります。

  4. ext-authz サービスの gRPC ポート (この例では 9000) をメモします。コンソールで確認するには、次の手順を実行します。

    1. ACK コンソール」にログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。

    2. [クラスター] ページで、目的のクラスターを見つけ、その名前をクリックします。 左側のペインで、[ネットワーク] > [サービス] を選択します。

    3. [サービス] ページで [ext-authz] をクリックすると、[エンドポイント] セクションに gRPC ポートが表示されます。

サンプルアプリケーションのデプロイ

httpbin および sleep アプリケーションをデプロイします。httpbin は権限付与を必要とするターゲットサービスとして機能し、sleep はテストリクエストを送信するクライアントとして機能します。

  1. httpbin.yaml という名前のファイルを次の内容で作成します。

    httpbin.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # httpbin service
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: httpbin
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
        service: httpbin
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 80
      selector:
        app: httpbin
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpbin
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpbin
          version: v1
      template:
        metadata:
          labels:
            app: httpbin
            version: v1
        spec:
          serviceAccountName: httpbin
          containers:
          - image: docker.io/kennethreitz/httpbin
            imagePullPolicy: IfNotPresent
            name: httpbin
            ports:
            - containerPort: 80
  2. httpbin アプリケーションをデプロイします。

    kubectl apply -f httpbin.yaml
  3. sleep.yaml という名前のファイルを次の内容で作成します。

    sleep.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # Sleep service
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: curlimages/curl
            command: ["/bin/sleep", "3650d"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
  4. sleep アプリケーションをデプロイします。

    kubectl apply -f sleep.yaml

ASM での権限付与サービスの登録

メッシュが gRPC を介して権限付与リクエストをルーティングできるように、ext-authz サービスを ASM インスタンスに登録します。

  1. ASM コンソールにログインします。左側のナビゲーションウィンドウで、[Service Mesh] > [メッシュ管理] を選択します。

  2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、[メッシュセキュリティセンター] > [カスタム承認サービス] を選択します。[カスタム承認サービスの定義] をクリックします。

  3. [カスタム権限付与サービスの登録] ページで、[envoy.ext_authz に基づいて実装されたカスタム権限付与サービス (HTTP または GRPC プロトコル)] タブをクリックし、次の表の説明に従ってパラメーターを設定し、次に [作成] をクリックします。

    必須パラメーター

    パラメーター説明
    プロトコル権限付与サービスで使用されるプロトコルです。GRPC
    名前権限付与サービス登録の名前です。test
    サービスアドレスエンドポイントは、<Service name>.<Namespace>.svc.<Cluster domain> のフォーマットで指定します。ext-authz.default.svc.cluster.local
    ポート (1 - 65535)権限付与サービスの gRPC ポートです。9000
    タイムアウト (秒)権限付与応答を待機する最大秒数です。この期間内にサービスが応答しない場合、サービスは利用不可とみなされます。10

    オプションパラメーター

    パラメーター説明
    権限付与サービスが利用できない場合の認証スキップ有効にすると、権限付与サービスに到達不能な場合でもリクエストを許可します。無効にすると、リクエストは拒否されます。
    Auth-Service が利用できない場合に ASM プロキシが返すエラーコード権限付与サービスが利用できない場合に呼び出し元に返される HTTP エラーコードです。権限付与サービスが利用できない場合の認証スキップが無効になっている場合にのみ利用可能です。
    認可リクエストへのオリジンリクエストボディの付加有効にすると、認可リクエストにリクエストボディが含まれます。最大ボディ長を指定してください。不完全なメッセージを Auth-Service へ送信することを許可も有効になっている場合、最大長を超えるボディは転送前に切り捨てられます。

権限付与ポリシーの作成

権限付与が必要なリクエストを定義するには、一致するリクエストを ext-authz サービスを経由してルーティングする権限付与ポリシーを作成します。

  1. ASM コンソール にログインします。左側のナビゲーションウィンドウで、Service Mesh > Mesh Management を選択します。

  2. Mesh Management ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションウィンドウで、Mesh Security Center > AuthorizationPolicy を選択し、[作成] をクリックします。

  3. [作成] ページで、以下の表に示すパラメーターを設定し、その後 [作成] をクリックします。

    パラメーター説明例の値
    [名前]権限付与ポリシーの名前です。test1
    ポリシータイプポリシーの種類です。[カスタム権限付与サービス] を選択すると、前のステップで登録した ext-authz サービスが使用されます。カスタム認可サービス
    カスタム承認サービス登録済みの権限付与サービスです。grpcextauth-test(GRPC)
    [名前空間]ポリシーが適用される名前空間です。[ワークロード範囲] タブで設定します。default
    [適用範囲]ポリシーが特定のサービスに適用されるか、または名前空間全体に適用されるかを指定します。サービス
    ワークロード保護対象のワークロードです。httpbin
    [リクエスト一致ルール]権限付与をトリガーするリクエストパスです。[リクエストターゲットの追加] セクションで、[パス] を有効化し、パスを指定します。/headers

    この構成により、/headers パスへの httpbin サービスに対するリクエストのみが、権限付与サービスへ送信され評価されます。他のパスへのリクエストは権限付与をバイパスします。

権限付与設定の検証

権限付与ポリシーが期待どおりに機能することを確認するために、3 つのテストを実行します。

テスト 1: 権限付与なしのパスへのリクエスト

権限付与ポリシーの対象外である /ip へのリクエストを送信します。

kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/ip" -s -o /dev/null -w "%{http_code}\n"

期待される出力: 200

/ip パスが権限付与ポリシーと一致しないため、リクエストは成功します。

テスト 2: 権限付与サービスによって拒否されたリクエスト

ヘッダー x-ext-authz: deny を付けて /headers へのリクエストを送信します。

kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: deny" -s

期待される出力:

denied by ext_authz for not found header `x-ext-authz: allow` in the request

必要な x-ext-authz: allow ヘッダーがないため、権限付与サービスはリクエストを拒否します。

テスト 3: 権限付与サービスによって承認されたリクエスト

ヘッダー x-ext-authz: allow を付けて /headers へのリクエストを送信します。

kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: allow" -s

期待される出力:

{
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.default:8000",
    "User-Agent": "curl/8.5.0",
    "X-Envoy-Attempt-Count": "1",
    "X-Ext-Authz": "allow",
    "X-Ext-Authz-Check-Result": "allowed",
    "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=c3e5364e87add0f4f69e6b0d029f5961b404c8f209bf9004b3d21a82cf67****;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
  }
}

X-Ext-Authz-Check-Result: allowed ヘッダーは、権限付与サービスがリクエストを承認したことを確認します。応答には、クライアント (sleep) とサーバー (httpbin) の両方の SPIFFE ID も含まれており、サービス間の Mutual TLS を検証します。

これら 3 つのテストにより、以下が確認されます。

  • 保護されていないパスへのリクエストは、権限付与チェックなしで通過します。

  • 必要なヘッダーがない保護されたパスへのリクエストは拒否されます。

  • 正しいヘッダーがある保護されたパスへのリクエストは承認されます。

本番環境での考慮事項

本番環境でカスタム権限付与をデプロイする際は、次の点に留意してください。

項目推奨事項
障害モード権限付与サービスが利用できない場合にリクエストを許可するか拒否するかを決定します。リクエストを許可する (フェイルオープン) と可用性は維持されますが、セキュリティは低下します。リクエストを拒否する (フェイルクローズ) とより安全ですが、権限付与サービスが停止した場合に停止を引き起こす可能性があります。
タイムアウト権限付与サービスのレスポンスレイテンシーに基づいてタイムアウト値を設定します。値が低すぎると誤った拒否が発生し、高すぎるとリクエストレイテンシーが増加します。
高可用性権限付与サービスの複数のレプリカを実行し、適切なリソースリクエストと制限を構成します。
スコープパフォーマンスオーバーヘッドを最小限に抑えるために、権限付与ポリシーを名前空間全体ではなく、特定のパスとワークロードに適用します。
監視権限付与サービスのログとレイテンシーを監視して、トラフィックに影響を与える前に問題を検出します。

クリーンアップ

このチュートリアルで作成したリソースを削除します。

kubectl delete -f ext-authz.yaml
kubectl delete -f httpbin.yaml
kubectl delete -f sleep.yaml

ASM コンソールから権限付与ポリシーとカスタム権限付与サービス登録を削除します。

  1. ASM コンソールで、[メッシュ セキュリティセンター] > [AuthorizationPolicy] を選択します。test1 ポリシーを削除します。

  2. [メッシュセキュリティセンター] > [カスタム権限付与サービス] を選択します。test 権限付与サービスを削除します。

関連ドキュメント