Kong Gatewayは、オープンソースのAPIゲートウェイであり、適切なリクエストだけを許可しながら、セキュリティ、レートリミティング、ログ記録などを管理します。OPA (Open Policy Agent)は、オープンソースのポリシーエンジンであり、あなたのセキュリティやアクセス決定をコントロールします。これをアプリからポリシーの執行を解耦している「心」と考えてくださいので、あなたのサービスはルールの実行について心配する必要はなくなります。代わりに、OPAはRego言語を使用して、ポリシーをAPI、マイクロサービス、または甚至Kubernetesに跨って評価します。これは柔軟で、安全で、ポリシーの更新を簡単にすることができます。OPAは3つの主要な要素を評価します:入力(リクエストのような实时データ)、データ(ユーザーロールなどの外部情報)、そしてポリシー(”許可”または”拒否”を決定するRego言語のロジック)。これらのコンポーネントを合わせることで、OPAは簡潔で一致性を保ちながら、あなたのセキュリティゲームを強くします。
私たちは何を達成したいのか?または何を解決しようとしているのか?
しばしば、OPA内のデータは、静的または徐々に変化する、牢靠な古い友達のようだ。これは、常に変化する入力データと並行して、賢明な決策を作成するために使用されます。しかし、マイクロサービスの广範囲のウェブ、大量のユーザー、およびPostgreSQLのような巨大なデータベースを持つシステムを考えてみてください。このシステムは、每一秒に数百万のトランザクションを処理し、 sweatを出さずにそのスピードと吞吐量を保ちます。
このようなシステムで精細なアクセスコントロールを実施するのは難しいですが、OPAを使用することで、マイクロサービスから重荷の作业を引き受けることができます。Kong API GatewayとOPAとの協力で、最も優れた吞吐量と正確なアクセスコントロールを得ることができます。
どのようにして、スピードを下げないで正確なユーザーデータを維持するか?常にPostgreSQLデータベースにアクセスし、数百万のレコードを取得することは、昂贵で遅いことです。正確さとスピードを両方を得るために、通常は両方の間で妥協が必要です。私たちは、ゲートウェイレベルで開発するカスタムプラグインを通じて、常に読み込んだりローカルキャッシュしたデータをOPAに提供し、そのポリシーの評価に使用することで、実用的なバランスを見つけることを目指します。
デモ
デモには、PostgreSQLにサンプルデータが設定されています。これには、名前、Eメール、役割などのユーザー情報が含まれています。ユーザーが特定のURLを通じてサービスにアクセスしようとすると、OPAはその要求が許可されているかどうかを評価します。Regoポリシーは、要求URL(リソース)、メソッド、およびユーザーの役割を確認し、ルールに基づいてtrueまたはfalseを返します。trueの場合、要求は許可され、falseの場合、アクセスは拒否されます。これまでの説明は直接的な設定です。カスタムプラグインについては以下の図を参照して、実装の理解を深めましょう。
Kong Proxy経由で要求が来た場合、Kongのカスタムプラグインがトリガーされます。プラグインは必要なデータを取得し、入力/クエリとともにOPAに渡します。このデータ取得には2つの部分があります。1つはRedisを検索して必要な値を見つけることで、見つかればOPAに渡します。見つからなければ、さらにPostgresに問い合わせてデータを取得し、RedisにキャッシュしてからOPAに渡します。次のセクションでコマンドを実行してログを観察するときにこれについて再訪することができます。OPAはポリシー、入力、データに基づいて決定を行い、許可された場合、Kongはその要求をAPIに送信します。このアプローチを使用することで、Postgresへのクエリ数が大幅に削減されているのに、OPAで使用可能なデータは正確であり、低遅延を保ちます。
pluginのカスタム作成を始めるには、handler.lua
が必要で、ここにプラグインの核心ロジックが実装されます。また、schema.lua
も必要で、これはプラグインの設定のスキーマを定義します。Kong用のカスタムプラグインを書く初めての方は、このリンクを参照してください。ドキュメントは、プラグインのパッケージ化とインストール方法も説明しています。今回は、このプラグインのロジックについて理解していきましょう。
デモの最初のステップは、デモ用のOPA、Kong、Postgres、Redisをローカル環境やクラウド環境にインストールすることです。このリポジトリーにcloneしてください。
docker-compose.yamlを確認してください。これには、上記の4つのサービスの配置が定義されています。Kongの環境変数を確認して、カスタムプラグインの読み込み方法をご覧ください。
以下のコマンドを実行して、サービスをデプロイしてください。
docker-compose build
docker-compose up
コンテナが起動していることを確認した後、Kong managerとOPAは以下のエンドポイントで利用可能です。
以下のコマンドを使用して、テストサービスを作成し、このルートにカスタムのKongプラグインを追加してください。
curl -X POST http://localhost:8001/config -F config=@config.yaml
OPAポリシーは、authopa.regoファイルで定義され、以下のコマンドを使用して、OPAサービスに投稿され更新されます。
curl -X PUT http://localhost:8181/v1/policies/mypolicyId -H "Content-Type: application/json" --data-binary @authopa.rego
このサンプルポリシーは、ユーザーが/demoパスにGET
メソッドでアクセスし、"Moderator"
の役割を持っている場合にのみ、ユーザーリクエストにアクセスを許可します。必要であれば、異なる基準に基づいてアクセス制御を調整するために、追加のルールを追加することができます。
opa_policy = [
{
"path": "/demo",
"method": "GET",
"allowed_roles": ["Moderator"]
}
]
現在の設定は完了しましたが、テストする前に、Postgresにテストデータを追加する必要があります。以下に示されるように、いくつかの従業員についてサンプルデータ(名前、電子メール、役割)を追加しました(PostgresReadmeに従ってください)。
以下は失敗した要求和成功的要求のサンプルです。
ここで、このカスタムプラグインの主要な機能をテストするために、2つの連続的な要求を送信し、データの取得がどのように行われているか、ログを確認しましょう。
これらはログです。
2024/09/13 14:05:05 [error] 2535#0: *10309 [kong] redis.lua:19 [authopa] No data found in Redis for key: [email protected], client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:25 [authopa] Fetching roles from PostgreSQL for email: [email protected], client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] postgres.lua:43 [authopa] Fetched roles: Moderator, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:29 [authopa] Caching user roles in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] redis.lua:46 [authopa] Data successfully cached in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 client 192.168.96.1 closed keepalive connection
------------------------------------------------------------------------------------------------------------------------
2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] redis.lua:23 [authopa] Redis result: {"roles":["Moderator"],"email":"[email protected]"}, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"
2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"
ログは、最初の要求の場合、Redisにデータがないため、Postgresからデータを取得し、それをRedisにキャッシュし、それをOPAに評価する前に送信します。次の要求の場合、データはRedisにありますので、応答はより速いでしょう。
結論
結論として、Kong GatewayをOPAと結合し、Redisキャッシングを実装したカスタムプラグインを使用することで、高并通过put環境でのアクセスコントロールにおいて、精度と速度を効果的にバランスすることができる。このプラグインは、最初のクエリ後にRedisにユーザーロールをキャッシュすることで、コストのかかるPostgresクエリの数を最小限に抑える。その後のリクエストでは、データはRedisから取得され、latencyを显著に減少させると同時に、OPAポリシー評価に使用される正確で更新されたユーザー情報を維持する。この手法は、細粒度アクセスコントロールをゲートウェイレベルで効率よく処理することで、パフォーマンスやセキュリティを犠牲にすることなく、スケール可能なマイクロサービスの监理に最適なソリューションとなる。
Source:
https://dzone.com/articles/enhanced-api-security-fine-grained-access-control