Authorization (RBAC)
- - 3 min read
Per default all requests inside a Service Mesh are allowed, which can be a problem security-wise. To solve this, authorization, which verifies if the user is allowed to perform a certain action, is required. Istio’s authorization provides access control on mesh-level, namespace-level and workload-level.
With the resource AuthorizationPolicy granular policies can be defined. These policies are loaded to and verified by the Envoy Proxy which then authorizes a request.
Implicit enablement
To enable authorization the only thing you need is to do is to define the AuthorizationPolicy. If the resource is not defined, then no access control will be used, instead any traffic is allowed. If AuthorizationPolicy is applied to a workload, then by default any traffic is denied unless it is explicitly allowed.
This is applicable to Service Mesh version 1.1+ |
Preparing Environment
The following steps will configure an example Role Based Access Control (RBAC). It will start from scratch. If you just want to quickly configure the authorization and have anything else in place, you can start form here: Configure Authentication Policy
Create a new project
oc new-project tutorial
Be sure that a Service Mesh Member Roll exists for this new project
cat <<'EOF' > memberroll.yaml apiVersion: maistra.io/v1 kind: ServiceMeshMemberRoll metadata: name: default spec: members: - tutorial EOF oc apply -f memberroll.yaml -n istio-system
Clone and install the example application
git clone https://github.com/redhat-developer-demos/istio-tutorial/ istio-tutorial oc apply -f istio-tutorial/customer/kubernetes/Deployment.yml -n tutorial oc apply -f istio-tutorial/customer/kubernetes/Service.yml -n tutorial oc expose service customer oc apply -f istio-tutorial/preference/kubernetes/Deployment.yml -n tutorial oc apply -f istio-tutorial/preference/kubernetes/Service.yml -n tutorial oc apply -f istio-tutorial/recommendation/kubernetes/Deployment.yml -n tutorial oc apply -f istio-tutorial/recommendation/kubernetes/Service.yml -n tutorial
Wait until all pods are running. There should be 2 containers for all pods:
oc get pods -w
Create Gateway and VirtualService
cat <<'EOF' > Gateway_VirtualService.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: customer-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: customer-gateway spec: hosts: - "*" gateways: - customer-gateway http: - match: - uri: prefix: /customer rewrite: uri: / route: - destination: host: customer port: number: 8080 EOF oc apply -f Gateway_VirtualService.yaml -n tutorial
Verify if the application is working You can either use the run.sh from previous tutorials, or simply try the following curl
export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}'); echo $GATEWAY_URL curl $GATEWAY_URL/customer
This should return the following line:
customer => preference => recommendation v1 from 'f11b097f1dd0': 1
Optionally check the connection from inside the customer container
get pods name and enter it:
oc get pods NAME READY STATUS RESTARTS AGE customer-6948b8b959-dhsm9 2/2 Running 0 177m preference-v1-7fdb89c86b-dvzs9 2/2 Running 0 177m recommendation-v1-69db8d6c48-cjcpn 2/2 Running 0 177m
Connect into the container pod and try to reach the different microservices
oc rsh customer-6948b8b959-dhsm9 sh-4.4$ curl customer:8080 customer => preference => recommendation v1 from 'f11b097f1dd0': 2 sh-4.4$ curl preference:8080 preference => recommendation v1 from 'f11b097f1dd0': 3 sh-4.4$ curl recommendation:8080 recommendation v1 from 'f11b097f1dd0': 4
Configure Authentication Policy
Enabling User-End authentication
cat <<'EOF' > authentication-policy.yaml apiVersion: "authentication.istio.io/v1alpha1" kind: "Policy" metadata: name: "customerjwt" spec: targets: - name: customer - name: preference - name: recommendation origins: - jwt: issuer: "testing@secure.istio.io" jwksUri: "https://gist.githubusercontent.com/lordofthejars/7dad589384612d7a6e18398ac0f10065/raw/ea0f8e7b729fb1df25d4dc60bf17dee409aad204/jwks.json" principalBinding: USE_ORIGIN EOF oc apply -f authentication-policy.yaml -n tutorial
Access should be denied after a few seconds
curl $GATEWAY_URL/customer Origin authentication failed.%
Use token to authenticate
token=$(curl https://gist.githubusercontent.com/lordofthejars/a02485d70c99eba70980e0a92b2c97ed/raw/f16b938464b01a2e721567217f672f11dc4ef565/token.simple.jwt -s) curl -H "Authorization: Bearer $token" $GATEWAY_URL/customer
This will result in a correct response
customer => preference => recommendation v1 from 'f11b097f1dd0': 5
Configure Role Based Access Control (RBAC)
Create the resource AuthorizationPolicy
This is a new resources, supported since Service Mesh 1.1. It will allow GET method when the role equals to "customer"
cat <<'EOF' > AuthorizationPolicy.yaml apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "customer" spec: rules: - to: - operation: methods: ["GET"] when: - key: request.auth.claims[role] values: ["customer"] EOF oc apply -f AuthorizationPolicy.yaml -n tutorial
Get a token for the role and retry to connect to the service,
token=$(curl https://gist.githubusercontent.com/lordofthejars/f590c80b8d83ea1244febb2c73954739/raw/21ec0ba0184726444d99018761cf0cd0ece35971/token.role.jwt -s) curl -H "Authorization: Bearer $token" $GATEWAY_URL/customer
This results in:
customer => preference => recommendation v1 from 'f11b097f1dd0': 8
Let’s verify the setting and change the AuthorizationPolicy. This will break the authorization, since the token provides roles=customer and we set the Policy to "whereistherole"
cat <<'EOF' > AuthorizationPolicy-Hack.yaml apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "customer" spec: rules: - to: - operation: methods: ["GET"] when: - key: request.auth.claims[role] values: ["whereistherole"] EOF oc replace -f AuthorizationPolicy-Hack.yaml -n tutorial
If you now try to access the service, with the token, which provides "customer" as role, it will lead to an error:
token=$(curl https://gist.githubusercontent.com/lordofthejars/f590c80b8d83ea1244febb2c73954739/raw/21ec0ba0184726444d99018761cf0cd0ece35971/token.role.jwt -s) curl -H "Authorization: Bearer $token" $GATEWAY_URL/customer RBAC: access denied
Copyright © 2020 - 2024 Toni Schmidbauer & Thomas Jungbauer