
Note: translation.: This cycle was dedicated to familiarizing us with the capabilities of Istio and demonstrating them in action. — finely tuned routing and network traffic management. Now, we will talk about security: to demonstrate the associated basic functions, the author uses the identity service Auth0, although similar setups can be made with other providers.
We configured a Kubernetes cluster where we deployed Istio and an example microservice application, Sentiment Analysis, thus showcasing Istio's capabilities.
With Istio, we managed to keep the services lightweight, as they do not require the implementation of layers such as retries, timeouts, circuit breakers, tracing, and monitoring. Additionally, we employed advanced testing and deployment techniques: A/B testing, mirroring, and canary releases.

In this new material, we will dive into the final layers on the path to business value: authentication and authorization — and in Istio, it’s a sheer delight!
Authentication and Authorization in Istio
I would never have believed that I would be inspired by authentication and authorization. What can Istio offer from a technological perspective to make these topics engaging and even inspire you?
The answer is simple: Istio shifts the responsibility for these functionalities from your services to the Envoy proxy. By the time requests reach the services, they are already authenticated and authorized, allowing you to focus on writing business-relevant code.
Sounds good? Let's take a look inside!
Authentication with Auth0
We will use Auth0 as the server for identity management and access. It has a trial version, is intuitive to use, and I simply like it. However, the same principles can be applied to any other : KeyCloak, IdentityServer, and many others.
To get started, go to with your account, create a tenant (tenant — a logical unit of isolation, see more in - translator's note) and go to Applications > Default App, selecting Domain, as shown in the screenshot below:

Specify this domain in the file resource-manifests/istio/security/auth-policy.yaml ():
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
name: auth-policy
spec:
targets:
- name: sa-web-app
- name: sa-feedback
origins:
- jwt:
issuer: "https://{YOUR_DOMAIN}/"
jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json"
principalBinding: USE_ORIGIN With this resource, Pilot (one of the three core components of the Control Plane in Istio — ed.) configures the Envoys to authenticate requests before routing them to the services: sa-web-app and sa-feedback. At the same time, the configuration does not apply to the service Envoys, sa-frontendallowing us to keep the frontend unauthenticated. To apply the policy, run the command:
$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” createdGo back to the page and make a request — you will see it end with status 401 Unauthorized. Now let's redirect frontend users to authenticate with Auth0.
Authenticating requests with Auth0
To authenticate end-user requests, you need to create an API in Auth0 that will represent authenticated services (reviews, details, and ratings). To create an API, go to Auth0 Portal > APIs > Create API and fill out the form:

An important piece of information here is Identifier, which we will later use in the script. Let's jot it down as:
- Audience: {YOUR_AUDIENCE}
The remaining necessary details are located on the Auth0 Portal in the section Applications — select Test Application (created automatically along with the API).
Here we will write down:
- Domain: {YOUR_DOMAIN}
- Client Id: {YOUR_CLIENT_ID}
Scroll to the Test Application until you find the text field Allowed Callback URLs (allowed URLs for callback), where we will specify the URL to which the call should be sent after authentication is complete. In our case, it is:
http://{EXTERNAL_IP}/callbackAnd for Allowed Logout URLs (allowed URLs for logout) we will add:
http://{EXTERNAL_IP}/logoutLet's move to the frontend.
Frontend update
Switch to the branch. auth0 repository [istio-mastery]. In this branch, the frontend code has been modified to redirect users to Auth0 for authentication and to utilize the JWT token in requests to the other services. This has been implemented as follows ():
analyzeSentence() {
fetch('/sentiment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token
},
body: JSON.stringify({ sentence: this.textField.getValue() })
})
.then(response => response.json())
.then(data => this.setState(data));
} To switch the frontend to using tenant data in Auth0, open sa-frontend/src/services/Auth.js and replace the values in it that we recorded above ():
const Config = {
clientID: '{YOUR_CLIENT_ID}',
domain:'{YOUR_DOMAIN}',
audience: '{YOUR_AUDIENCE}',
ingressIP: '{EXTERNAL_IP}' // Used for redirect after authentication
}The application is ready. Enter your Docker ID in the commands below when building and deploying the changes made:
$ docker build -f sa-frontend/Dockerfile
-t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0
sa-frontend
$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0
$ kubectl set image deployment/sa-frontend
sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0Try the application! You will be redirected to Auth0, where you need to log in (or sign up), after which you will be sent back to the page from which authenticated requests will be made. If you try the commands mentioned in the earlier parts of the article with curl, you will get the code 401 Status Code, indicating that the request is unauthorized.
Let's take the next step — authorize the requests.
Authorization with Auth0
Authentication allows us to know who the user is, but to find out what they have access to, authorization is required. Istio provides tools for this as well.
As an example, let's create two user groups (see the diagram below):
- Users (users) — with access only to the SA-WebApp and SA-Frontend services;
- Moderators (moderators) — with access to all three services.

