Secure your application with Istio

Despite giving much benefits, microservices need special treatment if it comes to security. There are plenty of dangers and means for unauthorized units to get access to our resources. Every service has to have restricted ingress control. Also, to defend against man-in-the-middle attack, traffic should be encrypted. Istio Security provides a set of solutions to these problems.

Security by default

Istio secures your services by default. It means, that all inbound and outbound traffic is blocked and needs special configuration to take place. You can configure ingress traffic using gateway Istio component and egress in service entry. What's important, you don't need to change the code of your application at all.


Authentication

Istio provides two types of authentication:

  1. Transport, service-to-service authentication - Istio supports mTLS to encrypt inside traffic.
  2. Origin, end-user authentication - Istio supports only JWT validation

Transport authentication

Let's assume that someone hacked into your network. You can prevent getting sensitive information by simply enabling mTLS within your service mesh. From now on, your services will only accept encrypted requests.

Istio automatically installs all necessary certificates in envoy sidecars. To enable mTLS you have to submit policy. You can do it globally or for specified services or namespaces. Here is an example where we enable mTLS for bot service :

kind: "Policy"
metadata:
  name: "bot"
spec:
  targets:
  - name: bot
  peers:
  - mtls: {}

We also need to configure on the client side. We do this in DestinationRule object. In this example we tells bot service to use mTLS:

kind: DestinationRule
metadata:
  name: bot
spec:
  host: bot
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

Origin authentication

Here is an example of policy with JWT user defined:

apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
  name: "jwt-example"
spec:
  targets:
  - name: bot
  peers:
  - mTLS: {}
  origins:
  - jwt:
      issuer: "testing@secure.istio.io"
      jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.0/security/tools/jwt/samples/jwks.json"
  principalBinding: USE_ORIGIN

After submitting this policy, all requests without correct token will be rejected.


Authorization

What if you had enabled mTLS in your service mesh, but someone hacked into one of your services? Istio have a simple solution for that. You can easily restrict access control.

You can enable authorization using RbacConfig object, where you can specify which services should be included or excluded from authorization. Here is an example, where we include all services from default namespace to have authorized access.

kind: RbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'
  inclusion:
    namespaces: ["default"]

To define policies you use ServiceRole and ServiceRoleBinding objects. In ServiceRole you define group of permission. In ServiceRoleBinding you assign this role to certain objects.

Let's take a look at simple example.

ServiceRole

Here's a viewer role that has access only to server service and only using GET method.

kind: ServiceRole
metadata:
  name: service-viewer
  namespace: default
spec:
  rules:
  - services: ["server.default.svc.cluster.local"]
    methods: ["GET"]

ServiceRoleBinding

To bind this role to all users we have to create following binding

kind: ServiceRoleBinding
metadata:
  name: binding-service-allusers
  namespace: default
spec:
  subjects:
  - user: "*"
  roleRef:
    kind: ServiceRole
    name: "service-viewer"

Not everyone is a security expert. If you want to be sure, that your application is totally protected you usually you need to put a lot of work in it. Istio frees you from this and helps you to fully secure your application without making any changes in your code.