Skip to main content

Deploy the Edge

In one sentence

Run octet-edge on the Linux hop that terminates the browser connection, give it your credentials, and route the collector's apiUrl to it.

This is step 2 of three. You should already be embedding the collector; next you'll fetch the verdict.

The one rule: terminate the browser connection

Read this first

The edge reads a connection-level network-timing signal that is only meaningful when the edge is the hop where the browser's connection actually terminates. If a separate TLS-terminating CDN or load balancer sits between the browser and the edge, that signal reflects the intermediary, not the browser — and confidence drops.

The integration still works without it (the other signals carry the verdict), but you get the strongest result when the edge is the connection-terminating hop. Because this depends on your specific infrastructure, finalize the exact termination topology with Octet during onboarding — that's expected and normal. The per-server guides below show the trade-offs.

Run it

The edge is a single static Linux binary (get it here). It's configured entirely through environment variables:

PORT=8080 \
OCTET_URL=https://<your-octet-api-url> \
LICENSE=<your-license-key> \
ALLOWED_ORIGIN=https://yourapp.com \
./octet-edge-linux-amd64
VariableRequiredPurpose
OCTET_URLyesOctet's API base URL — where the edge forwards. Octet gives you this. Silently defaults to a dev localhost address if unset — always set it (see below).
LICENSEprodYour license key, presented to Octet as x-octet-license.
ALLOWED_ORIGINrecommendedBrowser origin allowed to call the edge (CORS + the latency WebSocket). Set to your site, e.g. https://yourapp.com. Defaults to * (any origin).
PORTPort to listen on (default 8080; use 443 when the edge serves HTTPS directly).
EDGE_TLS_CERT_FILErecommendedTLS certificate chain (e.g. Let's Encrypt fullchain.pem). Set with EDGE_TLS_KEY_FILE + PORT=443 to have the edge serve HTTPS and terminate the browser connection itself — the cleanest way to satisfy the one rule above. Both unset ⇒ plain HTTP.
EDGE_TLS_KEY_FILErecommendedThe matching private key (e.g. privkey.pem). Required alongside EDGE_TLS_CERT_FILE.
EDGE_EXPOSE_VERDICTLeave off (default). Off ⇒ the browser gets only an { ok: true } ack and your backend fetches the verdict. 1 / true exposes the coarse verdict to the browser — demos only.
EXIT_IPTesting only — overrides the harvested source IP for loopback dev setups. Leave unset in production.
EDGE_DEBUGDiagnostics only — logs a line per request (incl. the end-user IP) to confirm the edge is the terminating hop. Leave off in production.
OCTET_CA_FILEoptionalOctet's CA certificate — pins and verifies Octet over HTTPS. For the planned mutual TLS; optional and inert until Octet provisions certs.
EDGE_CLIENT_CERT_FILEoptionalYour client certificate for mutual TLS to Octet. Planned hardening — not required yet.
EDGE_CLIENT_KEY_FILEoptionalThe matching private key. Planned hardening — not required yet.
Always set OCTET_URL

If OCTET_URL is unset the edge silently falls back to a local dev address (http://127.0.0.1:8787) — it won't error, but every request fails with 502 octet_unreachable. Set it to the URL Octet gave you.

Serving HTTPS to the browser. The browser reaches the edge over HTTPS, so the edge needs TLS in front of it. The strongest setup is to let the edge terminate that TLS itself — set EDGE_TLS_CERT_FILE + EDGE_TLS_KEY_FILE + PORT=443 and it serves HTTPS directly, keeping it the connection-terminating hop (the one rule above). The alternative is a reverse proxy that terminates TLS and forwards to the edge — simpler, but that proxy becomes the terminating hop and the timing signal weakens. See Edge standalone / container for the direct-TLS recipe, or the nginx / Caddy guides for the proxy approach.

The edge forwards to Octet at OCTET_URL (use https://). Mutual TLS is planned hardening and not yet in force: the OCTET_CA_FILE / EDGE_CLIENT_CERT_FILE / EDGE_CLIENT_KEY_FILE variables are optional and inert until Octet provisions certificates — when set, OCTET_CA_FILE pins Octet over HTTPS and adding the client cert + key enables mutual TLS. Full reference: Edge Configuration.

Endpoints it exposes

MethodPathPurpose
GET/healthLiveness check — returns { ok: true, ... }.
POST/v1/signalsThe collector posts the signal bundle here; the edge forwards and returns a coarse result.
GET/v1/wsThe latency channel the collector measures against.

The collector calls these relative to its apiUrl: with apiUrl: 'https://yourapp.com/octet', it posts to /octet/v1/signals and connects the WebSocket at /octet/v1/ws. Your server routes that prefix to the edge — see the per-server guides.

Pick your setup

The connection-level timing signal aside, the wiring is the same everywhere: route the browser's apiUrl traffic (including the WebSocket) to the edge, and pass through the source IP.

  • nginx — reverse-proxy a path prefix to the edge.
  • Caddyreverse_proxy with automatic HTTPS.
  • Cloud LB / CDN — AWS ALB/NLB, GCP, Cloudflare — and the termination caveat that matters most here.
  • Standalone / container — systemd, Docker, or a Kubernetes sidecar; the edge terminates directly.

Where to go next