OPA
Enforce Open Policy Agent (OPA) policies for more fine-grained access control.This feature is available with a Gloo Mesh Gateway license only.
About OPA
OPA is an open source, general-purpose policy engine that you can use to enforce versatile policies in a uniform way across your organization. Compared to a role-based access control (RBAC) authorization system, OPA allows you to create more fine-grained policies. For more information, see the OPA docs.
OPA policies are written in Rego. Based on the older query languages Prolog and Datalog, Rego extends support to more modern document models such as JSON.
Gloo Mesh's OPA integration populates an input
document to use in your OPA policies. The structure of the input
document depends on the context of the incoming request, described in the following table.
OPA input structure | Description |
---|---|
input.check_request |
By default, all OPA policies contain an Envoy Auth Service CheckRequest . This object has all the information that Envoy gathers about the request being processed. You can view the structure of this object in the attributes section of the linked Envoy doc. |
input.http_request |
When processing an HTTP request, Envoy populates this field for convenience. For the structure of this object, see the Envoy HttpRequest docs and proto files. |
input.state.jwt |
If you use OAuth, the token retrieved during the OIDC flow is placed into this field. |
Before you begin
-
Complete the demo setup to install Gloo Mesh, Istio, and Bookinfo in your cluster.
-
Create the Gloo Mesh resources for this policy in the management and workload clusters.
The following files are examples only for testing purposes. Your actual setup might vary. You can use the files as a reference for creating your own tests.
-
Download the following Gloo Mesh resources:
-
Apply the files to your management cluster.
kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-1.yaml --context ${MGMT_CONTEXT} kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-2.yaml --context ${MGMT_CONTEXT} kubectl apply -f workspace_gloo-mesh_anything.yaml --context ${MGMT_CONTEXT}
-
Download the following Gloo Mesh resources:
-
Apply the files to your workload cluster.
kubectl apply -f virtual-gateway_bookinfo_north-south-gw.yaml --context ${REMOTE_CONTEXT1} kubectl apply -f workspace-settings_bookinfo_anything.yaml --context ${REMOTE_CONTEXT1}
-
-
Send a request to verify that you can reach the
ratings
app without authorization. By default Gloo Mesh allows any request on routes that do not specify authentication.curl -v ${INGRESS_GW_IP}/ratings/1 -H "Host: www.example.com"
Example output:
{"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
Configure an external auth policy with OPA
Create the external auth policy with OPA.
-
Create an OPA rego policy file.
Review the following table to understand this configuration.cat <<EOF > policy.rego package test default allow = false allow { startswith(input.http_request.path, "/ratings/2") input.http_request.method == "GET" } allow { input.http_request.path == "/ratings/3" any({input.http_request.method == "GET", input.http_request.method == "DELETE" }) } EOF
Setting Description default allow = false
Denies all requests by default. allow {...}
Allows requests that match two conditions as follows. 1) The path starts with /ratings/2
AND the HTTP method isGET
; or, 2) the path is exactly/ratings/3
AND the HTTP method is eitherGET
orDELETE
. -
Store the OPA policy in a Kubernetes config map in the workload cluster that you want to create the external auth policy in.
kubectl --context ${REMOTE_CONTEXT1} -n bookinfo create configmap allow-get-users --from-file=policy.rego
-
Create an external auth server to use for your policy.
kubectl --context ${REMOTE_CONTEXT1} apply -f - <<EOF apiVersion: admin.gloo.solo.io/v2 kind: ExtAuthServer metadata: name: ext-auth-server namespace: bookinfo spec: destinationServer: ref: cluster: cluster-1 name: ext-auth-service namespace: gloo-mesh port: name: http2 EOF
-
Create a route table for the ratings app and external auth policy. Note that the route table selects the virtual gateway that you created before you began, and routes to the ratings service.
kubectl --context ${REMOTE_CONTEXT1} apply -f - <<EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: bookinfo namespace: bookinfo labels: expose: "true" spec: hosts: - '*' virtualGateways: - name: north-south-gw namespace: bookinfo cluster: cluster-1 workloadSelectors: [] http: - name: ratings labels: opa: "true" matchers: - uri: prefix: /ratings forwardTo: destinations: - ref: name: ratings namespace: bookinfo EOF
-
Create an external auth policy that uses the OPA config map.
kubectl --context ${REMOTE_CONTEXT1} apply -f - <<EOF apiVersion: security.policy.gloo.solo.io/v2 kind: ExtAuthPolicy metadata: name: ratings-apikey namespace: bookinfo spec: applyToRoutes: - route: labels: opa: "true" config: server: name: ext-auth-server namespace: bookinfo cluster: cluster-1 glooAuth: configs: - opaAuth: modules: - name: allow-get-users namespace: bookinfo query: "data.test.allow == true" EOF
Review the following table to understand this configuration. For more information, see the API reference.
Setting | Description |
---|---|
applyToRoutes |
Configure which routes to apply the policy to, by using labels. The label matches the app and the route from the route table. If omitted, the policy applies to all routes in the workspace. |
server |
The external auth server to use for the policy. |
opaAuth |
Configure the OPA authentication details. |
modules |
Refer to the name and namespace of the config map that has the OPA policy. Then, Gloo Mesh can use the OPA policy to use to resolve the query . This example uses the config map that you previously created. |
query |
The query that determines the authentication decision. The result of this query must be either a boolean or an array with a boolean as the first element. A value of true means that the request is authorized. Any other value or error means that the request is denied. In this example, data.test.allow is set to true . data is the section in the config map. test.allow are part of the OPA policy that you previously created. Access is allowed only if the response meets the allow conditions in the policy. |
Verify the external auth API key policy
-
Send a request to the
ratings
app along a path that is not allowed by the OPA policy, such as/ratings/1
. Now, the request is blocked with a 403 response.curl -v ${INGRESS_GW_IP}/ratings/1 -H "Host: www.example.com"
-
Send the request again, this time along a path that is allowed by the OPA policy, such as
GET /ratings/2
.curl -v -X GET ${INGRESS_GW_IP}/ratings/2 -H "Host: www.example.com"
You can reach the ratings app again!
{"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}