Deployment Architecture

One binary does not mean one deployment. The same 16 MB artifact deploys across isolated Kubernetes planes — giving you smaller blast radii than multi-service architectures.

Addressing the “Single Point of Failure”

Enterprise security teams often assume a single binary means everything fails together. The opposite is true.

The Key Insight

The binary is the constant. The deployment topology is the variable. A single binary deployed across four isolated node pools with distinct network policies gives you smaller blast radii than four different services with shared databases and porous network boundaries. Enterprise architects confuse artifact count with deployment topology — they are independent concerns.

?

“Everything in one binary means everything fails together.”

This conflates the build artifact with the runtime topology. Each ZenoAuth pod is deployed independently — a crash in the Auth Plane cannot propagate to the Admin or Break-Glass planes. They run on separate node pools, behind separate Envoy Gateway fleets, with separate Kubernetes namespaces and network policies.

?

“A vulnerability in auth means admin is compromised too.”

With interface splitting, an RCE in the auth flow gives the attacker access to one pod in the Auth Plane. NetworkPolicy blocks all egress except PostgreSQL. There is no network path to Admin or PIM planes — they are behind a separate Gateway that only accepts traffic from VPN CIDRs.

The real risks are operational, and they are eliminated.

IAM downtime comes from misconfigured network policies between microservices (eliminated: no east-west traffic), version skew between identity services (eliminated: single artifact), dependency failure like Redis or Infinispan (eliminated: PostgreSQL only), and slow coordinated rollouts (eliminated: one Deployment per plane).

Single Binary vs. Multi-Service

Every advantage flows from having one artifact, one build pipeline, one version.

Concern
Multi-Service
ZenoAuth
Why It Matters
CVE Surface Area
N binaries × M dependencies
1 binary, statically linked
Fewer dependencies = fewer attack vectors
Supply Chain Risk
N separate CI pipelines
1 build, 1 SBOM
One audit covers everything
Version Skew
Services may disagree on schema
Impossible
Every pod runs the exact same version
Rollback
Coordinated across services
Single kubectl rollout undo
Seconds, not hours
East-West Traffic
Inter-service APIs (often unencrypted)
None — pods talk only to PostgreSQL
No lateral movement after compromise
Memory Safety
JVM GC pauses, C buffer overflows
Rust: compile-time safety, no GC
Entire class of CVEs eliminated
Runtime Dependencies
JVM + Redis + Elasticsearch + Infinispan
PostgreSQL. That's it.
Each dependency is a failure mode

Interface-Split Reference Architecture

The same container image, deployed four ways. Route exposure is controlled at the infrastructure layer — not by compiling different binaries.

ZenoAuth interface-split deployment: four planes (Auth, Admin, PIM, Break-Glass) behind separate Envoy Gateways, all running the same binary, connected to PostgreSQL HA

Powered by Kubernetes Gateway API with Envoy Gateway as the data-plane implementation.

Four Planes of Operation

Every pod runs the identical binary. The infrastructure decides what each pod serves.

Plane A

Auth Plane — Public-Facing

The highest-throughput plane. Handles every OAuth authorize, token, introspect, and userinfo request. Horizontally scalable — adding pods is purely horizontal since there is no inter-service east-west traffic.

