Understanding Istio Security: Peer Authentication and mTLS for Microservices

@Harsh
8 min readNov 25, 2024

--

In modern microservices architectures, security is paramount. As services interact with each other, sensitive data is constantly transmitted across the network. Istio, a service mesh platform, provides a robust security model that includes authentication, authorization, and audit (AAA). In this blog, we focus on the authentication aspect, specifically peer authentication using Istio’s mutual TLS (mTLS) feature.

We will explore:

  • The 3As of Istio Security.
  • The basics of TLS and how it provides encryption and authentication.
  • The need for mTLS in microservices.
  • How Istio implements peer authentication to secure communication between services.
  • A practical step-by-step guide to enabling mTLS using Istio.

The 3 As of Security in Istio

Istio’s security model addresses three fundamental aspects of secure communication: Authentication, Authorization, and Audit (AAA). Let’s briefly explore each:

1. Authentication

Authentication is about verifying the identity of a service or user. It ensures that only legitimate entities can access the system.

  • Istio supports peer authentication (service-to-service) and request authentication (user-to-service).
  • Peer authentication is achieved using mTLS, while request authentication often uses tokens such as JWT (JSON Web Tokens).
  • By establishing identities for both clients and servers, Istio ensures secure communication.

2. Authorization

Once an entity is authenticated, Istio enforces rules that dictate what the entity is allowed to do.

  • Istio uses AuthorizationPolicies to define access control rules.
  • These policies can control access at the service, namespace, or workload level based on attributes like source, destination, or request content.

For example, an AuthorizationPolicy might allow only specific users or services to access certain endpoints of a microservice.

3. Audit

Audit refers to tracking and monitoring the actions of services and users. It helps identify suspicious activity and aids in compliance with regulations.

  • Istio integrates with tools like Prometheus, Grafana, and Kiali to collect logs, metrics, and tracing information.
  • Detailed logging helps administrators understand system behavior and trace unauthorized or problematic requests.

Understanding TLS

What is TLS?

Transport Layer Security (TLS) is a cryptographic protocol that ensures secure communication over a network. It offers two key capabilities:

  1. Encryption: Protects data from being intercepted and read during transmission.
  2. Authentication: Verifies the identity of the communicating parties, ensuring trust.

In a typical TLS connection:

  • A client initiates a connection to the server.
  • The server presents its certificate to prove its identity.
  • The client optionally verifies itself using a certificate.

How TLS Works

  1. Handshake: The client and server exchange certificates and agree on encryption keys.
  2. Data Encryption: All communication is encrypted using the agreed keys.
  3. Authentication: Certificates validate the parties’ identities.

Introduction to mTLS

What is mTLS in Microservices?

Mutual TLS (mTLS) is an extension of TLS where both the client and the server authenticate each other. Unlike standard TLS, which only verifies the server, mTLS ensures a bidirectional trust relationship.

In a microservices environment, mTLS is critical because services frequently communicate with each other, often without human intervention. mTLS ensures that:

  1. Only trusted services can connect: Prevents unauthorized services from accessing others.
  2. Data integrity and confidentiality: Protects data in transit.

Why mTLS is Essential in Microservices

  1. Dynamic Connections: Services are often created and destroyed dynamically in microservices. mTLS ensures secure connections even in ephemeral environments.
  2. Zero Trust Architecture: Adopts the principle of least privilege by enforcing strict authentication and encryption.
  3. Defense in Depth: Adds another layer of security, reducing reliance on network boundaries alone.

How mTLS Works in Istio

Istio implements mTLS at the proxy level (Envoy sidecars) instead of the application level. Here’s how it works:

  1. Each service proxy (sidecar) is issued an identity in the form of an X.509 certificate by Istio’s Citadel (or Istiod in newer versions).
  2. When one service wants to communicate with another:
  • The client proxy verifies the server proxy’s certificate.
  • The server proxy verifies the client proxy’s certificate.

3. Upon successful validation, communication is encrypted and secure.

Peer Authentication in Istio

Peer authentication is a key aspect of Istio’s authentication model. It focuses on verifying the identity of the service initiating a connection.

Configuring Peer Authentication in Istio

Istio provides fine-grained control over authentication policies. You can configure authentication globally or for specific namespaces or workloads.

Peer authentication policies are defined using Istio’s PeerAuthentication custom resource.

The three types of peer policy modes in Istio are:

  • PERMISSIVE
  • Workloads can accept both mutual TLS and plain text traffic. This mode is useful during migrations when workloads without sidecar cannot use mutual TLS.
  • STRICT
  • Workloads can only accept mutual TLS traffic. You can enable strict mTLS for certain services using PeerAuthentication or DestinationRule.
  • DISABLE
  • Mutual TLS is disabled. You should not use this mode unless you provide your own security solution.