The concept of authorization
To create these groups, we will use the Auth0 Authorization extension and use Istio to provide them with different levels of access.
Installing and configuring Auth0 Authorization
On the Auth0 portal, go to the extensions (Extensions) and install Auth0 Authorization. After installation, go to Authorization Extension, and then to the tenant configuration by clicking on the top right and selecting the corresponding menu option (Configuration). Activate groups (Groups) and click the publish rule button (Publish rule).

Creating groups
In the Authorization Extension, go to Groups and create a group Moderators. Since we will consider all authenticated users as regular users, there's no need to create an additional group for them.
Select the group Moderators, click on Add Members, add your main account. Leave some users without any group to ensure their access is denied. (New users can be created manually via Auth0 Portal > Users > Create User.)
Add Group Claim to Access Token
Users have been added to the groups, but this information must also be reflected in the access tokens. To comply with OpenID Connect and at the same time return the groups we need, the token will need to add its . This is implemented through Auth0 rules.
To create a rule, go to the Auth0 Portal to Rules, click on Create Rule and select an empty rule from the templates.

Copy the code below and save it as a new rule Add Group Claim ():
function (user, context, callback) {
context.accessToken['https://sa.io/group'] = user.groups[0];
return callback(null, user, context);
}Note: this code takes the first group of the user defined in the Authorization Extension and adds it to the access token as a custom claim (under its namespace, as required by Auth0).
Go back to the page Rules and check that you have two rules written in the following order:
- auth0-authorization-extension
- Add Group Claim
The order is important because the group field asynchronously gets the rule auth0-authorization-extension and then is added as a claim by the second rule. As a result, the access token looks like this:
{
"https://sa.io/group": "Moderators",
"iss": "https://sentiment-analysis.eu.auth0.com/",
"sub": "google-oauth2|196405271625531691872"
// [truncated for clarity]
} Now you need to configure the Envoy proxy to check user access, where the group will be pulled from the claim (https://sa.io/group) in the returned access token. This is a topic for the next section of the article.
Authorization Configuration in Istio
To enable authorization, you need to turn on RBAC for Istio. We will use the following configuration for this:
apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
name: default
spec:
mode: 'ON_WITH_INCLUSION' # 1
inclusion:
services: # 2
- "sa-frontend.default.svc.cluster.local"
- "sa-web-app.default.svc.cluster.local"
- "sa-feedback.default.svc.cluster.local" Explanations:
- 1 — RBAC is enabled only for the services and namespaces listed in the
Inclusion; - 2 — we list our services.
Apply the configuration with the following command:
$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created Now all services require role-based access control. In other words, access to all services is denied and will result in the response RBAC: access denied. Now let's allow access to authorized users.
Access Configuration for Regular Users
All users should have access to the SA-Frontend and SA-WebApp services. This is implemented using the following Istio resources:
- ServiceRole defines the rights that the user has;
- ServiceRoleBinding determines to whom this ServiceRole applies.
For regular users, we will allow access to certain services ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: regular-user
namespace: default
spec:
rules:
- services:
- "sa-frontend.default.svc.cluster.local"
- "sa-web-app.default.svc.cluster.local"
paths: ["*"]
methods: ["*"] And through regular-user-binding we will apply the ServiceRole to all visitors of the page ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: regular-user-binding
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "regular-user"Does "all users" mean that unauthenticated users will also gain access to the SA WebApp? No, the policy checks the validity of the JWT token.
We will apply configurations:
$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding createdAccess configuration for moderators
For moderators, we want to enable access to all services ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: mod-user
namespace: default
spec:
rules:
- services: ["*"]
paths: ["*"]
methods: ["*"] But we want such rights only for those users whose access token contains the claim https://sa.io/group with the value Moderators ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: mod-user-binding
namespace: default
spec:
subjects:
- properties:
request.auth.claims[https://sa.io/group]: "Moderators"
roleRef:
kind: ServiceRole
name: "mod-user" We will apply configurations:
$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding createdDue to caching in the envoys, it may take a couple of minutes for the authorization rules to take effect. After that, you will be able to verify that users and moderators have different access levels.
Conclusion on this part
Seriously: have you ever seen a simpler, effortless, scalable, and secure approach to authentication and authorization?
Only three Istio resources (RbacConfig, ServiceRole, and ServiceRoleBinding) were required to achieve fine-grained control over authentication and authorization of end users' access to services.
In addition, we moved the burden of these issues from our services to the envoys, achieving:
- a reduction in boilerplate code where security issues and bugs can arise;
- a decreased likelihood of stupid situations where one endpoint became accessible from the outside and forgot to report it;
- eliminating the need to update all services whenever a new role or permission is added;
- ensuring that new services remain simple, secure, and fast.
Output
Istio allows teams to focus their resources on business-critical tasks without adding overhead to services, returning them to a 'micro' status.
The article (in three parts) provided foundational knowledge and a ready-to-use practical guide for getting started with Istio in real projects.
P.S. from the translator
Also read in our blog:
- "Back to Microservices with Istio": , ;
- «»;
- «».
Source: habr.com
