Istio によるマルチクラウド・アプリ
App Identity and Access Adapter を使用すると、すべての ID 管理を 1 カ所でまとめて行うことができます。
App Identity and Access Adapter は現在サポートされていません。
企業では複数のプロバイダーのクラウドを利用したり、オンプレミス・ソリューションとオフプレミス・ソリューションを組み合わせて利用したりするので、異機種混合のデプロイメント・モデルがあれば、既存のインフラストラクチャーを保持してベンダーのロックインを回避することができます。 このアダプターは、App ID などの OIDC 準拠の ID プロバイダーと連携するように構成できます。 このサービスにより、アダプターは、フロントエンド・アプリケーションおよびバックエンド・アプリケーションを含むすべての環境で認証ポリシーおよび許可ポリシーを制御することができます。 そのうえ、コードを変更したりアプリケーションを再デプロイしたりする必要が一切ありません。
App Identity and Access Adapter はどのように役立つのでしょうか? 詳細は、次のビデオをご覧ください。
マルチクラウド・アーキテクチャー
マルチクラウド・コンピューティング環境とは、複数のクラウドやプライベート・コンピューティングの環境を単一のネットワーク・アーキテクチャーに組み合わせたものです。 複数の環境にワークロードを分散させることで、耐障害性、柔軟性、およびコスト効率を高めることができます。 これらのメリットを実現するために、Kubernetes などのオーケストレーション層を備えたコンテナー・ベースのアプリケーションを使用することが一般的です。
Istio およびこのアダプターについて
Istio は、Kubernetes と統合できる既存の分散アプリケーションの上層に透過的に構成されるオープン・ソースのサービス・メッシュです。 デプロイメントの複雑さを緩和するために、Istio は、サービス・メッシュ全体の動作に関する洞察を提供し、操作を制御できるようにします。 App ID を Istio を組み合わせると、カスタム・アプリケーションのコード変更を必要としない、マルチクラウド・アーキテクチャー対応のスケーラブルな統合 ID ソリューションになります。 詳しくは Istioとはをご覧ください。
Istio は Envoy プロキシーのサイドカーを使用して、サービス・メッシュ内のすべてのサービスのインバウンドとアウトバウンドのすべてのトラフィックを仲介します。 プロキシーを使用して、Istio はトラフィックに関する情報 (テレメトリー) を抽出します。テレメトリーは、ポリシー決定を適用するために、Mixer という Istio コンポーネントに送信されます。 App Identity and Access Adapter は、このテレメトリー (属性) をカスタム・ポリシーに照らして分析し、サービス・メッシュ全体の ID およびアクセス管理を制御することで Mixer 機能を拡張します。 アクセス管理ポリシーは特定の Kubernetes サービスにリンクされ、特定のサービス・エンドポイントに合わせて微調整することができます。 ポリシーとテレメトリの詳細については、 Istioのドキュメントを参照。
Istio の制限により、現在、App Identity and Access Adapter はユーザー・セッション情報を内部に保管します。複数のレプリカやフェイルオーバー構成でその情報を保持することはありません。 この制限が解消されるまで、このアダプターを使用する場合は、ワークロードを単一のレプリカに限定してください。
フロントエンド・アプリの保護
ブラウザベースのアプリケーションを使用している場合、 Open ID Connect(OIDC) / OAuth 2.0 authorization_grant
フローを使用してユーザーを認証することができます。 認証されていないユーザーは、検出されると自動的に認証ページにリダイレクトされます。
認証が完了すると、ブラウザーは、アダプターが要求をインターセプトする暗黙の /oidc/callback
エンドポイントにリダイレクトされます。 この時点で、アダプターは ID プロバイダーからトークンを取得し、最初にユーザーから要求された URL にユーザーをリダイレクトします。
セッション・トークンなどのユーザー・セッション情報は、Authorization
ヘッダーで確認できます。
Authorization: Bearer <accessToken> <IDToken>
認証済みユーザーをログアウトさせることもできます。 認証済みエンド・ユーザーは、oidc/logout
が付加された保護エンドポイントにアクセスするとログアウトされます。
https://myhost/path/oidc/logout
必要な場合は、リフレッシュ・トークンを使用して、ユーザーの再認証なしで新規アクセス・トークンおよび ID トークンを自動的に取得することができます。 構成した ID プロバイダーがリフレッシュ・トークンを返す場合は、そのトークンがセッション内に保持され、ID トークンの有効期限が切れたときに新規トークンを取得するために使用されます。
バックエンド・アプリの保護
このアダプタは、OAuth 2.0 JWT Bearer フローと連携して使用することで、JWT Bearer トークンを検証し、サービス API を保護することができます。 ベアラー許可フローでは、有効なアクセス・トークンとオプションの ID トークンを指定した許可ヘッダーが要求に含まれていなければなりません。
予期されるヘッダー構造は Authorization=Bearer {access_token} [{id_token}]
です。 認証されていないクライアントには、HTTP 401 応答ステータスと一緒に、許可を取得するために必要な範囲のリストが返されます。 トークンが無効または期限切れの場合、API 戦略は HTTP 401 応答と一緒に Www-Authenticate=Bearer scope="{scope}" error="{error}"
というオプションのエラー・コンポーネントを返します。
トークンおよびその使用方法について詳しくは、トークンについてを参照してください。
開始前に
開始する前に、以下の前提条件がインストールされていることを確認してください。
-
現在、IBM Cloud Kubernetes Service Managed Istio では、ポリシーの適用をサポートしていません。 このアダプターを使用するには、手動でインストールした Istio を使用する必要があります。
アダプターのインストール
チャートをインストールするために、クラスター内で Helm を初期化し、使用するオプションを定義して、インストール・コマンドを実行します。
-
IBM Cloud Kubernetes Service を使用している場合は、必ずログインし、クラスターのコンテキストを設定してください。
-
Istio ポリシーの適用が有効になっていることを確認します。 有効になっていない場合は、有効にします。
-
リポジトリーを追加します。
helm repo add appidentityandaccessAdapter https://raw.githubusercontent.com/ibm-cloud-security/app-identity-and-access-Adapter/master/helm/appidentityandaccessAdapter
-
チャートをインストールします。
helm install --name appidentityandaccessAdapter appidentityandaccessAdapter/appidentityandaccessAdapter
image.tag
フラグを設定すると、インストール中にイメージ・タグを指定できます。 例えば、--set image.tag=0.5.0
です。 また、チャートをローカルでインストールすることもできます。 そのためには、インストール・コマンドを実行する前に、git clone git@github.com:ibm-cloud-security/app-identity-and-access-Adapter.git
を実行してリポジトリーを複製します。
許可ポリシーと認証ポリシーの適用
認証ポリシーまたは許可ポリシーは、要求がリソースにアクセスするために満たす必要がある一連の条件です。 ID プロバイダーのサービス構成および特定のフローを使用すべき状況を示すポリシーを定義して、サービス・メッシュ内の任意のリソースへのアクセスを制御できます。 CRDの例を見るには、 samplesディレクトリをチェックしてください。
ポリシーを作成するには、次のようにします。
- 構成を定義します。
- エンドポイントを登録します。
構成の定義
フロントエンド・アプリケーションとバックエンド・アプリケーションのどちらを保護するかに応じて、以下のいずれかの方法でポリシー構成を作成します。
-
フロントエンド・アプリケーションの場合: ユーザー認証を必要とするブラウザー・ベースのアプリケーションは、OIDC / OAuth 2.0 認証フローを使用するように構成できます。 ID プロバイダーとの認証フローを簡単にするために使用するクライアントを指定した
OidcConfig
CRD を定義するには、以下の例を参考にしてください。apiVersion: "security.cloud.ibm.com/v1" kind: OidcConfig metadata: name: oidc-provider-config namespace: sample-namespace spec: discoveryUrl: https://us-south.appid.cloud.ibm.com/oauth/v4/<tenantID>/.well-known/openid-configuration clientId: <clientID> clientSecret: <randomlyGeneratedClientSecret> clientSecretRef: name: <nameOfKubeSecret> key: <keyInKubeSecret>
YAML設定ファイルの構成要素について フィールド タイプ 必須 説明 discoveryUrl
ストリング ある OIDC/OAuth 2.0 構成情報の JSON 文書を提供する既知のエンドポイント。 clientId
ストリング ある 認証に使用するクライアントの ID。 clientSecret
ストリング - いいえ
クライアントの認証に使用するプレーン・テキストのシークレット。 指定しない場合は、 clientSecretRef
が存在している必要があります。clientSecretRef
オブジェクト いいえ クライアントの認証に使用する参照シークレット。 参照は clientSecret
の代わりに使用することができます。clientSecretRef.name
ストリング ある clientSecret
を含む Kubernetes シークレットの名前。clientSecretRef.key
ストリング ある clientSecret
がある Kubernetes シークレット内のフィールド。 -
バックエンドアプリケーションの場合:OAuth 2.0 Bearer トークン仕様は、 JSON ウェブトークン(JWT )を使用して API を保護するためのパターンを定義しています。 以下の構成を例として使用して、トークンの署名の検証に使用する公開鍵リソースを含む
JwtConfig
CRD を定義します。apiVersion: "security.cloud.ibm.com/v1" kind: JwtConfig metadata: name: jwt-config namespace: sample-app spec: jwksUrl: https://us-south.appid.cloud.ibm.com/oauth/v4/<tenantID>/publickeys
アプリケーション・エンドポイントの登録
Policy
CRD 内に、着信要求を検証して認証ルールを適用するためのアプリケーション・エンドポイントを登録します。 各 Policy
は、オブジェクトが存在する Kubernetes 名前空間に排他的に適用されます。それぞれに、保護するサービス、パス、およびメソッドを指定できます。
apiVersion: "security.cloud.ibm.com/v1"
kind: Policy
metadata:
name: samplepolicy
namespace: sample-app
spec:
targets:
-
serviceName: <svcSampleApp>
paths:
- exact: /web/home
method: ALL
policies:
- policyType: oidc
config: <oidcProviderConfig>
rules:
- claim: scope
match: ALL
source: access_token
values:
- appid_default
- openid
- claim: amr
match: ANY
source: id_token
values:
- cloud_directory
- google
- exact: /web/user
method: GET
policies:
- policyType: oidc
config: <oidcProviderConfig>
redirectUri: https://github.com/ibm-cloud-security/app-identity-and-access-Adapter
- prefix: /
method: ALL
policies:
-
policyType: jwt
config: <jwtConfig>
サービス・オブジェクト | タイプ | 必須 | 説明 |
---|---|---|---|
serviceName |
string |
ある | 保護するポリシー名前空間内の Kubernetes サービスの名前。 |
paths |
array[Path Object] |
ある | 保護するエンドポイントを定義するパス・オブジェクトのリスト。 指定しない場合、すべてのパスが保護されます。 |
パス・オブジェクト | タイプ | 必須 | 説明 |
---|---|---|---|
exact or prefix |
string |
ある | ポリシーを適用するパス。 オプションには、exact と prefix があります。 exact では、最後の / を除く、指定されたエンドポイントとの完全一致が適用対象になります。prefix では、指定された経路接頭部で始まるエンドポイントが適用対象になります。 |
method |
enum |
いいえ | 保護する HTTP メソッド。 有効なオプションは、ALL、GET、PUT、POST、DELETE、PATCH です。デフォルトは ALL です。 |
policies |
array[Policy] |
いいえ | 適用する OIDC/JWT ポリシー。 |
ポリシー・オブジェクト | タイプ | 必須 | 説明 |
---|---|---|---|
policyType |
enum |
ある | OIDC ポリシーのタイプ。 オプションには jwt または oidc があります。 |
config |
string |
ある | 使用するプロバイダー構成の名前。 |
redirectUri |
string |
いいえ | 認証が成功した後にユーザーをリダイレクトする URL。デフォルト: 元の要求 URL。 |
rules |
array[Rule] |
いいえ | トークン検証に使用する一連のルール。 |
ルール・オブジェクト | タイプ | 必須 | 説明 |
---|---|---|---|
claim |
string |
ある | 検証するクレーム。 |
match |
enum |
いいえ | クレームの検証に必要な基準。 オプションには、ALL 、ANY 、または NOT があります。 デフォルトでは、ALL に設定されます。 |
source |
enum |
いいえ | ルールを適用するトークン。 オプションには access_token または id_token があります。 デフォルトでは、access_token に設定されます。 |
values |
array[string] |
ある | 検証に必要な一連の値。 |
アダプターの削除
このアダプターおよび関連するすべての CRD を削除するには、Helm チャートおよび関連する署名鍵と暗号鍵を削除する必要があります。
helm delete --purge appidentityandaccessAdapter
kubectl delete secret appidentityandaccessAdapter-keys -n istio-system
ロギングの構成
デフォルトでは、外部ロギング・システムと簡単に統合できるように、ログは JSON 形式で整形され、info
可視性レベルで提供されます。 ロギング構成を更新するには、Helm チャートを使用します。 サポートされるロギング・レベルには、Zap コアで示される範囲 [-1, 7]が含まれます。 レベルの詳細については、 Zapコアのドキュメントを参照してください。
アダプター
アダプターのログを表示するには、kubectl
を使用するか、Kubernetes コンソールの appidentityandaccessAdapter
pod からポッドにアクセスできます。
alias Adapter_logs="kubectl -n istio-system logs -f $(kubectl -n istio-system get pods -lapp=appidentityandaccessAdapter -o jsonpath='{.items[0].metadata.name}')"
Adapter_logs | jq
Mixer
アダプターが要求を受け取っていないように見える場合は、Mixer ログを調べて、アダプターに正常に接続されていることを確認してください。
alias mixer_logs="kubectl -n istio-system logs -f $(kubectl -n istio-system get pods -lapp=telemetry -o jsonpath='{.items[0].metadata.name}') -c mixer"
mixer_logs | jq