Skip to content

Architecture Overview

System Diagram

Module Boundaries

Norn v2 is split into three independently built modules:

API (v2/api/)

The Go API server. Handles app discovery, deploy pipeline orchestration, Nomad job management, secrets, and real-time event broadcasting.

v2/api/
├── main.go            # Entry point, routing, middleware
├── config/            # Environment-based configuration
├── store/             # PostgreSQL database layer
├── handler/           # HTTP request handlers
├── pipeline/          # Deploy pipeline orchestrator
├── nomad/             # Nomad client and job translator
├── consul/            # Consul client for service discovery
├── hub/               # WebSocket event hub
├── saga/              # Saga event log system
├── secrets/           # SOPS-based secrets manager
├── storage/           # S3-compatible object storage client
├── auth/              # CF Access JWT validator
└── model/             # Shared types (InfraSpec, Deployment, etc.)

CLI (v2/cli/)

The Charm-powered terminal client. Uses Bubble Tea for TUI rendering, Lip Gloss for styling, and Cobra for command structure.

v2/cli/
├── main.go
├── cmd/               # Cobra command definitions
│   ├── root.go
│   ├── status.go
│   ├── app.go
│   ├── deploy.go
│   ├── restart.go
│   ├── rollback.go
│   ├── scale.go
│   ├── logs.go
│   ├── health.go
│   ├── stats.go
│   ├── secrets.go
│   ├── snapshots.go
│   ├── cron.go
│   ├── invoke.go
│   ├── saga.go
│   ├── validate.go
│   ├── forge.go
│   ├── endpoints.go
│   ├── stream.go
│   └── version.go
└── api/               # HTTP client for the Norn API

UI (v2/ui/)

React 19 + Vite 7 + TypeScript dashboard. Communicates with the API over REST and WebSocket.

v2/ui/
├── src/
│   ├── components/    # React components (AppCard, DeployPanel, etc.)
│   ├── hooks/         # Custom hooks (useWebSocket, useApps, etc.)
│   ├── pages/         # Route pages
│   └── api/           # API client functions
├── index.html
├── vite.config.ts
└── package.json

API Endpoints

General

MethodPathDescription
GET/api/healthService health check
GET/api/versionAPI version
GET/api/statsDeployment and cluster statistics
GET/api/appsList all discovered apps
GET/api/deploymentsList recent deployments
GET/api/validateValidate all infraspecs
GET/api/validate/{id}Validate a single infraspec
GET/api/sagaList recent saga events
GET/api/saga/{sagaId}Get all events for a saga
GET/api/cloudflared/ingressList active cloudflared hostnames
POST/api/webhooks/{provider}Webhook receiver (GitHub)

Per-App (/api/apps/{id}/...)

MethodPathDescription
GET/Get app details
POST/deployStart a deployment
GET/logsStream logs (SSE)
POST/restartRolling restart
POST/scaleScale a task group
POST/rollbackRollback to previous deployment
GET/secretsList secret keys
PUT/secretsUpdate secrets
DELETE/secrets/{key}Delete a secret
GET/snapshotsList database snapshots
POST/snapshots/{ts}/restoreRestore a snapshot
GET/cron/historyCron execution history
POST/cron/triggerTrigger a cron job manually
POST/cron/pausePause a cron job
POST/cron/resumeResume a paused cron job
PUT/cron/scheduleUpdate cron schedule
POST/invokeInvoke a function
GET/function/historyFunction execution history
POST/forgeSet up cloudflared routing
POST/teardownRemove cloudflared routing
POST/endpoints/toggleToggle a single cloudflared endpoint
GET/execExec into a running allocation

WebSocket

PathDescription
/wsReal-time event stream

Authentication

Norn supports three auth modes (can be combined):

  1. Cloudflare Access — validates Cf-Access-Jwt-Assertion header against your CF Access team. Set NORN_CF_ACCESS_TEAM_DOMAIN and NORN_CF_ACCESS_AUD.
  2. Bearer Token — validates Authorization: Bearer <token> header. Set NORN_API_TOKEN.
  3. Open — if neither is configured, all endpoints are open (suitable for local dev).

Auth-exempt routes: /ws, /api/health, /api/version, /api/webhooks/*, /api/apps/*/exec.