Practical Guide to Enabling mTLS in Istio

We’ll follow the steps to understand the mTLS authentication or peer authentication.

Step 1: Set up the cluster

  • Create two namespaces, foo and bar, and deploy httpbin and curl with sidecars on both of them. This means these both namespaces should have service mesh enabled.
kubectl create ns foo
kubectl label namespace foo istio-injection=enabled
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/httpbin/httpbin.yaml -n foo
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/curl/curl.yaml -n foo
  • bar namespace.
kubectl create ns bar
kubectl label namespace bar istio-injection=enabled
kubectl describe ns bar
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/httpbin/httpbin.yaml -n bar
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/curl/curl.yaml -n bar
  • Create another namespace, legacy, and deploy curl without a sidecar, means don’t enable Istio injection in that namespace.
kubectl create ns legacy
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.24/samples/curl/curl.yaml -n legacy
  • Verify the setup by sending http requests (using curl) from the curl pods, in namespaces foo, bar and legacy, to httpbin.foo and httpbin.bar. All requests should succeed with return code 200.
  • All the request will succeed because there is no peer authentication. No matter whether the namespace have Istio enabled or not, every request will succeed.
for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec "$(kubectl get pod -l app=curl -n ${from} -o jsonpath={.items..metadata.name})" -c curl -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "curl.${from} to httpbin.${to}: %{http_code}\n"; done; done
  • As we can see that legacy namespace does not have Istio enabled, even though all the http request send by it were succeeded.

Step 2: Lock down to mutual TLS by namespace

  • Enable Peer Authentication but before that check whether there is any peer authentication already exist or not.
kubectl get peerauthentication --all-namespaces
  • Create a PeerAuthentication policy to enforce mTLS on foo namespace:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: peer-auth
namespace: foo
spec:
mtls:
mode: STRICT
  • This policy enforces mTLS for all services in the foo namespace.
  • Now, you should see the request from curl.legacy to httpbin.foo failing since legacy did not come under service mesh so it is a unknown request for foo namespace.
  • But on the other hand, bar namespace can able to send request successfully. why?
  • Istio-injected namespace services automatically have Envoy sidecars.
  • These sidecars handle mTLS connections, including certificate exchange, encryption, and authentication.
  • When a service in an Istio-injected namespace tries to send a request to another namespace with STRICT mTLS enabled, the source sidecar establishes an mTLS connection with the destination sidecar.
  • Both sidecars verify each other’s certificates, which are issued by Istio’s Certificate Authority (Citadel or Istiod).
  • If the certificates match and the mTLS handshake succeeds, the communication is allowed.
  • You can lock down workloads in all namespaces to only accept mutual TLS traffic by putting the policy in the system namespace of your Istio installation.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: peer-auth
namespace: istio-system
spec:
mtls:
mode: STRICT
  • Now, both the foo and bar namespaces enforce mutual TLS only traffic, so you should see requests from curl.legacy failing for both.
  • To apply peer authentication to specific workloads, modify the selector field:
apiVersion: security.istio.io/v1beta1  
kind: PeerAuthentication
metadata:
name: peer-auth
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
mtls:
mode: STRICT
  • This policy enforces mTLS for the httpbin workload only.

Benefits of Peer Authentication in Istio

  1. Improved Security: Ensures that only trusted services communicate with each other.
  2. Transparency: Istio manages certificates and keys automatically.
  3. Flexibility: Policies can be applied globally or per workload.
  4. Encryption by Default: All traffic is encrypted without modifying application code

Challenges and Best Practices

Challenges

  1. Certificate Management: Proper rotation and renewal are critical.
  2. Performance Overhead: Encryption adds slight latency to communication.

Best Practices

  1. Use STRICT mode to enforce mTLS wherever possible.
  2. Regularly monitor certificates using Istio tools.
  3. Test policies in staging environments before applying them to production.

Conclusion

Istio’s peer authentication and mTLS capabilities play a crucial role in securing microservices. By enforcing encryption and mutual authentication at the proxy level, Istio simplifies security management while adhering to the principles of zero trust.

This blog covered the basics of TLS, the importance of mTLS in microservices, and a hands-on guide to implementing peer authentication using Istio. By enabling mTLS, you’re taking a significant step toward building a secure, resilient service mesh.

Sign up to discover human stories that deepen your understanding of the world.

--

--

@Harsh
@Harsh

Written by @Harsh

A devOps engineer from India

No responses yet

Write a response