Overview & architecture

Dodona is a gRPC-first application substrate where progressive delivery and provable data sovereignty are native primitives — able to run on top of the cloud you already have.

The problem

The parts of Kubernetes people actually fight with — service routing, releases, identity, traffic policy — are assembled from four leaky layers stacked on top of each other:

Service (L4 VIP) + kube-proxy/iptables + CoreDNS + bolt-on Istio/Envoy sidecars

Each layer translates the layer below into something closer to what you wanted. The thing you actually wanted — "route this request to the right version of the right service, securely, and prove where the data went" — is an L7 concern, and the conventional stack only gets there by gluing a second control plane (a service mesh) onto the first, plus a flag SaaS in app code, plus a rollout operator driving the mesh through CRDs.

Dodona's bet: if identity and an L7 gRPC data plane are the substrate instead of add-ons, those layers collapse into one coherent thing — and progressive delivery and data sovereignty fall out of it in one place.

One brain, two skins, two drivers

┌─────────────────────────┐      ┌──────────────────────────┐
│ SKIN 1: native gRPC API │      │ SKIN 2: emulated K8s API │   ← front-ends
│ (new services)          │      │ (legacy workloads · roadmap)│
└────────────┬────────────┘      └────────────┬─────────────┘
             └───────────────┬────────────────┘
                             ▼
       ┌────────────────────────────────────────────────┐
       │  THE BRAIN  (owned — the differentiator)        │
       │  discovery · identity · L7 routing              │   ← one control plane
       │  progressive-delivery & sovereignty policy      │
       └────────────────────────────────────────────────┘
                             ▲
             ┌───────────────┴────────────────┐
┌────────────┴────────────┐      ┌────────────┴─────────────┐
│ DRIVER 1: k8s-driver    │      │ DRIVER 2: cloud-driver   │   ← back-ends
│ run on EKS/GKE (rented) │      │ run on EC2/GCE (roadmap) │
└─────────────────────────┘      └──────────────────────────┘
  • Two skins (front-ends): a native gRPC API for new services, and — on the roadmap — an emulated Kubernetes API that hosts the real kube-apiserver for legacy workloads. Both funnel into one brain.
  • One brain (owned): endpoint registry, identity, L7 routing, and the progressive-delivery / sovereignty policy engine. The architectural invariant: there is exactly one control plane and one capacity view under both skins.
  • Drivers (back-ends): Kubernetes and cloud/static discovery drivers already register endpoints into the brain. Live autoscaling and broader provider actuation are later driver-framework work.

The data plane: proxyless gRPC

The gRPC library itself is the data plane. In Rust this is DonaChannel, a tower Service that any generated typed gRPC client runs on; in Go it is a connection-level interceptor. Either way, every call executes the same pipeline in your process:

1. context     — request attributes plus authenticated mTLS/SPIFFE identity where present
2. constraint  — hard: residency filters the eligible endpoint set; deny + audit
3. selection   — soft: flag rules (sticky bucketing), else canary weights
4. balance     — pick a ready endpoint of the chosen variant

This is stronger than a sidecar, not just leaner: there is no proxy hop to pay for and no sidecar to bypass. Enforcement also runs in the serving process (a server-side interceptor), so even traffic that skips Dodona routing entirely is still policed — that is what makes sovereignty provable rather than configured.

Honest costs of proxyless: native coverage is gRPC/HTTP2; each SDK language is a maintenance commitment (Go and Rust exist and are held to a shared conformance contract); non-gRPC traffic goes through a proxy fallback driver. The current xDS adapter serves state-of-the-world ADS/CDS/EDS; LDS/RDS/delta export is still future work.

The control plane

The brain (donad) keeps an endpoint registry fed by streaming leases — the registration stream is the liveness signal, so endpoints vanish from the routing table the moment a workload dies. Config fans out over per-service WatchConfig streams: each client subscribes to exactly the services it calls and receives full snapshots only for those. That per-client scoping is the delta-xDS discipline that avoids the config-blast-radius ceiling, applied from day one.

The SDK batch-reports call outcomes, flag exposures, and audit events back to the brain. Outcomes feed rolling per-variant health windows; the canary controller judges those windows to step, promote, or roll back a rollout. Flags, ingress, shared-service records, artifacts, releases, deployments, cells, and the audit chain persist when donad --data-dir is set. Multi-replica brain HA is still later store integration work.

What exists today

Implemented, tested, runnable, and reflected in the 2026-07-07 audit:

  • Rust workspace (rust/): 28 crates, including the brain, proxyless SDK, deployment pipeline, identity, sovereignty, store, xDS, agent, ingress, edge, auth, console, observe, drivers, scheduler, CLI, demo, e2e, and Directory relay/connector crates.
  • Deployment pipeline: artifacts, releases, deployment records, manual holds, rollout actions, scheduling-tag checks, and deployment mutation audit.
  • SPIFFE and federation identity: token-gated SVIDs, scoped join tokens, node attestation, cells, bundles, revocation, and workload SVID grants, with documented verifier seams.
  • Ingress, edge, auth, and console: public HTTP routing, route auth, Cloudflare DNS/cert reconciliation, a minimal auth helper, and operator dashboard/API/MCP surfaces.
  • Observe: gRPC ingest/query, memory and ClickHouse stores, spool handling, service/log/metric/trace/error/Kubernetes query APIs, and an agent collect stream. Native OTLP receiver and browser explorers are not implemented yet.
  • Go reference implementation (phase0/): the original thesis proof and cross-language conformance peer. It does not have deployment, federation, or observe wrapper APIs.
Scope honesty. The scheduler and live placement loop, full Kubernetes emulation skin, OTLP receiver, observability explorers, Directory product, live-cloud autoscaling, RBAC/SSO, and hosted distribution are not shipped. The roadmap says which stage owns each.

Next steps

  • Quickstart — run the five-scenario demo in Go or Rust.
  • Concepts — flags & sticky bucketing, the canary state machine, residency & audit, endpoint leases.
  • Control-plane API — the proto surface.