Open Policy Agent (OPA) is an open source lightweight general policy engine, which can replace the built-in policy function module in the software to help users realize the decoupling of service and policy engine. Benefit from OPA Perfect ecosystem , users can easily integrate OPA and other services, such as program library, HTTP API, etc.
As shown in the figure below, OPA first describes the policy through the policy language Rego; Then the policy data is stored through JSON, and then the user can send a query request. After receiving the query request, OPA will combine the policy, data and the query request content entered by the user to generate the policy decision, and send the decision to the service.
Plug in introduction
Apache APISIX provides an OPA plug-in. Users can use this plug-in to easily introduce the policy capabilities provided by OPA into Apache APISIX to realize flexible identity authentication and admission control functions.
After the OPA plug-in is configured on the route, Apache apisid will assemble the request information and connection information into JSON data and send them to the policy decision API address when processing the response request. As long as the policies deployed in OPA comply with the data specifications set by Apache APISIX, functions such as pass request, reject request, custom status code, custom response header, custom response header and so on can be realized.
Taking HTTP API as an example, this paper introduces the OPA plug-in, and explains in detail how to integrate Apache apisid with OPA to realize the decoupling of authentication and authorization of back-end services.
How to use
Step 1: build a test environment
- Use Docker to build OPA services.
# Run OPA using Docker docker run -d --name opa -p 8181:8181 openpolicyagent/opa:0.35.0 run -s
- Create a policy example.
# Create policy 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 { # It has a request header named test header and a value of only for test request.headers["test-header"] == "only-for-test" # The request method is GET request.method == "GET" # Request path starts with / get startswith(request.path, "/get") # GET parameter test exists and is not equal to abcd request.query["test"] != "abcd" # GET parameter user does not exist 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"] }'
- Create users data.
# Create test user data 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" } } }'
Step 2: create a route and open the opa plug-in
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" } }'
Step 3: Test Request
# Allow request 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" } # Reject the request and rewrite the status code and response header 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 # Reject the request and return the custom response header 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 # Reject the request and return a custom response (string) 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 # Reject the request and return a custom response (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"}
Add: close plug-in
Thanks to the dynamic characteristics of Apache apisik, you can close the OPA plug-in on the route by removing the relevant configuration of the OPA plug-in in the route configuration and saving it.
summary
This article describes the detailed operation steps of the docking between Apache APIs IX and Open Policy Agent. I hope this article can give you a clearer understanding of the use of Open Policy Agent in Apache APIs IX and facilitate subsequent practical operation.
Apache APISIX is not only committed to maintaining its high performance, but also attaches great importance to the construction of open source ecology. At present, Apache APISIX has 10 + authentication and authorization related plug-ins, which support docking with the mainstream authentication and authorization services in the industry.
If you have the need to connect with other authentication and authorization, you may wish to visit Apache APIs IX's GitHub , leave your suggestions through issue; Or subscribe to Apache APIs IX mailing list , express your thoughts by email.