The Problem

Enterprises that need a self‑hosted, zero‑trust gateway often stitch together separate VPN, API‑gateway, and PaaS components. That creates divergent configs, multiple credential stores, and a larger attack surface. Octelium aims to collapse those pieces into a single, extensible platform that can be run on‑prem or in a cloud VM.

What This Does

Octelium ships six loosely coupled sub‑projects:

  • cluster – the full control‑plane (auth server, portal, data‑plane gateways) – 707 files.
  • client – CLI tools (octelium, octeliumctl) and the “connect” server implementation – 230 files.
  • apis – protobuf‑generated gRPC stubs and type definitions – 28 files.
  • pkg, octelium‑go, unsorted – shared utilities and a single example script.

The CLI (client/octelium/main.go) parses sub‑commands and ultimately launches a tunnel server (client/octelium/commands/connect/controller/esshmain/server.go). The control‑plane exposes gRPC services defined in apis/main/*.pb.go (e.g. authv1.pb.go, corev1.pb.go) and uses the same protobufs for client‑side stubs.

How It Is Wired

Execution startclient/octelium/main.go:31 (func main). It creates a root command, loads config, then calls Execute.

Key flowExecute → connect → Run (see client/octelium/commands/connect/controller/esshmain/server.go:104). Run reaches ~400 internal functions and performs three external actions:

  1. SubprocessdoCmd → cmd.Run starts the WireGuard/QUIC tunnel binary.
  2. Databaseclient/common/authc/authc.go → NewClient builds a Redis client (redis.NewClient).
  3. Crypto/SecretskubeInformerFactory.Core().V1().Secrets watches Kubernetes secret objects for TLS material.

The most widely referenced internal helpers are:

  • CoreC (called from 216 places) – central configuration loader.
  • Cleanup (211 calls) – deferred resource release.
  • Initialize (210 calls) – bootstraps logging, metrics, and global state.

These three have the largest blast radius; any change propagates through >200 call sites. The import graph shows no circular dependencies, but several UI router packages (cluster/authserver/.../router) have instability = 1, meaning they import many others without being imported themselves – a potential hot‑spot for future refactor.

Side‑effects – 67 functions read/write files, 2 make outbound network calls, 7 exec external commands, 13 perform cryptographic ops, and 14 touch a Redis store. The shortest documented outbound path is:

main → Execute → connect → Run → NewClient → redis.NewClient

How To Use It

# Clone the repo
git clone https://github.com/moses-y/octelium
cd octelium

# Build the CLI container (Dockerfile in client/octelium)
docker build -t octelium-cli -f client/octelium/Dockerfile .

# Or build locally with the Makefile (default target builds all binaries)
make          # uses go modules in client/*/go.mod

# Create a runtime config – copy the example and fill values
cp cluster/authserver/authserver/web/package/.env.example \
   cluster/authserver/authserver/web/package/.env.development
# (rotate any secrets after copying)

# Start a control‑plane component, e.g. the auth server
docker run -d --name auth \
  -v $(pwd)/cluster/authserver/authserver/web/package/.env.development:/app/.env \
  octelium-authimage   # image name defined in the Dockerfile

# Launch the client tunnel
./bin/octelium connect --profile mycluster

If you prefer the native binaries, the entry points are:

  • client/octelium/main.go – CLI driver.
  • client/octeliumctl/main.go – admin utilities.

Both are compiled by the Makefile targets octelium and octeliumctl.

Real‑World Use

A SaaS provider can deploy the authserver and portal pods in a private VPC, expose octeliumctl to ops, and give developers a single octelium connect command. The tunnel terminates on the client, authenticates via the gRPC Authenticate service (apis/main/authv1/authv1_grpc.pb.go), and forwards L7 requests to internal services without ever exposing raw IPs.

Code Health & Issues

  • High – tracked .env filescluster/authserver/authserver/web/package/.env.development (and two similar files) are committed despite .gitignore. Remove with git rm --cached and rotate credentials.
  • High – unpinned GitHub Actions – workflow files reference actions by tag (@v4). Replace with commit SHA to avoid supply‑chain drift.
  • High – committed secrets – same .env files contain live keys; treat as a breach and rotate.
  • Medium – no Dependabot – 26 manifest files lack automated updates. Add .github/dependabot.yml.
  • Medium – base images not pinned – Dockerfiles use golang:1.26.5 and alpine:3.23 tags; switch to digests.
  • Medium – no vulnerability gate – CI lacks a dependency‑review or osv‑scanner step.
  • Medium – missing non‑root USER – containers run as root; add an unprivileged user.
  • Low – missing job timeouts – workflow client-components.yaml lacks timeout-minutes.
  • Low – missing repo conventions – no .editorconfig, .gitattributes, or formatter config.

The static analysis also reports 91 high‑severity cognitive‑load issues (deep nesting) in test files such as client/octelium/commands/connect/controller/service_cfg_test.go. Refactoring with early returns will improve maintainability.

The Bottom Line

Octelium provides a concrete, single‑repo implementation of a zero‑trust gateway with a clear Go‑centric core and React UI front‑ends. The codebase is large, modular, and well‑instrumented, but it ships with committed secrets, unpinned CI actions, and deep nesting that will hinder rapid onboarding. It is suitable for teams comfortable managing Go services and willing to address the immediate security hygiene gaps before production use.