アプリケーションIDおよびアクセスアダプター
コード変更なしでマルチクラウドKubernetesアプリケーションを保護するためのIstioの利用。
コンテナ化されたアプリケーションをKubernetes上で実行している場合、アプリケーションIDおよびアクセスアダプターを使用することで、コードの変更や再デプロイなしで、抽象化されたレベルのセキュリティを実現できます。
コンピューティング環境が単一のクラウドプロバイダー、複数のクラウドプロバイダーの組み合わせ、またはハイブリッドクラウドアプローチに基づいているかにかかわらず、中央集権的なID管理により、既存のインフラストラクチャを維持し、ベンダーロックインを回避できます。
アプリケーションIDおよびアクセスアダプター を使用すると、IBM Cloud App ID、Auth0、Okta、Ping Identity、AWS Cognito、Azure AD B2Cなど、任意のOAuth2/OIDCプロバイダーを使用できます。認証および承認ポリシーは、フロントエンドアプリケーションとバックエンドアプリケーションを含むすべての環境で、コードの変更や再デプロイなしに、効率的に適用できます。
Istioとアダプターの理解
Istio は、分散アプリケーションに透過的にレイヤー化され、Kubernetesとシームレスに統合されるオープンソースのサービスメッシュです。Istioは、デプロイの複雑さを軽減するために、サービスメッシュ全体の動作に関する洞察と運用制御を提供します。詳細については、Istioアーキテクチャを参照してください。
Istioは、Envoyプロキシサイドカーを使用して、サービスメッシュ内のすべてのポッドの送受信トラフィックを仲介します。IstioはEnvoyサイドカーからテレメトリを抽出し、テレメトリの収集とポリシーの適用を担当するIstioコンポーネントであるMixerに送信します。
アプリケーションIDおよびアクセスアダプターは、サービスメッシュ全体でさまざまなアクセス制御ポリシーに対してテレメトリ(属性)を分析することにより、Mixerの機能を拡張します。アクセス制御ポリシーは特定のKubernetesサービスにリンクでき、特定のサービスエンドポイントに細かく調整できます。ポリシーとテレメトリの詳細については、Istioのドキュメントを参照してください。
アプリケーションIDおよびアクセスアダプターをIstioと組み合わせると、カスタムアプリケーションコードの変更を必要としない、マルチクラウドアーキテクチャのためのスケーラブルで統合されたIDおよびアクセスソリューションが提供されます。
インストール
アプリケーションIDおよびアクセスアダプターは、github.com
リポジトリから直接Helmを使用してインストールできます。
$ 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
あるいは、リポジトリをクローンして、Helmチャートをローカルにインストールすることもできます。
$ git clone git@github.com:ibm-cloud-security/app-identity-and-access-adapter.git
$ helm install ./helm/appidentityandaccessadapter --name appidentityandaccessadapter.
Webアプリケーションの保護
Webアプリケーションは、一般的にauthorization_code
と呼ばれるOpenID Connect(OIDC)ワークフローによって保護されています。認証されていない/権限のないユーザーが検出されると、自動的に選択したIDサービスにリダイレクトされ、認証ページが表示されます。認証が完了すると、ブラウザはアダプターによってインターセプトされた暗黙的な/oidc/callback
エンドポイントにリダイレクトされます。この時点で、アダプターはIDサービスからアクセスおよびIDトークンを取得し、ユーザーをWebアプリの元々要求されたURLにリダイレクトします。
認証状態とトークンはアダプターによって維持されます。アダプターによって処理される各リクエストには、次の形式でアクセスとIDトークンを保持するAuthorizationヘッダーが含まれます。Authorization: Bearer <access_token> <id_token>
開発者は、ユーザー名の表示、ユーザーロールに基づいたUIの調整など、アプリケーションエクスペリエンスの調整にトークンを利用できます。
認証セッションを終了し、トークン(ユーザーログアウト)を消去するには、保護されたサービスの下にある/oidc/logout
エンドポイントにブラウザをリダイレクトするだけです。たとえば、アプリをhttps://example.com/myapp
から提供している場合、ユーザーをhttps://example.com/myapp/oidc/logout
にリダイレクトします。
アクセストークンが期限切れになると、リフレッシュトークンを使用して、ユーザーが再認証する必要なしに、新しいアクセスとIDトークンを自動的に取得します。構成されたIDプロバイダーがリフレッシュトークンを返す場合、それはアダプターによって保持され、古いトークンが期限切れになったときに新しいアクセスとIDトークンを取得するために使用されます。
Webアプリケーション保護の適用
Webアプリケーションの保護には、2種類の資源の作成が必要です。OidcConfig
リソースを使用してさまざまなOIDCプロバイダーを定義し、Policy
リソースを使用してWebアプリ保護ポリシーを定義します。
apiVersion: "security.cloud.ibm.com/v1"
kind: OidcConfig
metadata:
name: my-oidc-provider-config
namespace: sample-namespace
spec:
discoveryUrl: <discovery-url-from-oidc-provider>
clientId: <client-id-from-oidc-provider>
clientSecretRef:
name: <kubernetes-secret-name>
key: <kubernetes-secret-key>
apiVersion: "security.cloud.ibm.com/v1"
kind: Policy
metadata:
name: my-sample-web-policy
namespace: sample-namespace
spec:
targets:
- serviceName: <kubernetes-service-name-to-protect>
paths:
- prefix: /webapp
method: ALL
policies:
- policyType: oidc
config: my-oidc-provider-config
rules: // optional
- claim: iss
match: ALL
source: access_token
values:
- <expected-issuer-id>
- claim: scope
match: ALL
source: access_token
values:
- openid
バックエンドアプリケーションとAPIの保護
バックエンドアプリケーションとAPIは、Bearerトークンフローを使用して保護されます。このフローでは、着信トークンが特定のポリシーに対して検証されます。Bearerトークン承認フローでは、JWT形式の有効なアクセストークンを含むAuthorization
ヘッダーをリクエストに含める必要があります。ヘッダーの期待される構造はAuthorization: Bearer {access_token}
です。トークンが正常に検証された場合、リクエストは要求されたサービスに転送されます。トークン検証が失敗した場合、APIにアクセスするために必要なスコープのリストを含むHTTP 401がクライアントに返されます。
バックエンドアプリケーションとAPIの保護の適用
バックエンドアプリケーションとAPIの保護には、2種類の資源の作成が必要です。JwtConfig
リソースを使用してさまざまなJWTプロバイダーを定義し、Policy
リソースを使用してバックエンドアプリ保護ポリシーを定義します。
apiVersion: "security.cloud.ibm.com/v1"
kind: JwtConfig
metadata:
name: my-jwt-config
namespace: sample-namespace
spec:
jwksUrl: <the-jwks-url>
apiVersion: "security.cloud.ibm.com/v1"
kind: Policy
metadata:
name: my-sample-backend-policy
namespace: sample-namespace
spec:
targets:
- serviceName: <kubernetes-service-name-to-protect>
paths:
- prefix: /api/files
method: ALL
policies:
- policyType: jwt
config: my-oidc-provider-config
rules: // optional
- claim: iss
match: ALL
source: access_token
values:
- <expected-issuer-id>
- claim: scope
match: ALL
source: access_token
values:
- files.read
- files.write
既知の制限事項
このブログを書いている時点では、アプリケーションIDおよびアクセスアダプターには2つの既知の制限事項があります。
WebアプリケーションにアプリケーションIDおよびアクセスアダプターを使用する場合は、アダプターの複製を1つ以上作成しないでください。Envoy ProxyがHTTPヘッダーを処理する方法のため、MixerからEnvoyに複数の
Set-Cookie
ヘッダーを返すことが不可能でした。そのため、Webアプリケーションのシナリオを処理するために必要なすべてのCookieを設定できませんでした。この問題はEnvoyとMixerで最近解決され、今後のアダプターのバージョンで対応する予定です。**これはWebアプリケーションのみに影響し、バックエンドアプリやAPIには影響しません。**一般的なベストプラクティスとして、クラスタ内通信には常に相互TLSを使用することを検討する必要があります。現時点では、MixerとアプリケーションIDおよびアクセスアダプター間の通信チャネルは相互TLSを使用していません。Mixerアダプター開発者ガイドに記載されているアプローチを実装することにより、今後対応する予定です。
まとめ
マルチクラウド戦略が導入されている場合、環境が拡大し多様化するにつれて、セキュリティは複雑になる可能性があります。クラウドプロバイダーは、自社のサービスが安全であることを保証するためのプロトコルとツールを提供していますが、開発チームは、OAuth2によるAPIアクセスコントロール、トラフィック暗号化による中間者攻撃からの防御、サービスアクセスコントロールのための相互TLSの提供など、アプリケーションレベルのセキュリティを担当しています。しかし、各サービスに対して個別にこれらのセキュリティの詳細を定義する必要があるため、マルチクラウド環境ではこれが複雑になります。
開発チームは、サービスをさまざまなクラウドプロバイダーに移植するために時間を費やしており、同様に、導入されているセキュリティも柔軟でインフラストラクチャに依存しないものである必要があります。
IstioとアプリケーションIDおよびアクセスアダプターを使用すると、使用するプログラミング言語やフレームワークに関係なく、コードの変更や再デプロイをまったく行わずにKubernetesアプリを保護できます。このアプローチに従うことで、アプリの最大限の移植性と、複数の環境で同じセキュリティポリシーを容易に適用する能力が保証されます。
アプリケーションIDおよびアクセスアダプターの詳細については、リリースブログを参照してください。