Skip to content

Developer Guide

Internal documentation for working on the Digilan Edge platform. Start with How It Works.

Repositories

All repositories are on GitLab under digilan/.

Repo Language Role
edge/gateway Go (OpenBSD amd64/arm64) Edge agent (edge-agent / ea) and its signed release pipeline
edge/relay Go (Linux) relayd: SNI forwarder and WireGuard/WebSocket tunnel endpoint
platform/nexus Go Connect RPC control plane; owns the protobuf definitions (proto/) and the Postgres schema
platform/authz Go Connect RPC authorization service (acl, roles, role_actions)
platform/realtime TypeScript (Cloudflare Workers) Per-device Durable Object bridging the agent WebSocket, portal viewers and nexus
platform/portal TypeScript (SvelteKit 2, Svelte 5) Web UI
platform/radius-ctrl .NET, Preact FreeRADIUS control plane (dev only)
platform/mr-wifi, platform/mr-wifi-svelte PHP + Go, SvelteKit Monsieur Wifi (dev only)
infra/terraform OpenTofu Scaleway and Cloudflare infrastructure, Zitadel and relay scripts
infra/ci-templates GitLab CI Shared image build and Scaleway container deploy jobs
provisioning/openbsd-autoinstall Shell OpenBSD autoinstall USB images
documentation/mkdocs Markdown This site

Key concepts

  • Connect RPC everywhere. Portal to nexus, agent to nexus, relay to nexus, realtime to nexus (and back), and nexus to authz all speak Connect over HTTP/1.1. The portal uses JSON by default; set VITE_NEXUS_BINARY=true for binary protobuf.
  • One config document per version. Each save is a new gateway_configs row holding the whole JSON config. The agent consumes the blob directly. See Config Lifecycle.
  • Desired state, reconciled. Nexus records what a device should run (config version and agent release). Pushes through realtime only make the device ask sooner, so an offline device converges when it reconnects.
  • One Durable Object per device. It holds at most one gateway socket, plus any number of read-only viewers and operator (console) sockets.
  • Confirm or roll back. Every applied config arms a 60 s guard on the agent. Every self-update arms an out-of-process watchdog.
  • Identity is Zitadel; authorization is ours. Nexus checks the JWT, then each handler asks authz. Grants are keyed on the raw Zitadel sub.
  • Shared database per environment. Nexus and authz use the same database. Each owns its own tables.
  • Releases on tags. nexus, authz, realtime, portal, gateway and relay build and deploy from tag pipelines only; merge requests run checks. See CI & Releases.