oc new-project tutorial
- By: Thomas Jungbauer ( Lastmod: 2021-08-14 )
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.
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+ |
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
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
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 - 2023 Toni Schmidbauer & Thomas Jungbauer
Built with Hugo Learn Theme and Hugo