Apache APISIX 与 Open Policy Agent 集成以丰富其生态系统
API7.ai
December 24, 2021
Open Policy Agent (OPA) は、オープンソースの軽量な汎用ポリシーエンジンであり、ソフトウェア内の組み込みポリシー機能モジュールを置き換え、ユーザーがサービスとポリシーエンジンを分離するのを支援します。OPAの充実したエコシステムのおかげで、ユーザーはプログラムライブラリやHTTP APIなどの他のサービスとOPAを簡単に統合できます。
以下の図に示すように、OPAはまずポリシー言語Regoを使用してポリシーを記述し、その後JSONを使用してポリシーデータを保存します。その後、ユーザーはクエリリクエストを送信できます。OPAはクエリリクエストを受信すると、ポリシー、データ、およびユーザー入力を組み合わせてポリシー決定を生成し、その決定をサービスに送信します。
プラグイン紹介
Apache APISIXは、opa
プラグインを提供しており、ユーザーがOPAが提供するポリシー機能をApache APISIXに簡単に導入し、柔軟な認証とアクセス制御機能を実現できます。
ルートにopa
プラグインを設定すると、Apache APISIXはリクエスト情報や接続情報などをJSONデータに組み立て、レスポンスリクエストを処理する際にポリシー決定APIアドレスに送信します。OPAにデプロイされたポリシーがApache APISIXが設定したデータ仕様に準拠している限り、リクエストの許可、リクエストの拒否、カスタムステータスコード、カスタムレスポンスヘッダーなどの機能を実現できます。
この記事では、HTTP APIを例にopa
プラグインを紹介し、Apache APISIXとOPAを統合してバックエンドサービスの認証認可を分離する方法について詳しく説明します。
使用方法
テスト環境の構築
-
Dockerを使用してOPAサービスを構築します。
# DockerでOPAを実行 docker run -d --name opa -p 8181:8181 openpolicyagent/opa:0.35.0 run -s
-
example
ポリシーを作成します。# ポリシーを作成 curl -XPUT 'localhost:8181/v1/policies/example' \ --header 'Content-Type: text/plain' \ --data-raw 'package example import input.request import data.users default allow = false allow { # リクエストヘッダーにtest-headerがあり、その値がonly-for-testである request.headers["test-header"] == "only-for-test" # リクエストメソッドがGETである request.method == "GET" # リクエストパスが/getで始まる startswith(request.path, "/get") # GETパラメータtestが存在し、その値がabcdでない request.query["test"] != "abcd" # GETパラメータuserが存在する request.query["user"] } reason = users[request.query["user"]].reason { not allow request.query["user"] } headers = users[request.query["user"]].headers { not allow request.query["user"] } status_code = users[request.query["user"]].status_code { not allow request.query["user"] }'
-
users
データを作成します。# テストユーザーデータを作成 curl -XPUT 'localhost:8181/v1/data/users' \ --header 'Content-Type: application/json' \ --data-raw '{ "alice": { "headers": { "Location": "http://example.com/auth" }, "status_code": 302 }, "bob": { "headers": { "test": "abcd", "abce": "test" } }, "carla": { "reason": "Give you a string reason" }, "dylon": { "headers": { "Content-Type": "application/json" }, "reason": { "code": 40001, "desc": "Give you a object reason" } } }'
ルートを作成し、プラグインを有効化
以下のコマンドを実行してルートを作成し、opa
プラグインを有効にします。
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/r1' \ --header 'X-API-KEY: <api-key>' \ --header 'Content-Type: application/json' \ --data-raw '{ "uri": "/*", "methods": [ "GET", "POST", "PUT", "DELETE" ], "plugins": { "opa": { "host": "http://127.0.0.1:8181", "policy": "example" } }, "upstream": { "nodes": { "httpbin.org:80": 1 }, "type": "roundrobin" } }'
リクエストのテスト
次に、以下のコマンドを実行してopa
プラグインにリクエストを送信し、プラグインの動作状態をテストします。
# リクエストを許可 curl -XGET '127.0.0.1:9080/get?test=none&user=dylon' \ --header 'test-header: only-for-test' { "args": { "test": "abcd1", "user": "dylon" }, "headers": { "Test-Header": "only-for-test", "with": "more" }, "origin": "127.0.0.1", "url": "http://127.0.0.1/get?test=abcd1&user=dylon" } # リクエストを拒否し、ステータスコードとレスポンスヘッダーを書き換える curl -XGET '127.0.0.1:9080/get?test=abcd&user=alice' \ --header 'test-header: only-for-test' HTTP/1.1 302 Moved Temporarily Date: Mon, 20 Dec 2021 09:37:35 GMT Content-Type: text/html Content-Length: 142 Connection: keep-alive Location: http://example.com/auth Server: APISIX/2.11.0 # リクエストを拒否し、カスタムレスポンスヘッダーを返す curl -XGET '127.0.0.1:9080/get?test=abcd&user=bob' \ --header 'test-header: only-for-test' HTTP/1.1 403 Forbidden Date: Mon, 20 Dec 2021 09:38:27 GMT Content-Type: text/html; charset=utf-8 Content-Length: 150 Connection: keep-alive abce: test test: abcd Server: APISIX/2.11.0 # リクエストを拒否し、カスタムレスポンス(文字列)を返す curl -XGET '127.0.0.1:9080/get?test=abcd&user=carla' \ --header 'test-header: only-for-test' HTTP/1.1 403 Forbidden Date: Mon, 20 Dec 2021 09:38:58 GMT Content-Type: text/plain; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Server: APISIX/2.11.0 Give you a string reason # リクエストを拒否し、カスタムレスポンス(JSON)を返す curl -XGET '127.0.0.1:9080/get?test=abcd&user=dylon' \ --header 'test-header: only-for-test' HTTP/1.1 403 Forbidden Date: Mon, 20 Dec 2021 09:42:12 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive Server: APISIX/2.11.0 {"code":40001,"desc":"Give you a object reason"}
プラグインの無効化
Apache APISIXの動的な性質により、ルート上のOPAプラグインは、ルート設定からopa
プラグイン関連の設定を削除して保存するだけで無効にできます。
まとめ
この記事では、Apache APISIXとOpen Policy Agentを連携するための詳細な手順を説明しました。この記事が、Apache APISIXでOpen Policy Agentを使用する際の理解を深め、その後の実践操作を容易にすることを願っています。
Apache APISIXは、自身の高性能を維持することに加えて、オープンソースエコシステムの構築にも非常に重視しています。現在、Apache APISIXには10以上の認証認可関連のプラグインがあり、業界の主要な認証認可サービスとの連携をサポートしています。
他の認証認可サービスとの連携が必要な場合は、Apache APISIXのGitHubにアクセスし、issueを通じて提案を残してください。または、Apache APISIXのメーリングリストに登録して、メールでアイデアを伝えてください。