Service Mesh Platform  ·  View 07 of 31  ·  3 · Structure

Layered Architecture

Five layers, from declared intent to telemetry, with the packages that implement each.

Editable source SVG draw.io All views
Intent and governance Intent repositories Forgejo · signed Policy checks OPA · impact replay Argo CD one per site · waves Argo Rollouts weights owner Control plane Kubernetes API etcd · per cluster Admission guards Gatekeeper · VAP istiod compile · delta xDS Identity plane Offline root HSM · 10 years OpenBao PKI cluster intermediates SPIRE server 7-day signing CA SPIRE agent per node · attests Data plane Cilium L3/L4 policy · BGP Egress gateway declared hosts East-west gateway SNI passthrough Envoy sidecar native sidecar Observability and cost OpenCost per-team report Thanos 15 d · 13 mo Tempo traces · 7 d OTel collector node · bounded ClickHouse access · issuance apply delta xDS SVID · SDS telemetry Layered Architecture Data store Decision point Application we own Security / platform Interface / broker synchronous event / async Each layer depends only on the layers above it for change, and on nothing above it for forwarding a request. v 1.0 · owner Platform Networking Architecture · date 2026-09

Decisions

  • The identity plane is its own layer and does not share a process with the control plane. istiod compiles configuration and holds no signing key; SPIRE issues identities and knows nothing about routes.
  • Cilium sits in the data plane as a second enforcement point. It is weaker than the mesh (L3/L4, no identity from certificates) and it is independent of it, which is the property an emergency block needs.
  • Argo CD runs one instance per site, so no site's clusters need another site's control loop to change.

Why this shape lasts

  • The seams between layers are open standards: Kubernetes objects, xDS, the SPIFFE Workload API and OTLP. A layer's implementation can change without the layers either side of it noticing.

Deliberately out

  • A service catalogue product. Dependencies are declared in the intent repositories next to routes, because a declaration that lives in a different system from the configuration it drives drifts from it.