This tutorial shows how Istio’s EnvoyFilter can be configured to include Envoy’s External Authorization filter to delegate authorization decisions to OPA.
This tutorial requires Kubernetes 1.14 or later. To run the tutorial locally, we recommend using in version v1.0+
with Kubernetes 1.14+.
The tutorial also requires Istio v1.8.0 or later. It assumes you have Istio deployed on top of Kubernetes. See Istio’s Quick Start page to get started.
The quick_start.yaml
manifest defines the following resources:
External Authorization Filter to direct authorization checks to the OPA-Envoy sidecar. See
kubectl -n istio-system get envoyfilter ext-authz
for details.Kubernetes namespace (
opa-istio
) for OPA-Envoy control plane components.OPA configuration file and an OPA policy into ConfigMaps in the namespace where the app will be deployed, e.g.,
default
. The following is the example OPA policy:- alice is granted a guest role and can perform a
GET
request to/productpage
. - bob is granted an admin role and can perform a
GET
to/productpage
and/api/v1/products
.
package istio.authz
import input.attributes.request.http as http_request
import input.parsed_path
default allow = false
allow {
parsed_path[0] == "health"
http_request.method == "GET"
}
allow {
required_roles[r]
}
roles_for_user[r] {
r := user_roles[user_name][_]
}
required_roles[r] {
perm := role_perms[r][_]
perm.method = http_request.method
perm.path = http_request.path
}
user_name = parsed {
[_, encoded] := split(http_request.headers.authorization, " ")
[parsed, _] := split(base64url.decode(encoded), ":")
}
user_roles = {
"alice": ["guest"],
"bob": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
}
OPA is configured to query for the decision. If the response is
true
the operation is allowed, otherwise the operation is denied. Sample input received by OPA is shown below:data.istio.authz.allow
{
"attributes": {
"request": {
"http": {
"method": "GET",
"path": "/productpage",
"headers": {
"authorization": "Basic YWxpY2U6cGFzc3dvcmQ="
}
}
}
}
}
With the input value above, the answer is:
An example of the complete input received by OPA can be seen .
- alice is granted a guest role and can perform a
kubectl label namespace default opa-istio-injection="enabled"
kubectl label namespace default istio-injection="enabled"
kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/networking/bookinfo-gateway.yaml
minikube:
192.168.99.100:31380
For other platforms see the Istio documentation on determining ingress IP and ports.
Check that alice can access /productpage
BUT NOT /api/v1/products
.
curl --user alice:password -i http://$GATEWAY_URL/productpage
curl --user alice:password -i http://$GATEWAY_URL/api/v1/products
Check that bob can access /productpage
AND /api/v1/products
.
Congratulations for finishing the tutorial !
This tutorial showed how Istio’s can be configured to use OPA as an External authorization service.
This tutorial also showed a sample OPA policy that returns a boolean
decision to indicate whether a request should be allowed or not.