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=truefor binary protobuf. - One config document per version. Each save is a new
gateway_configsrow 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.