Architecture Overview
Last updated 4 min read
Report issueArchitecture Overview#
A 10-minute tour of how GritivaCore is wired together. Audience: developers about to modify the system, ops people evaluating it, and curious users.
The canonical source for the in-depth architecture is
docs/architecture/overview.mdin the repo. This page is the public-facing summary.
The big picture#
TEXT ┌──────────────────────────┐ │ Hosted Control Plane │ │ (panel.gritiva.com) │ │ FastAPI + Postgres │ └────────────┬─────────────┘ │ outbound WebSocket (always 443) ┌──────────────┼──────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ VM │ │ VM │ │ VM │ │ +agent │ │ +agent │ │ +agent │ │ │ │ │ │ │ │ scope1 │ │ scope1 │ │ scope1 │ │ scope2 │ │ scope2 │ │ scope2 │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ └──── gmesh ───┴──── gmesh ───┘ (WireGuard, peer-to-peer)
Three layers:
- Hosted control plane — the panel, API, and docs system. Knows what should be true. Doesn't carry your traffic.
- The agent — a single PyInstaller binary running as a systemd unit on each VM. Reconciles its local state with the control plane's desired state.
- The data plane — gmesh (WireGuard between scopes), runs entirely on your hardware. We cannot see or relay your traffic.
Components#
Control plane#
| Component | Tech | What it does |
|---|---|---|
| API | FastAPI (Python 3.12) | REST + WebSocket endpoints, RBAC, audit logs |
| Panel | React 19 + Vite | The admin UI at panel.gritiva.com |
| Database | Postgres 15 + Alembic | Tenants, accounts, VMs, scopes, services, sharing, audit |
| Workers | Celery + Redis | Background jobs (DRM reconciler, mesh peer roster, billing) |
| Docs system | FastAPI + Celery + Next.js | The thing you're reading right now |
Agent (on each VM)#
| Module | Path | What it does |
|---|---|---|
| Main loop | agentNew/main.py | Event loop, WS connection to control plane |
| Collectors | agentNew/collectors/*.py | Periodic snapshots: cpu, mem, network, services |
| Scope handler | agentNew/handlers/scope.py | Creates/destroys netns + cgroup |
| Mesh handler | agentNew/handlers/mesh.py | Manages wg-gmesh interface per scope |
| Firewall handler | agentNew/handlers/mesh_firewall_handler.py | nftables rules in scope netns |
| Resource monitor | agentNew/resource_monitor.py | Heartbeat + watchdog |
The mesh (gmesh)#
- Protocol: WireGuard
- Daemon:
gmeshd(one per VM) - Topology: full mesh between scopes (no central relay)
- Discovery: peer roster pushed from control plane via WS
- Identity: each scope has a long-lived X25519 keypair
Data flows#
"I provisioned a new VM"#
- You click "Add VM" in the panel → control plane mints an enrollment token
- You run
curl ... | bashon the VM → installer drops the agent binary + systemd unit + token - Agent starts, opens WS to
panel.gritiva.com, presents the token - Control plane registers the VM, sends back the initial desired state (no scopes yet, no mesh peers)
- Panel shows the VM online within ~10 seconds
"I created a scope"#
- You run
gritivactl scope create my-app --cpu 2 --mem 4G - Panel saves the desired state (
scopestable) - Agent receives a
scope_createmessage over WS - Agent calls
scope_handler.py:create():ip netns add my-appcgcreate -g cpu,memory:my-app- Set quotas
- Optionally bind /etc/resolv.conf
- Agent reports back
scope_status: ready - Panel marks the scope ready
"I shared a service from scope A to scope B on another VM"#
- You run
gritivactl share allow --service db --to my-app - Control plane writes a sharing rule, computes the implied mesh peers (A↔B), pushes to both agents
- Each agent's
mesh.pyhandler:- Adds the peer to its scope's wg-gmesh peer list
- Updates nftables firewall in the scope netns
- Inside scope B,
db.scope-a:5432now resolves and routes via WireGuard
What the agent does NOT do#
- It does not phone home with your application data
- It does not require root all the time (only
CAP_NET_ADMIN+CAP_SYS_ADMIN) - It does not auto-update without your consent (you opt in via the panel)
- It does not run customer workloads in its own process (each scope is independent)
Failure model#
| Failure | What happens |
|---|---|
| Agent crashes | systemd restarts it; scopes keep running because they're separate processes |
| Control plane unreachable | Agent retries WS with exponential backoff; existing scopes + mesh unaffected |
| Network partition between two VMs | Affected mesh peers move to PEER_STATUS_CONNECTING, reconnect on heal |
| VM dies | Scopes on it die with it; on reboot, agent reconciles from the desired state |
Further reading#
- Concepts: Scope — netns + cgroup deep dive
- Concepts: Mesh — gmesh protocol + peer state machine
- Concepts: VNet — Wave A overlay primitive
- Concepts: DRM — domain routing reconciler
- Postmortems — what's gone wrong and what we learned