Zero-Trust Architecture: Hardening Multi-Cloud Kubernetes Clusters

Zero-Trust Architecture: Hardening Multi-Cloud Kubernetes Clusters

In a perimeter-less cloud-native world, zero-trust is not a product — it is an operating model. Every workload, service account, and inter-pod communication path must be treated as untrusted by default. Kubernetes, despite its orchestration power, ships with permissive defaults that are catastrophically dangerous at enterprise scale without deliberate hardening.

This post outlines the GurkhaX zero-trust methodology for multi-cloud Kubernetes environments, covering network segmentation, workload identity, secrets management, and runtime anomaly detection.


1. Network Policy: Deny-All as the Baseline

Kubernetes has no default network isolation. Without explicit NetworkPolicy objects, every pod can communicate with every other pod across all namespaces.

Start with a global deny-all baseline:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

Then grant communication only along declared trust paths. For example, allowing the payments service to reach the database tier:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-payments-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: payments-service
      ports:
        - protocol: TCP
          port: 5432

Use Cilium or Calico for L7-aware network policies that can filter on HTTP methods, paths, and gRPC calls — far beyond what the standard CNI spec allows.


2. Workload Identity: IRSA, Workload Identity Federation, and SPIFFE

Never mount long-lived cloud credentials into pods. Instead, use cloud-native workload identity mechanisms:

  • AWS EKS: IAM Roles for Service Accounts (IRSA) via OIDC federation
  • GKE: Workload Identity Federation binding Kubernetes service accounts to GCP IAM roles
  • Azure AKS: Azure AD Workload Identity (formerly AAD Pod Identity)

Annotate your service account to bind the IAM role:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: s3-reader
  namespace: data-pipeline
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/s3-read-only-role

For multi-cloud environments, deploy SPIRE (SPIFFE Runtime Environment) as your workload identity fabric — issuing short-lived X.509 SVIDs to every workload regardless of cloud provider.


3. Service Mesh mTLS: Istio or Linkerd

Enforce mutual TLS (mTLS) between all services using a service mesh. This ensures:

  1. Every service authenticates before communicating
  2. Traffic is encrypted in-transit even within the cluster
  3. Authorization policies can be enforced at the L7 layer

Istio PeerAuthentication to enforce strict mTLS across a namespace:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: strict-mtls
  namespace: production
spec:
  mtls:
    mode: STRICT

Add AuthorizationPolicy to restrict which services can call which endpoints:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: payments-authz
  namespace: production
spec:
  selector:
    matchLabels:
      app: payments-service
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/api-gateway"]
      to:
        - operation:
            methods: ["POST"]
            paths: ["/v1/charge", "/v1/refund"]

4. Secrets Management: Never Store Secrets in etcd

Kubernetes secrets are base64-encoded — not encrypted — by default. Any actor with get secret RBAC privileges can exfiltrate credentials trivially.

Mandatory controls:

  • Enable etcd encryption at rest using AES-256 or KMS-provider envelope encryption
  • Inject secrets via HashiCorp Vault Agent Injector or External Secrets Operator integrated with AWS Secrets Manager / GCP Secret Manager
  • Audit secret access using kubectl audit-log with alerting on get/list verbs against secret resources

5. Runtime Threat Detection with Falco

Deploy Falco to detect anomalous workload behavior at the syscall level:

- rule: Unexpected Outbound Connection from Pod
  desc: A pod is making an unexpected outbound connection
  condition: >
    outbound and container and not (proc.name in (allowed_processes))
    and not fd.sip in (trusted_ips)
  output: >
    Unexpected outbound connection from pod (user=%user.name command=%proc.cmdline
    connection=%fd.name container=%container.name image=%container.image.repository)
  priority: WARNING

Route Falco alerts into your SIEM (Elastic, Splunk, or Chronicle) via Falcosidekick for enrichment and automated response playbooks.


Zero-Trust Hardening Checklist

  • Default-deny NetworkPolicy in all namespaces
  • Workload identity via IRSA / GKE WIF / SPIRE — no static credentials
  • Service mesh mTLS enforced in STRICT mode
  • etcd encryption enabled with external KMS provider
  • Secrets injected via Vault or External Secrets Operator
  • Falco deployed with custom rules and SIEM integration
  • Pod Security Standards (Restricted profile) enforced via admission controller
  • RBAC least-privilege audit run quarterly

GurkhaX runs Kubernetes security posture assessments and full zero-trust architecture implementations for enterprise clients. Contact our team to schedule an infrastructure security review.