Bird
Raised Fist0
Kubernetesdevops~10 mins

Mutual TLS for service communication in Kubernetes - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Process Flow - Mutual TLS for service communication
Service A wants to connect to Service B
Service A presents its client certificate
Service B verifies client certificate
Service B presents its server certificate
Service A verifies server certificate
Secure connection established with mutual trust
Data exchange happens
This flow shows how two services authenticate each other using certificates before exchanging data securely.
Execution Sample
Kubernetes
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
spec:
  mtls:
    mode: STRICT
This Kubernetes manifest enables strict mutual TLS for all services in the namespace.
Process Table
StepActionService A StateService B StateResult
1Service A initiates connectionSends client certificateWaiting for client certConnection attempt started
2Service B receives client certificateClient cert sentVerifies client certificateClient authenticated
3Service B sends server certificateWaiting for server certSends server certificateServer cert sent
4Service A verifies server certificateVerifies server certificateServer cert sentServer authenticated
5Mutual TLS handshake completesBoth certificates verifiedBoth certificates verifiedSecure connection established
6Data exchangeEncrypted data sentEncrypted data receivedSecure communication ongoing
💡 Mutual TLS handshake completes successfully, enabling encrypted and authenticated communication.
Status Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 5Final
Service A CertificateNot sentSent to Service BSentWaiting for server certVerified server certMutual TLS establishedSecure communication
Service B CertificateNot sentWaiting for client certClient cert verifiedSent to Service ASentMutual TLS establishedSecure communication
Connection StateDisconnectedConnectingAuthenticating clientAuthenticating serverHandshake completeConnectedSecure connection
Key Moments - 3 Insights
Why does Service B verify Service A's certificate before sending its own?
Service B must confirm Service A is trusted before revealing its own identity to avoid exposing sensitive data. This is shown in step 2 and 3 of the execution_table.
What happens if Service A fails to verify Service B's certificate?
The mutual TLS handshake fails and the connection is not established, preventing insecure communication. This would stop the flow at step 4 in the execution_table.
Why is mutual TLS stronger than one-way TLS?
Because both services authenticate each other, not just the server. This prevents impersonation from either side, as seen in the mutual verification steps 2 and 4.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the state of Service A after step 3?
AClient certificate verified
BSecure connection established
CWaiting for server certificate
DDisconnected
💡 Hint
Check the 'Service A State' column at step 3 in the execution_table.
At which step does the mutual TLS handshake complete?
AStep 4
BStep 5
CStep 6
DStep 3
💡 Hint
Look for the row where both certificates are verified and connection is established.
If Service B does not verify Service A's certificate, what will happen?
AHandshake fails and connection stops
BService B sends server certificate anyway
CConnection proceeds without encryption
DService A retries sending certificate
💡 Hint
Refer to the key moment about verification failure and the execution_table step 2.
Concept Snapshot
Mutual TLS (mTLS) requires both client and server to present certificates.
In Kubernetes, enable mTLS via PeerAuthentication with mode STRICT.
Services verify each other's certificates before exchanging data.
This ensures encrypted, authenticated, and trusted communication.
If verification fails, connection is refused.
Use mTLS to secure service-to-service communication in clusters.
Full Transcript
Mutual TLS for service communication means both services prove their identity using certificates before talking. Service A starts by sending its client certificate to Service B. Service B checks this certificate to make sure Service A is trusted. Then Service B sends its own server certificate back. Service A verifies it. When both sides confirm each other's certificates, they establish a secure connection. This process is called a mutual TLS handshake. After the handshake, data is exchanged securely and encrypted. If either side fails to verify the other's certificate, the connection stops. In Kubernetes, you enable this by applying a PeerAuthentication resource with mtls mode set to STRICT. This setup helps keep service communication safe and trusted inside the cluster.

Practice

(1/5)
1. What is the main purpose of Mutual TLS (mTLS) in Kubernetes service communication?
easy
A. To disable encryption for faster debugging
B. To increase the speed of service communication
C. To allow services to communicate without authentication
D. To encrypt data and verify identities between services

Solution

  1. Step 1: Understand mTLS purpose

    Mutual TLS encrypts data and verifies both client and server identities to secure communication.
  2. Step 2: Compare options

    Only To encrypt data and verify identities between services correctly describes encryption and identity verification, others are incorrect or opposite.
  3. Final Answer:

    To encrypt data and verify identities between services -> Option D
  4. Quick Check:

    mTLS = encrypt + verify identities [OK]
Hint: mTLS means both encryption and identity check [OK]
Common Mistakes:
  • Thinking mTLS only encrypts but doesn't verify identity
  • Confusing mTLS with disabling security
  • Assuming mTLS speeds up communication
