# Secure Service Communication

> **CNPA Domain:** Platform Observability, Security, and Conformance (20%) **Topic:** Secure Service Communication

## Overview

In a microservices architecture, services communicate constantly over the network. By default, this traffic is unencrypted and unauthenticated — any compromised workload can eavesdrop or impersonate another service. **Secure service communication** is the platform capability that ensures every service-to-service connection is:

* **Encrypted** (confidentiality)
* **Authenticated** (identity verification)
* **Authorized** (only permitted callers succeed)

Platform teams implement this transparently through **mutual TLS (mTLS)** and **service mesh**, so application developers don't manage certificates themselves.

***

## The Problem: East-West Traffic

```
                 North-South (external)
                      ↓
              [Ingress / API Gateway]
                      ↓
    ┌─────────────────────────────────────┐
    │         Kubernetes Cluster          │
    │                                     │
    │   [Service A] ──?──▶ [Service B]    │  ← East-West
    │       ↕                   ↕         │
    │   [Service C] ──?──▶ [Service D]    │  ← East-West
    └─────────────────────────────────────┘
```

East-west traffic between services is the **largest attack surface** in a microservices platform. Without mTLS:

* A compromised pod can intercept traffic from other services
* Services cannot verify the identity of their callers
* Network-based attacks (MITM, impersonation) are possible inside the cluster

***

## Mutual TLS (mTLS)

**TLS** (Transport Layer Security) encrypts a connection. **Mutual TLS** additionally requires both parties to present certificates — the client authenticates the server AND the server authenticates the client.

```
Standard TLS:
  Client ──validates server cert──▶ Server
  
Mutual TLS:
  Client ──validates server cert──▶ Server
  Server ──validates client cert──▶ Client
  ↓
  Secure, authenticated, encrypted channel
```

### How Service Mesh Implements mTLS

Without service mesh, each application must manage its own certificates. With a service mesh, a **sidecar proxy** (Envoy) intercepts all traffic and handles TLS transparently:

```
Pod A:                                    Pod B:
┌─────────────────────┐                  ┌─────────────────────┐
│  App Container      │                  │  App Container      │
│  (plain HTTP :8080) │                  │  (plain HTTP :8080) │
│         ↓           │                  │         ↑           │
│  Envoy Sidecar      │──── mTLS ──────▶│  Envoy Sidecar      │
│  (encrypts traffic) │                  │  (decrypts traffic) │
└─────────────────────┘                  └─────────────────────┘
```

The application code communicates on `localhost` with no TLS knowledge. The service mesh handles everything.

***

## Service Mesh: Istio

[Istio](https://istio.io/) is the most widely deployed service mesh. Platform teams install Istio on the cluster and enforce mTLS across namespaces.

### Enabling mTLS Cluster-Wide

```yaml
# Enforce mTLS for all services in the mesh
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system  # Applies cluster-wide
spec:
  mtls:
    mode: STRICT  # Reject all non-mTLS traffic
```

```yaml
# Per-namespace strict mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: payments
spec:
  mtls:
    mode: STRICT
```

### Authorization Policies

Istio `AuthorizationPolicy` restricts which services can communicate:

```yaml
# Only allow payment-service to call inventory-service
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: inventory-access
  namespace: inventory
spec:
  selector:
    matchLabels:
      app: inventory-service
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - cluster.local/ns/payments/sa/payment-service
```

***

## Service Mesh: Linkerd

[Linkerd](https://linkerd.io/) is a CNCF graduated, simpler alternative to Istio with automatic mTLS requiring zero configuration after installation.

```bash
# Install Linkerd
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -

# Annotate namespace — automatic mTLS for all pods
kubectl annotate namespace payments \
  linkerd.io/inject=enabled
```

All pods in annotated namespaces automatically get mTLS with zero application changes.

***

## Kubernetes Network Policies

Even before implementing a service mesh, **NetworkPolicies** provide Layer 3/4 traffic control:

```yaml
# Default deny all ingress in payments namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: payments
spec:
  podSelector: {}
  policyTypes:
    - Ingress

---
# Allow ingress only from api-gateway
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-gateway
  namespace: payments
spec:
  podSelector:
    matchLabels:
      app: payment-service
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              app: api-gateway
      ports:
        - protocol: TCP
          port: 8080
```

> **Note:** NetworkPolicies require a CNI plugin that supports them (Calico, Cilium, Weave).

***

## Zero-Trust Networking

**Zero-trust** is the security model that assumes no network location is trusted by default:

> "Never trust, always verify"

| Principle             | Implementation                                |
| --------------------- | --------------------------------------------- |
| **Verify explicitly** | mTLS identity for every service call          |
| **Least privilege**   | AuthorizationPolicies limit permitted callers |
| **Assume breach**     | Network policies segment blast radius         |

Platform teams implement zero-trust by combining:

1. **mTLS** (via service mesh) for authentication
2. **AuthorizationPolicies** for access control
3. **NetworkPolicies** for network segmentation
4. **External secrets** to avoid credential leakage

***

## Certificate Management

Service mesh tools manage short-lived certificates automatically. For platform-level certificate authority:

```yaml
# cert-manager: automated TLS certificate lifecycle
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: payment-service-tls
  namespace: payments
spec:
  secretName: payment-service-tls
  duration: 24h        # Short-lived cert
  renewBefore: 1h
  issuerRef:
    name: platform-ca
    kind: ClusterIssuer
  dnsNames:
    - payment-service.payments.svc.cluster.local
```

***

## Key Takeaways

* East-west (service-to-service) traffic is the primary attack surface inside a Kubernetes cluster
* **mTLS** provides both encryption and mutual identity verification for service communication
* **Service meshes** (Istio, Linkerd) implement mTLS transparently via sidecar proxies — no application code changes
* **Istio AuthorizationPolicies** enforce which service identities are permitted to call which services
* **NetworkPolicies** provide network segmentation at L3/L4 as a complementary security layer
* **Zero-trust** = verify every connection, grant least privilege, assume breach

***

## Further Reading

* [Istio Security Documentation](https://istio.io/latest/docs/concepts/security/)
* [Linkerd mTLS](https://linkerd.io/2.14/features/automatic-mtls/)
* [Cilium Network Policies](https://docs.cilium.io/en/stable/network/kubernetes/policy/)
* [cert-manager Documentation](https://cert-manager.io/docs/)
* → Next: [Policy Engines for Platform Governance](https://blog.htunnthuthu.com/getting-started/fundamentals/platform-engineering-101/platform-engineering-101-policy-engines)
