Architecture

System design, components, and data flow of the Zentinel Control Plane.

System Overview

┌─────────────────────────────────────────────────────────────┐
│                    Control Plane (Phoenix)                   │
├─────────────┬─────────────┬─────────────┬──────────────────┤
│  REST API   │  LiveView   │  Compiler   │  Rollout Engine  │
│  (JSON)     │  UI (WS)    │  (Oban)     │  (Oban, 5s tick) │
├─────────────┴─────────────┴─────────────┴──────────────────┤
│  Events & Notifications  │  Observability  │  Analytics     │
│  (Slack, PD, Teams, WH)  │  (SLOs, Alerts) │  (WAF, Reqs)  │
└──────┬──────┬─────────────┴───────┬─────┴────────┬─────────┘
       │      │                     │              │
       │   ┌──┴─────────────┐   ┌──┴──────────────┘
       │   │  PostgreSQL     │   │  MinIO / S3
       │   │  (SQLite dev)   │   │  (Bundle Storage)
       │   └─────────────────┘   └────────────────────
       │
┌──────┴──────────────────────────────────────────────────────┐
│                      Zentinel Nodes                          │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │
│  │ Node 1  │  │ Node 2  │  │ Node 3  │  │ Node N  │  ...   │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │
└─────────────────────────────────────────────────────────────┘

Core Components

REST API

Three consumer classes:

ConsumerAuthBase Path
OperatorAPI key/api/v1/projects/:slug/
NodeNode key / JWT/api/v1/nodes/:id/
WebhookHMAC signature/api/v1/webhooks/

LiveView UI

Real-time web interface over WebSocket. Org-scoped routes: /orgs/:org_slug/projects/:project_slug/.... Covers dashboards, node management, bundle diff viewer, rollout tracking, service editor, topology graph, WAF dashboard, SLOs, alerts, and audit logs.

Compiler Service

Runs as an Oban background job (CompileWorker):

  1. Validates KDL config via zentinel validate
  2. Assembles .tar.zst archive (config, manifest, CA certs, plugins)
  3. Uploads to S3-compatible storage
  4. Signs with Ed25519 (optional)
  5. Generates CycloneDX 1.5 SBOM
  6. Scores risk against previous bundle

Rollout Engine

Self-rescheduling Oban worker (TickWorker), ticks every 5 seconds per active rollout.

StrategyBehavior
RollingFixed-size batches with health checks between each
CanaryProgressive traffic ramp with statistical analysis
Blue-GreenStandby slot deployment, traffic shift, swap
All at OnceSimultaneous deployment to all nodes

Health gates between batches: heartbeat status, error rate, P99 latency, CPU%, memory%.

Data Flow

Bundle Deployment

Operator creates bundle → CompileWorker validates + assembles + uploads
    → Bundle status: "compiled"
    → Operator creates rollout
    → Approval workflow (if configured)
    → TickWorker deploys in batches
    → Nodes poll, download from S3, activate, report via heartbeat

Node Communication

Pull-based model — nodes initiate all communication:

OperationEndpointFrequency
RegistrationPOST /projects/:slug/nodes/registerOnce
HeartbeatPOST /nodes/:id/heartbeatEvery 10-30s
Bundle pollGET /nodes/:id/bundles/latestEvery 5-30s
JWT refreshPOST /nodes/:id/tokenOn expiry
MetricsPOST /nodes/:id/metricsPeriodic
WAF eventsPOST /nodes/:id/waf-eventsPeriodic

Multi-Tenancy

Organization
├── Members (admin, operator, reader)
├── Signing Keys (Ed25519 for JWT)
├── SSO Providers (OIDC, SAML)
└── Projects
    ├── Environments (dev → staging → production)
    ├── Nodes, Bundles, Rollouts
    ├── Services, Upstream Groups, Certificates
    ├── Auth Policies, WAF Policies, Middlewares
    ├── Plugins, Secrets
    ├── Notifications, SLOs, Alerts
    └── Audit Logs

Background Jobs

Powered by Oban. Queues: default (10), rollouts (5), maintenance (2).

WorkerSchedulePurpose
CompileWorkerOn demandBundle validation and assembly
TickWorkerEvery 5sRollout state machine
StalenessWorkerPeriodicMark offline nodes (120s threshold)
DriftWorkerEvery 30sConfig drift detection
SliWorkerEvery 5 minSLI computation
AlertEvaluatorEvery 30sAlert rule evaluation
RollupWorkerHourlyMetric aggregation
WafBaselineWorkerHourlyWAF statistical baselines
WafAnomalyWorkerEvery 15 minZ-score anomaly detection

Database & Storage

  • Database: PostgreSQL (production), SQLite (development) — transparent via Ecto
  • Storage: S3-compatible — path: bundles/{project_id}/{bundle_id}.tar.zst
  • Downloads: Presigned S3 URLs (no proxy through control plane)