Routes /auth/* /oauth/* /.well-known/* /scim/v2/*
Traffic source Internet (end users, relying parties)
Replicas 3–20+ (HPA)
Security Rate limiting, session affinity
Plane B

Admin Plane — Internal

Where operators manage users, rotate keys, configure RBAC, and review audit logs. Isolated behind a VPN-only Gateway — a compromise of the public Auth Plane does not grant access to administrative operations.

Routes /api/v1/* /admin/*
Traffic source Admin UI, CI/CD pipelines
Replicas 2–3
Security VPN CIDRs only
Plane C

PIM Plane — Privileged Operations

Handles just-in-time access elevation — temporary admin privileges with approval workflows and time-bounded SD-JWT credentials. Low-volume but high-sensitivity. Can run on hardened nodes with additional OS-level controls.

Routes /api/v1/pim/*
Traffic source Internal service mesh
Replicas 2 (active-active)
Security Internal mesh CIDRs, hardened nodes
Plane D

Break-Glass Plane — Emergency Access

The emergency access path when normal authentication is unavailable. Operates independently on its own Gateway and node pool. Remains operational even if Auth, Admin, and PIM planes are all down.

Routes /api/v1/pim/break-glass /auth/emergency-*
Traffic source On-call jump hosts only
Replicas 1–2
Security 2–3 jump host IPs only

How It Works: Gateway API + Envoy

The Kubernetes Gateway API's role-oriented model maps naturally to interface splitting.

Role-Based Infrastructure

Each team owns their layer. Separation of concerns is enforced by the API itself — not by convention or documentation.

Role Mapping
# Who runs the proxies? Infra Team → GatewayClass (Envoy Gateway) # What listeners exist? Platform Team → Gateway (public / internal / breakglass) # Which paths go where? App Team → HTTPRoute (per-plane route tables) # Who can connect? Security Team → SecurityPolicy (IP allowlists, TLS, auth)

Three Separate Envoy Fleets

Each Gateway provisions its own Envoy deployment. A crash or resource exhaustion in the public Envoy cannot affect the internal or break-glass listeners.

Physical Isolation Layers

  1. Separate Envoy fleets — no shared proxy infrastructure
  2. Separate Kubernetes namespaces — RBAC per plane
  3. Separate node pools — kernel-level isolation
  4. NetworkPolicy per namespace — L3/L4 defense in depth
  5. SecurityPolicy per Gateway — IP allowlists, rate limits
  6. ReferenceGrants — explicit cross-namespace routing permission

Blast Radius Analysis

Compromise of any single plane gives the attacker exactly this — and no more.

What an attacker cannot do

No network access to other planes

NetworkPolicy blocks all pod-to-pod traffic between namespaces

No path through other Gateways

Each Gateway runs its own Envoy fleet — no shared proxy

No Kubernetes API access

Minimal ServiceAccount RBAC, no cluster-level permissions

No filesystem writes

readOnlyRootFilesystem: true enforced on all pods

No privilege escalation

allowPrivilegeEscalation: false, all capabilities dropped, non-root UID

Database access — mitigated

Row-Level Security

Multi-tenant isolation at the database layer. Queries are scoped to the requesting org.

Compile-time SQL checking

sqlx verifies all queries against the schema at compile time. SQL injection is a compile error.

Connection-level TLS

All database connections use sslmode=require. No plaintext wire protocol.

Encrypted secrets at rest

Signing keys stored with HKDF-derived encryption. Key material is never in plaintext.

Separate connection pools

Resource exhaustion on Auth Plane's pool cannot starve Break-Glass.

Scaling & Resource Efficiency

Rust's zero-cost abstractions mean dramatically lower resource requirements.

Per-Pod Resource Requirements

Plane CPU Request Memory Request Memory Limit
Auth 250m 64 Mi 256 Mi
Admin 100m 48 Mi 128 Mi
PIM 100m 48 Mi 128 Mi
Break-Glass 100m 48 Mi 128 Mi

A single pod uses ~50 MB at steady state. Compare to Keycloak's 512 MB minimum heap.

Horizontal Scaling Targets

Throughput Auth Pods Admin Total Memory
100 req/s 2 2 ~0.5 GB
1,000 req/s 5 2 ~1.3 GB
10,000 req/s 15 3 ~3 GB
50,000+ req/s 20+ (HPA) 3 ~5 GB

An equivalent Keycloak HA deployment at 1,000 req/s requires 12+ GB of memory.

HA Comparison

How ZenoAuth's interface-split deployment compares to alternatives.

Dimension
ZenoAuth
Keycloak
Auth0
Minimum HA footprint
2 pods + PG + Envoy
3 pods + PG + Infinispan + Redis
Vendor-managed
Memory per pod
50–64 MB
512 MB–2 GB
N/A
Inter-service traffic
None (pods → PG only)
Infinispan clustering
N/A
Interface splitting
Gateway API HTTPRoute
Separate instances, separate configs
Not possible
Break-glass isolation
Dedicated Gateway + plane
No built-in PIM
No built-in PIM
Signing key sync
Automatic via PostgreSQL
Infinispan replication
Vendor-managed
Full isolation option
SCIM-SCIM replication
Manual export/import
Not possible
Rollback
kubectl rollout undo
Coordinated multi-service
Vendor-controlled
Supply chain audit
1 cargo audit, 1 SBOM
JVM + 200+ transitive deps
No visibility

Progressive Deployment

Start simple. Graduate to interface splitting when your security posture requires it.

Step 1: Minimal HA

Three identical pods behind a single Gateway. Zero-downtime rolling updates, automatic key rotation, PostgreSQL advisory locks for distributed jobs.

Minimal HA (3 Pods)
# Single Gateway, single HTTPRoute apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute spec: parentRefs: - name: zenoauth-gateway rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: zenoauth port: 80 # 3 pods across availability zones replicas: 3 topologySpreadConstraints: - topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule

Step 2: Interface Split

Same binary, same image tag, deployed across separate namespaces and node pools. Each plane gets its own Gateway, SecurityPolicy, and network boundary.

What changes (the binary does not)

  • 1. Add namespaces — one per plane, with pod-security enforced
  • 2. Add Gateways — public, internal, breakglass
  • 3. Add HTTPRoutes — per-plane path matching
  • 4. Add SecurityPolicies — IP allowlists per Gateway
  • 5. Add NetworkPolicies — L3/L4 namespace isolation
  • 6. Deploy to node pools — taints + tolerations per plane

One Binary. Four Planes. Zero Version Skew.

Read the full deployment design document or explore the technical architecture.

Technical Architecture Security Model Talk to an Architect