Cloud Service Mesh のユーザー認証の構成
TRAFFIC_DIRECTOR
コントロール プレーンを実装している場合、この機能は許可リストによってのみサポートされます。この機能を組織の許可リストに登録するようリクエストするには、サポートにお問い合わせください。
Cloud Service Mesh のユーザー認証は、デプロイされたワークロードへのブラウザベースのエンドユーザー認証とアクセス制御のための統合ソリューションです。このソリューションにより、ユーザー認証の既存の ID プロバイダ(IDP)と統合できます。アクセス管理には、Istio API と認可ポリシーが使用されます。これは、Istio JSON Web Token(JWT)認証に代わる、ユーザー フレンドリーな代替手段です。
代表的な使用例は、従業員がウェブブラウザからアクセスできるように、組織が Cloud Service Mesh を使用してウェブ アプリケーションをホストする場合です。また、組織では既存の ID プロバイダを使用してユーザー ID を管理する必要があります。Cloud Service Mesh のユーザー認証では、ユーザーは標準のウェブベースの OpenID Connect(OIDC)ログインと同意フローを使用して簡単に認証できます。ユーザーが認証されると、Cloud Service Mesh によって Istio の認可ポリシーが適用されます。認可が正常に完了すると、安全な認証情報形式で ID がワークロードに送信されます。
仕組み
Cloud Service Mesh のユーザー認証では、新しいコンポーネント authservice
が導入されています。このコンポーネントは、すべての受信認証リクエストをインターセプトする外部認可サービスとして Envoy ベースの Ingress と統合します。authservice
は OIDC プロトコルのクライアントサイドを実装し、ユーザーがブラウザからアプリケーションにアクセスできるようにします。この際、ユーザーはインタラクティブな認証および同意フローを完了して、有効期間の短いセッションを確立します。authservice
は、OIDC 認証サーバーとして機能できる ID プロバイダと統合するための業界標準プロトコルを実装します。ユーザーが認証されると、主要な情報は RCToken
に JWT 形式でカプセル化され、authservice
によって署名されてから Ingress の Istio 認証レイヤに転送されます。このモデルは、メッシュへのトラフィックの境界アクセス制御を提供します。ユーザーがリソースへのアクセスを承認されている場合は、この RCToken もマイクロサービスに転送されるため、主要な情報を取得してきめ細かいアクセス制御を行えます。
次の図は、メッシュ内の authservice
の場所と、Ingress、ワークロード、ユーザーのブラウザ、既存の IDP など、メッシュの他の部分との関連を示しています。
管理者は、Cloud Service Mesh インストール時にアドオンとして authservice
をインストールできます。authservice
をインストールすると、UserAuth
カスタム リソースで定義されている OIDC エンドポイント構成と他の関連設定が読み取られます。管理者は、Cloud Service Mesh の ExternalAuthorization
API を使用して、auth_server
を Ingress のフィルタとして構成できます。
ユーザー認証サービスをインストールする
次の手順では、authservice
の構成方法について説明します。
前提条件
依存ツールのインストールとクラスタの検証の手順に沿って、次の操作を行います。- プライベート クラスタでマネージド Cloud Service Mesh を使用している場合は、クラスタが IDP に Egress トラフィックを送信できることを確認します。
さらに、次の手順に沿って、前提条件を満たしていることを確認してください。
ユーザー認証オーバーレイを使用してインストールをカスタマイズする
ユーザー認証サービスをインストールするには、Cloud Service Mesh のインストールをカスタマイズして、メッシュレベルの外部認可プロバイダを追加する必要があります。必要な手順は、マネージド Cloud Service Mesh とクラスタ内の Cloud Service Mesh のどちらを使用しているかによって異なります。
マネージド
ユーザー認証 MeshConfig が含まれるように ConfigMap を更新します。次のコマンドでは、マネージド Cloud Service Mesh のプロビジョニングに使用したのと同じ
REVISION_LABEL
(asm-managed
、asm-managed-rapid
、asm-managed-stable
など)を使用します。kubectl edit configmap istio-REVISION_LABEL -n istio-system
MeshConfig の
mesh
フィールドに次のテキストを追加します。mesh: |- ... extensionProviders: - name: "asm-userauth-grpc" envoyExtAuthzGrpc: service: "authservice.asm-user-auth.svc.cluster.local" port: "10003"
asm-user-auth
Namespace を作成します。kubectl create namespace asm-user-auth
インジェクションの Namespace を有効にします。手順は、コントロール プレーンの実装によって異なります。
マネージド(TD)
デフォルトのインジェクション ラベルを Namespace に適用します。
kubectl label namespace asm-user-auth \ istio.io/rev- istio-injection=enabled --overwrite
マネージド(Istiod)
推奨: 次のコマンドを実行して、デフォルトのインジェクション ラベルを Namespace に適用します。
```sh kubectl label namespace asm-user-auth \ istio.io/rev- istio-injection=enabled --overwrite ```
マネージド Istiod コントロール プレーンを使用している既存のユーザーの場合: デフォルトのインジェクションを使用することをおすすめしますが、リビジョンベースのインジェクションもサポートされています。次の手順を行います。
- 次のコマンドを実行して、利用可能なリリース チャンネルを探します。
kubectl -n istio-system get controlplanerevision
出力は次のようになります。
NAME AGE asm-managed-rapid 6d7h
出力の
NAME
列の値は、Cloud Service Mesh バージョンで使用可能なリリース チャンネルに対応するリビジョン ラベルです。リビジョン ラベルを Namespace に適用します。
kubectl label namespace asm-user-auth \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite
asm-user-auth
Namespace に Istio ゲートウェイをインストールします。kubectl apply -n asm-user-auth -f DIR_PATH/samples/gateways/istio-ingressgateway
クラスタ内
サンプルのユーザー認証オーバーレイを取得し、メッシュにカスタマイズがある場合は更新します。このオーバーレイ ファイルをソース コントロール内で管理することをおすすめします。
curl https://raw.githubusercontent.com/GoogleCloudPlatform/asm-user-auth/v1.2.5/overlay/user-auth-overlay.yaml > user-auth-overlay.yaml
オーバーレイを使用して Cloud Service Mesh をインストールするに沿って、Google 提供のスクリプトを使用し、ユーザー認証オーバーレイを使用して Cloud Service Mesh をインストールします。例:
./asmcli install \ --project_id PROJECT_ID \ --cluster_name CLUSTER_NAME \ --cluster_location CLUSTER_LOCATION \ --fleet_id FLEET_PROJECT_ID \ --output_dir DIR_PATH \ --enable_all \ --custom_overlay user-auth-overlay.yaml
ユーザー認証の
kpt
パッケージがAuthorizationPolicy
を作成し、pkg/ext-authz.yaml
で指定された外部認可プロバイダを参照します。asm-user-auth
Namespace を作成します。kubectl create namespace asm-user-auth
インジェクションの名前空間を有効にします。
推奨: 次のコマンドを実行して、デフォルトのインジェクション ラベルを Namespace に適用します。
kubectl label namespace asm-user-auth \ istio.io/rev- istio-injection=enabled --overwrite
デフォルトのインジェクションを使用することをおすすめしますが、リビジョンベースのインジェクションもサポートされています。 次の手順で対応します。
次のコマンドを使用して、
istiod
のリビジョン ラベルを探します。kubectl get deploy -n istio-system -l app=istiod -o \ jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
リビジョン ラベルを Namespace に適用します。次のコマンドで、
REVISION_LABEL
は前の手順でメモしたistiod
リビジョン ラベルの値です。kubectl label namespace asm-user-auth \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite
asm-user-auth
Namespace に Istio ゲートウェイをインストールします。kubectl apply -n asm-user-auth -f DIR_PATH/samples/gateways/istio-ingressgateway
OIDC クライアントの構成を準備する
次の手順で OIDC クライアント構成を設定します。このガイドでは Google を IDP として使用しますが、OIDC 認証をサポートする任意の IDP を使用できます。
Google Cloud コンソールで、[API とサービス] > [認証情報] に移動します。
[認証情報を作成] に移動し、[OAuth クライアント ID] を選択します。必要に応じて、[OAuth 同意画面] オプションを設定し、次のオプションを構成します。
- [アプリケーションの種類] を [ウェブ アプリケーション] に設定します。
- [承認済みのリダイレクト URI] を
https://REDIRECT_HOST/REDIRECT_PATH
に設定します。たとえば、ローカルホストの場合、https://localhost:8443/_gcp_asm_authenticate
に設定できます。
最後に [保存] をクリックします。
さらに、後で使用するために OIDC クライアントの構成を保存します。
export OIDC_CLIENT_ID=CLIENT_ID export OIDC_CLIENT_SECRET=CLIENT_SECRET export OIDC_ISSUER_URI=ISSUER_URI export OIDC_REDIRECT_HOST=REDIRECT_HOST export OIDC_REDIRECT_PATH=REDIRECT_PATH
kpt
パッケージを入手する
公開リポジトリから推奨の authservice
構成をインストールするには、次の手順を行います。これらのコマンドは、最新の authservice
コンテナを取得し、asm-user-auth
名前空間の Pod として起動します。また、すべてのリクエストをインターセプトするように Ingress を構成します。
kpt パッケージを取得します。
kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth.git/@v1.2.5 .
cd asm-user-auth/
Ingress ゲートウェイのリダイレクト URL とシークレットを設定する
OAuth2
には、HTTPS で保護されたエンドポイントでホストされているリダイレクト URL が必要です。これらのコマンドはサンプル用途であり、Istio Ingress ゲートウェイの自己署名証明書を生成することで簡単に設定できます。
自己署名証明書を生成します。
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ -days 365 -nodes -subj '/CN=localhost'
HTTPS トラフィックをホストする Ingress ゲートウェイのシークレットを作成します。
kubectl create -n asm-user-auth secret tls userauth-tls-cert --key=key.pem \ --cert=cert.pem
暗号鍵と署名鍵を適用する
authservice
が正しく動作するには、2 つの鍵セットが必要です。1 つ目は、暗号化と復号の対称鍵です。この鍵は、セッションの状態を Cookie として設定する前に、セッションの暗号化に使用します。
2 つ目は、公開鍵/秘密鍵のペアです。この鍵は、RCToken として JWT 形式で認証されたユーザー情報に署名するために使用されます。このペアの公開鍵は、サイドカーが JWT の検証に使用できる事前定義されたエンドポイントで公開されます。
ユーザー認証の kpt
パッケージには、簡単に設定できるように 2 つのサンプルキーが含まれています。ただし、任意の鍵管理システムを使用して、これらの鍵を生成することもできます。
次の形式でセッション暗号鍵を準備します。または、
cat ./samples/cookie_encryption_key.json
で表示できる pkg のサンプルを使用します。{ "keys":[ { "kty":"oct", "kid":"key-0", "K":"YOUR_KEY", "useAfter": 1612813735 } ] }
次のコマンドを使用して、テスト AES 鍵を生成できます。
openssl enc -aes-256-cbc -k mycustomkey -P -md sha1 | grep key
次の形式で RCToken 署名鍵を準備します。または、
cat ./samples/rctoken_signing_key.json
で表示できる pkg のサンプルを使用します。{ "keys":[ { "kty":"RSA", "kid":"rsa-signing-key", "K":"YOUR_KEY", # k contains a Base64 encoded PEM format RSA signing key. "useAfter": 1612813735 # unix timestamp } ] }
次のコマンドを使用して、テスト 512 ビット RSA 秘密鍵を生成できます。
openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:512
authservice
が独自のファイル システムにマウントする Kubernetes Secret を作成します。kubectl create secret generic secret-key \ --from-file="session_cookie.key"="./samples/cookie_encryption_key.json" \ --from-file="rctoken.key"="./samples/rctoken_signing_key.json" \ --namespace=asm-user-auth
ユーザー認証サービスをデプロイする
次のコマンドは、ユーザー認証サービスとデプロイを asm-user-auth
名前空間に作成します。
ユーザー認証の構成に必要な値を設定します。クライアント ID とシークレットは Kubernetes Secret として保存されるため、Base64 を使用してエンコードします。使用可能なすべてのセッターを表示するには、公開リポジトリにアクセスしてください。
kpt fn eval pkg --image gcr.io/kpt-fn/apply-setters:v0.2 --truncate-output=false -- \
client-id="$(echo -n ${OIDC_CLIENT_ID} | base64 -w0)" \
client-secret="$(echo -n ${OIDC_CLIENT_SECRET} | base64 -w0)" \
issuer-uri="${OIDC_ISSUER_URI}" \
redirect-host="${OIDC_REDIRECT_HOST}" \
redirect-path="${OIDC_REDIRECT_PATH}"
kpt
パッケージを適用します。
# Remove the potential alpha version CRD if exists.
kubectl delete crd userauthconfigs.security.anthos.io
kubectl apply -f ./pkg/asm_user_auth_config_v1beta1.yaml
kubectl apply -f ./pkg
authservice
は UserAuthConfig
CRD を使用してエンドユーザー認証を行います。UserAuthConfig
は実行時に構成可能で、authservice
の動作を変更し、任意の OIDC 認証サーバーのエンドポイントで構成するように更新できます。
cat pkg/user_auth_config.yaml
でファイルを表示できます。これには次のフィールドが含まれます。
apiVersion: security.anthos.io/v1beta1
kind: UserAuthConfig
metadata:
name: user-auth-config
namespace: asm-user-auth
spec:
authentication:
oidc:
certificateAuthorityData: "" # kpt-set: ${ca-cert}
issuerURI: "<your issuer uri>" # kpt-set: ${issuer-uri}
proxy: "" # kpt-set: ${proxy}
oauthCredentialsSecret:
name: "oauth-secret" # kpt-set: ${secret-name}
namespace: "asm-user-auth" # kpt-set: ${secret-namespace}
redirectURIHost: "" # kpt-set: ${redirect-host}
redirectURIPath: "/_gcp_asm_authenticate" # kpt-set: ${redirect-path}
scopes: "" # kpt-set: ${scopes}
groupsClaim: "" # kpt-set: ${groups}
outputJWTAudience: "test_audience" # kpt-set: ${jwt-audience}
user_auth_config.yaml
フィールドの詳細については、ユーザー認証構成の詳細をご覧ください。
API リクエスト ID を構成する
API リクエスト ID は、Cloud Service Mesh ユーザー認証で API リクエストを識別するために使用される Common Expression Language(CEL)式のセットです。これらの ID を定義すると、Cloud Service Mesh ユーザー認証で、API リクエストの認証エラーを意味的に処理できます。
具体的には、API リクエストを識別する CEL 式を指定すると、Cloud Service Mesh ユーザー認証で、未承認の API リクエストが 401-Unauthorized ステータス コードで失敗します。これは、未認証の API リクエストに対してこのステータス コードを想定する CLI やサービス アカウントなどのクライアントで重要です。
API リクエスト ID がない場合は、Cloud Service Mesh ユーザー認証によって、すべて未認証リクエストが構成済みの OpenID Connect(OIDC)プロバイダにリダイレクトされ、302-Found ステータス コードが返されます。このリダイレクト動作は、失敗時に 401-Unauthorized を想定する API リクエストでは通常望ましくありません。
API リクエスト ID を定義するには、UserAuthConfig CR
に apiRequestIdentifier
セクションを追加します。これにより、複数の CEL 式を追加できます。複数の CEL 式が指定されている場合、少なくともそのうち 1 つに一致するリクエストが API リクエストとみなされます。
次の例は、ヘッダー example-api-header
を含むリクエスト、ホスト api.example.com
に送信されるリクエスト、/v1/api/
の下のパスをターゲットとするリクエストを API リクエストとして指定する方法を示しています。
apiVersion: security.anthos.io/v1beta1
kind: UserAuthConfig
metadata:
name: user-auth-config
namespace: asm-user-auth
spec:
authentication:
oidc:
certificateAuthorityData: "" # kpt-set: ${ca-cert}
issuerURI: "<your issuer uri>" # kpt-set: ${issuer-uri}
proxy: "" # kpt-set: ${proxy}
oauthCredentialsSecret:
name: "oauth-secret" # kpt-set: ${secret-name}
namespace: "asm-user-auth" # kpt-set: ${secret-namespace}
redirectURIHost: "" # kpt-set: ${redirect-host}
redirectURIPath: "/_gcp_asm_authenticate" # kpt-set: ${redirect-path}
scopes: "" # kpt-set: ${scopes}
groupsClaim: "" # kpt-set: ${groups}
outputJWTAudience: "test_audience" # kpt-set: ${jwt-audience}
apiRequestIdentifier:
name: "api-request-identifiers"
expressions:
- "'example-api-header' in http_request.headers"
- "http_request.host == api.example.com"
- "matches(http_request.path, '/v1/api/(.*)')"
# other expressions go here
Cloud Service Mesh ユーザー認証の CEL 式は、次のフィールドで構成できます。
http_request.headers
: HTTP リクエスト ヘッダーのマップ。キーは小文字の文字列で、値は文字列のベクトルです。CEL 式でこのフィールドを使用して、特定のヘッダーを含むリクエストを API リクエストとして指定します。
http_request.host
: リクエストされた HTTP URL ホスト(例:api.example.com
)。CEL 式でこのフィールドを使用して、特定のホストへのリクエストを API リクエストとして指定します。
http_request.path
: リクエストされた HTTP URL パス(例:/example-api-path
)。常に「/」で始まり、リクエスト URL のクエリ コンポーネントは含まれません。CEL 式でこのフィールドを使用して、特定のパスのリクエストを API リクエストとして指定します。
次のセクションでは、これらのフィールドの一部をチェックしてマッチングし、API リクエストであるリクエストを特定する方法について Cloud Service Mesh ユーザー認証に通知する CEL 式の例を示します。
式のサンプル
ヘッダー X-API-Key
を含むすべてのリクエストをマッチングします。
"'x-api-key' in http_request.headers"
ヘッダー X-API-Key
が特定の値に設定されているすべてのリクエストをマッチングします。
"'x-api-key' in http_request.headers && http_request.headers['x-api-key'].values == ['example-value ']"
ホスト api.example.com
へのすべてのリクエストをマッチングします。
"http_request.host == api.example.com"
パス /api/query
へのすべてのリクエストをマッチングします。
"http_request.path == /api/query"
/api/
の下のパスへのすべてのリクエストをマッチングします。
"matches(http_request.path, '/api/(.*)')"
インストール後のタスクを行う
前述のインストール手順が完了した後は、以下のタスクが必要になります。
アプリケーションのユーザー認証を有効にする
このセクションでは、例として httpbin
を使用して、ユーザー認証を有効にする方法について説明します。
Cloud Service Mesh ユーザー認証では、CUSTOM
タイプの認可ポリシーを使用して OIDC フローをトリガーします。
Istio ゲートウェイをインストールした後、それを構成し、上記で作成した TLS 証明書 userauth-tls-cert
を使用して HTTPS トラフィックを処理するようにします。インストールした pkg/gateway.yaml
の構成を以下に示します。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: userauth
namespace: asm-user-auth
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: userauth-tls-cert
---
# This ensures the OIDC endpoint has at least some route defined.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: userauth-oidc
namespace: asm-user-auth
spec:
gateways:
- userauth
hosts:
- '*'
http:
- match:
- uri:
prefix: /status
- uri:
prefix: "your-oidc-redirect-path"
name: user-auth-route
route:
- destination:
host: authservice
port:
number: 10004
デプロイで
istio-proxy
自動インジェクションを有効にするには、default
Namespace にラベルを付けます。kubectl label namespace default istio.io/rev=REVISION --overwrite
httpbin
をdefault
Namespace にデプロイします。kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml -n default
httpbin
を更新して、このゲートウェイを使用して HTTPS トラフィックを処理し、ポート転送を使用してローカルでアプリケーションにアクセスします。kubectl apply -f./samples/httpbin-route.yaml -n default kubectl port-forward service/istio-ingressgateway 8443:443 -n asm-user-auth
ポート 8443 の Ingress ゲートウェイが
localhost
に転送され、アプリケーションはローカルでアクセス可能になります。samples/rctoken-authz.yaml
をデプロイして RequestAuthentication と AuthorizationPolicy を有効にし、リクエストの RCToken を検証します。kubectl apply -f ./samples/rctoken-authz.yaml -n asm-user-auth
samples/rctoken-authz.yaml
の例:apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: require-rc-token spec: selector: matchLabels: istio: ingressgateway jwtRules: - issuer: "authservice.asm-user-auth.svc.cluster.local" audiences: - "test_audience" jwksUri: "http://authservice.asm-user-auth.svc.cluster.local:10004/_gcp_user_auth/jwks" fromHeaders: - name: X-ASM-RCTOKEN forwardOriginalToken: true --- apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-rc-token spec: selector: matchLabels: istio: ingressgateway action: ALLOW rules: - when: - key: request.auth.claims[iss] values: - authservice.asm-user-auth.svc.cluster.local - key: request.auth.claims[aud] values: - test_audience
ユーザー認証を確認する
httpbin
は 2 つのパスを提供します。/ip
は一般公開され、/headers
はエンドユーザーが構成済みの IDP を介してログインする必要があります。
https://localhost:8443/ip
にアクセスして、/ip
に直接アクセスできることを確認します。https://localhost:8443/headers
にアクセスして、OIDC ログインページが表示されることを確認します。ログイン後、[次へ] をクリックして、
/headers
ページにリダイレクトすることを確認します。
認証ポリシーを構成する
前の手順で構成を完了すると、各ユーザーはウェブベースの認証フローにリダイレクトされます。フローが完了すると、authservice
によって JWT 形式の RCToken
が生成されます。これを使用して、認証されたユーザー情報が転送されます。
Ingress で Istio の認証ポリシーを追加して、認証されたユーザーごとに認証チェックが行われるようにします。
kubectl apply -f ./samples/httpbin-authz.yaml -n asm-user-auth
httpbin-authz.yaml
ファイルは、Ingress ゲートウェイを構成して authservice が発行した RC トークンを検証し、JWT にオーディエンスや発行者などの目的のフィールドが含まれている場合にのみ承認します。次の認証ポリシーの例をご覧ください。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-rc-token spec: selector: matchLabels: istio: ingressgateway action: ALLOW rules: - to: - operation: paths: ["/ip"] - to: when: - key: request.auth.claims[iss] values: - authservice.asm-user-auth.svc.cluster.local - key: request.auth.claims[aud] values: - test_audience - key: request.auth.claims[sub] values: - allowed_user_sub_1 # Change this with the "sub" claim in the RC token. Wildcard '*' will match everything.
環境固有の設定を構成する
前のステップでは、簡単にセットアップするため、localhost
と自己署名 HTTPS 証明書を使用しました。本番環境用に使用する場合は、example.com
などの実際のドメインを使用します。
また、certificateAuthorityData
に目的のルート証明書コンテンツがあることを確認します。たとえば、IdP がシステムのルート証明書で信頼されている場合は空のままにできます。HTTPS 接続を終端する HTTPS プロキシがある場合は、プロキシのルート証明書に設定する必要があります。
鍵の管理とローテーションを行う
authservice
で使用されるキーのセットは 2 つあります。各鍵を個別にローテーションできます。ただし、鍵をローテーションする前に、ローテーションの仕組みを理解しておくことが重要です。
どちらの鍵も JSON 形式です。useAfter
フィールドには、鍵の使用が開始されると考えられる期間のタイムスタンプを指定します。鍵のローテーション中は、JSON に古い鍵と新しい鍵の両方を含める必要があります。たとえば、次の例では、new-key
はタイムスタンプ 1712813735
の後にのみ使用されます。
{
"keys":[
{
"kty":"RSA",
"kid":"old-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1612813735, # unix timestamp
}
{
"kty":"RSA",
"kid":"new-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1712813735, # unix timestamp
}
]
}
Cloud Service Mesh では、ブラウザの Cookie に保存されるセッション データを暗号化するために対称鍵を使用します。既存のセッションの有効性を確保するため、authservice
は鍵セット内のすべての鍵で復号を試みます。ローテーション時には、authservice
は新しいセッションの暗号化に新しい鍵を使用し、引き続き古い鍵による復号を試みます。
公開鍵/秘密鍵ペアは、RCToken
の署名に使用されます。公開鍵は、JWT 検証のために istiod
によってサイドカーに送信されます。authservice
が新しい秘密鍵を使用して RCToken
に署名する前に、サイドカーが新しい公開鍵を受け取ることが重要です。この目的を達成するため、authservice
は、鍵が追加された直後に公開鍵の公開を開始します。ただし、その鍵を使用して RCToken
に署名するまではかなりの時間待機します。
要約すると、鍵のローテーションを行うときは、次のことをおすすめします。
- 定期的に、または必要に応じて、鍵のローテーションを実行します。
- JSON 形式で、現在の鍵と新しい鍵の両方を指定します。新しい鍵は、将来のタイムスタンプに関連付ける必要があります。タイムスタンプは現在の時刻の少なくとも数時間前に指定することをおすすめします。
- 新しい鍵が使用された後でもサービスが正常であるかをモニタリングし確認します。新しい鍵が使用されてから 1 日以上待ってから、次の手順に進みます。
- JSON エントリから古い鍵を削除します。今後それらの鍵は不要です。
マルチクラスタ デプロイ
Cloud Service Mesh のユーザー認証では、マルチクラスタのデプロイをサポートしています。前記のように、各クラスタにユーザー認証をデプロイする必要があります。UserAuth カスタム リソース、OIDC クライアント シークレット、暗号鍵などのユーザー認証構成は、すべて各クラスタに複製する必要があります。
デフォルトでは、Ingress ゲートウェイはいずれかの authservice
インスタンスへの認証リクエストをロードバランシングします。宛先ルールを使用すると、同じクラスタ内の authservice
にリクエストを送信し、他のクラスタの authservice
にのみフェイル オーバーするように Ingress ゲートウェイを構成できます。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: authservice-fail-over
namespace: asm-user-auth
spec:
host: authservice.asm-user-auth.svc.cluster.local
trafficPolicy:
loadBalancer:
localityLbSetting:
enabled: true
failover:
- from: us-east
to: us-west
- from: us-west
to: us-east
他の構成と同様に、各クラスタで構成する必要があります。
カスタム クレームのマッピング
カスタム クレームのマッピングを構成するには、spec.authentication.oidc.attributeMapping
を構成して、元の ID プロバイダの IDToken からのマッピングを定義します。キーは RCToken のクレーム名になり、値は IDToken からクレームを解析する方法の CEL 式になります。assertion
を使用して IDToken を参照します。
例:
spec:
authentication:
oidc:
attributeMapping:
aud_copy: assertion.aud
decision: 'assertion.sub.startsWith("123") ? "success" : "fail"'
RCToken では、ネストされたクレーム attributes
に、構成したクレームが含まれています。
"attributes": {
"aud_copy": "foo.googleusercontent.com",
"decision": "success"
}
CEL 式が IDToken の値を解析できない場合、クレームは無視されます。認証フローが失敗することはありません。
ユーザー認証のアップグレード
ユーザー認証パッケージには、新しいユーザー認証バージョン用の更新されたバイナリが含まれているため、再度インストールします。
kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth.git/@v1.2.5 . cd asm-user-auth/
OIDC クライアントの構成を保存します。
export OIDC_CLIENT_ID=CLIENT_ID export OIDC_CLIENT_SECRET=CLIENT_SECRET export OIDC_ISSUER_URI=ISSUER_URI export OIDC_REDIRECT_HOST=REDIRECT_HOST export OIDC_REDIRECT_PATH=REDIRECT_PATH
ユーザー認証サービスをデプロイして、新しいバージョンにアップグレードします。
ユーザー認証構成の詳細
次の表に、CRD の各フィールドの説明を示します。
フィールド名 | 説明 |
---|---|
authentication.oidc |
このセクションには、OIDC エンドポイントの構成と、OIDC フローで使用されるパラメータが含まれます。 |
authentication.oidc.certificateAuthorityData |
これは、OIDC 認証サーバーまたは HTTPS プロキシのドメイン(存在する場合)の SSL ルート証明書です。 |
authentication.oidc.oauthCredentialsSecret |
Secret は、JSON ペイロードに OAuth2 OIDC の client_id と client_secret を含む Kubernetes Opaque タイプのシークレットを参照します。 |
authentication.oidc.issuerURI |
出力 RCToken の発行者として使用する URI。 |
authentication.oidc.proxy |
OIDC IDP へのプロキシ サーバー(該当する場合)。形式 http://user:[email protected]:8888. |
authentication.oidc.redirectURIHost |
OAuth 終了 URI に使用するホスト。空白のままにすると、ターゲット URL からのホストが使用され、リダイレクト URI が動的に構成されます。 この値は、より高いレベルのドメインでユーザー認証 SSO セッションが必要な場合に使用できます。たとえば、profile.example.com/ と admin.example.com/ の間で SSO を有効にするには、この値を example.com に設定します。これにより、すべてのサブドメイン間で共有されるユーザー認証セッションを example.com で確立できます。注: 同じメッシュから複数のドメイン(example1.com と example2.com)が提供されている場合、この機能は使用できないため、空白のままにすることをおすすめします。 |
authentication.oidc.redirectURIPath |
authservice が OAuth フローを終了するエンドポイントのパス。authentication.oidc.clientID の承認サーバーで、この URI パスとホストを承認済みのリダイレクト URI として登録する必要があります。また、この URI は、 authservice が有効になっている同じサービス メッシュと Ingress から提供される必要があります。 |
authentication.oidc.scopes |
認証リクエストでリクエストする必要がある OAuth スコープ。「openid」スコープに加えてリクエストされているアクセス権限を指定するために使用する識別子のカンマ区切りリスト。例: "groups,allatclaim"。 |
authentication.oidc.groupsClaim |
idtoken にグループ クレームが含まれている場合は、このフィールドを使用して名前を指定します。指定すると、サービスは、このリクエストのデータを出力 RCToken の groups クレームに渡します。このクレームには、文字列のカンマ区切りリストを含める必要があります。例: ["group1", "group2"] |
authentication.oidc.attributeMapping |
idtoken からの 1 つ以上のクレーム マッピングと CEL 式を含みます。すべてのクレームは assertion.X によって参照されます。assertion は元の IDToken を参照します(例: aud_copy: assertion.aud ) |
authentication.outputJWTAudience |
authservice によって生成された RCToken の対象デバイス。サイドカーは、この対象デバイス値に対して受信 RCToken を検証できます。 |
トラブルシューティング
IDP へのネットワーク アクセス。
考えられるログ:
error: TLS handshake failed.
。istio-proxy
に接続されているエフェメラル コンテナからcurl
を実行して、IDP 発行者 URI を呼び出して確認します。たとえば、Cloud Service Mesh ログの収集をご覧ください。接続できない場合は、クラスタのファイアウォール ルールまたは他のネットワーク構成を確認します。
ルート CA 証明書。
考えられるログ:
error: The server's TLS certificate did not match expectations.
またはerror: TLS handshake failed.
。certificateAuthorityData
が正しいルート CA 証明書を保持していることを確認します。HTTPS トラフィックを終了する HTTPS プロキシが存在しない場合は、IDP のルート CA 証明書を保持することになります。存在する場合は、代わりにプロキシを保持することになります。リダイレクト パスの構成。
考えられる動作: OIDC 認証フロー中に 404 エラーページが表示される。
ユーザー認証は、path 属性を使用せずに「Set-Cookie」ヘッダーを返します。デフォルトでは、ブラウザはリクエスト URL のディレクトリを Cookie パス(パスに関連する Cookie のスコープ)として使用します。そのため、意図している場合を除き、リダイレクト パスに「/」を含めないことをおすすめします。
サイドカーは jwksUri を取得できません。
シナリオによっては、サイドカーの制限により、jwksUri の取得が失敗することがあります。Namespace がワイルドカード(
./*
やistio-system/*
など)を使用して表されていない場合、これは機能しません。下り(外向き)サイドカーに Namespace を手動で追加する必要があります。
よくある質問
ユーザー認証を有効にした Cloud Service Mesh をアップグレードするにはどうすればよいですか。
Cloud Service Mesh のアップグレード プロセスに従って、コマンドラインで
--custom_overlay user-auth-overlay.yaml
をasmcli install
に追加してオーバーレイ ファイルを指定します。authservice
にはどれくらいのリソースをプロビジョニングすればよいですか。また、1 秒間に処理できるリクエスト数はどれくらいですか。デフォルトでは、
authservice
は 2.0 vCPU、256Mi メモリで構成されています。このような構成では、authservice
は 1 秒あたり 500 件のリクエストを処理できます。大量のリクエストを処理するには、CPU を追加する必要があります。CPU は、そのリクエストの処理能力にほぼ比例します。また、認証サービスの複数のレプリカを構成して、水平方向の拡張性を高めることもできます。