2. Which PeerAuthentication mode in Istio allows both encrypted (mTLS) and plain traffic to a service?
easy
A. STRICT
B. PERMISSIVE
C. DISABLE
D. ENFORCED

Solution

  1. Step 1: Recall PeerAuthentication modes

    STRICT enforces mTLS only, PERMISSIVE allows both mTLS and plain, DISABLE turns off mTLS.
  2. Step 2: Match mode to description

    PERMISSIVE mode allows both encrypted and plain traffic, matching the question.
  3. Final Answer:

    PERMISSIVE -> Option B
  4. Quick Check:

    PERMISSIVE = both encrypted and plain allowed [OK]
Hint: PERMISSIVE means allow both secure and insecure traffic [OK]
Common Mistakes:
  • Confusing STRICT with PERMISSIVE
  • Thinking DISABLE allows encrypted traffic
  • Assuming ENFORCED is a valid mode
3. Given this PeerAuthentication YAML snippet:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: myapp
spec:
  mtls:
    mode: STRICT

What happens when a service in namespace myapp receives plain HTTP traffic?
medium
A. The traffic is rejected because mTLS is enforced
B. The traffic is accepted without encryption
C. The traffic is accepted but logged as insecure
D. The traffic is redirected to HTTPS automatically

Solution

  1. Step 1: Analyze PeerAuthentication mode

    The mode is STRICT, which enforces mTLS for all incoming traffic in the namespace.
  2. Step 2: Understand effect on plain HTTP

    Plain HTTP traffic without mTLS will be rejected because encryption and identity verification are mandatory.
  3. Final Answer:

    The traffic is rejected because mTLS is enforced -> Option A
  4. Quick Check:

    STRICT mode rejects plain HTTP [OK]
Hint: STRICT mode blocks non-mTLS traffic [OK]
Common Mistakes:
  • Assuming plain HTTP is accepted in STRICT mode
  • Thinking traffic is redirected automatically
  • Confusing logging with rejection
4. You applied this PeerAuthentication config but your service still accepts plain HTTP traffic:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: test
spec:
  mtls:
    mode: STRICT

What is the most likely reason?
medium
A. The service is in a different namespace than 'test'
B. PeerAuthentication resource is missing the selector field
C. STRICT mode allows plain HTTP by default
D. mTLS is disabled globally in Istio

Solution

  1. Step 1: Check namespace scope

    PeerAuthentication applies only to the specified namespace 'test'. If the service is outside, it won't be affected.
  2. Step 2: Understand effect on service

    If the service is in another namespace, it won't enforce STRICT mode and may accept plain HTTP.
  3. Final Answer:

    The service is in a different namespace than 'test' -> Option A
  4. Quick Check:

    Namespace mismatch causes no mTLS enforcement [OK]
Hint: PeerAuthentication applies per namespace only [OK]
Common Mistakes:
  • Assuming STRICT mode allows plain HTTP
  • Thinking selector is mandatory for namespace-wide policy
  • Ignoring namespace differences
5. You want to enforce mTLS only for service payments in namespace finance, but allow other services to accept plain traffic. Which PeerAuthentication config achieves this?
hard
A.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: permissive-all
  namespace: finance
spec:
  mtls:
    mode: PERMISSIVE
B.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: finance-wide
  namespace: finance
spec:
  mtls:
    mode: STRICT
C.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: payments-mtls
  namespace: finance
spec:
  selector:
    matchLabels:
      app: payments
  mtls:
    mode: STRICT
D.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: payments-disable
  namespace: finance
spec:
  selector:
    matchLabels:
      app: payments
  mtls:
    mode: DISABLE

Solution

  1. Step 1: Understand requirement

    Enforce mTLS STRICT only for 'payments' service, allow others to accept plain traffic.
  2. Step 2: Analyze options

    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: payments-mtls
      namespace: finance
    spec:
      selector:
        matchLabels:
          app: payments
      mtls:
        mode: STRICT
    applies STRICT mode with selector for 'payments' only.
    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: finance-wide
      namespace: finance
    spec:
      mtls:
        mode: STRICT
    enforces STRICT for whole namespace, not desired.
    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: permissive-all
      namespace: finance
    spec:
      mtls:
        mode: PERMISSIVE
    allows both for all services.
    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: payments-disable
      namespace: finance
    spec:
      selector:
        matchLabels:
          app: payments
      mtls:
        mode: DISABLE
    disables mTLS for payments, opposite of requirement.
  3. Final Answer:

    PeerAuthentication with selector for payments and STRICT mode -> Option C
  4. Quick Check:

    Selector + STRICT = mTLS only for selected service [OK]
Hint: Use selector with STRICT mode for specific service enforcement [OK]
Common Mistakes:
  • Applying STRICT mode to whole namespace accidentally
  • Using DISABLE mode when enforcement is needed
  • Not using selector to target specific service