Skip to content

Config homes & files ​

Each component keeps its state under fixed directories. The CLI stays per-user at ~/.burrowee/cli/. The gateway and edge are system services since 0.2.0, and since 0.3 everything machine-owned sits in one root-owned tree, /usr/local/burrowee/: a config root under /usr/local/burrowee/etc/, a data root under /usr/local/burrowee/var/, and the binaries in the exec root /usr/local/burrowee/bin — which is not on PATH; see Put the exec root on PATH. Nothing is placed in /usr/local/bin. A pre-0.2.0 per-user tree (~/.burrowee/gateway, ~/.burrowee/edge) is a migration source only — the installer's migration ladder adopts it into the system roots (or run migrate --from <dir> yourself).

No runtime component reads BURROWEE_* environment variables (the installers do read a few, like BURROWEE_SKIP_PREFLIGHT — see Install); relocation is by flag only — the CLI's --home (and --config, whose parent directory becomes the home), the gateway's --config-dir/--data-dir (--home is a deprecated alias), and the edge's --home, which names the config root (the data root is always derived from it). Key material is written 0600 inside 0700 directories.

uninstall (without --purge) moves the home aside to a timestamped backup, <home>.bak.<timestamp>, instead of deleting it.

CLI — ~/.burrowee/cli/ ​

Written by burrowee bootstrap <blob> <pin>.

FileWhat it holds
config.jsonThe relay matrix, schema v4: gateways — each one carrying its own membership as relays: {system, edges, default} (full relay ids) — a shared relays catalog keyed by relay id (kind system|edge, origin, LAN addresses, pinned LAN-cert fingerprint), bridges, defaults (the global default gateway only), and an optional pinned transport mode. One client can be paired with several gateways, each reachable over several relays — see Relays
config.json.v3.bakWritten once, by the v3 → v4 migration: the exact pre-migration config.json bytes, mode 0600. A secret — it inlines the same service PSK. Restoring it over config.json is the only way back to a pre-v4 CLI (see below)
ssh_configOpenSSH-format host aliases read by burrowee ssh, with #@gateway / #@service / #@relay directives
<svc>_configThe same alias format, generalized per service: burrowee open --svc <svc> <host> resolves <host> from <svc>_config (e.g. vnc_config)
fingerprints.jsonThe opt-in browser TLS/HTTP disguise config (burrowee fingerprint path prints this path; disabled by default — stock TLS)
logs/Managed-daemon logs; every stderr line is timestamped, so logs/daemon.err.log is diagnosable after the fact
identity/client.keyThe client's own identity key (0600) — generated on first use, shared across every gateway you pair with
identity/device.keyThe device's identity key — generated on first burrowee login, used to authorize the device with the console for gated downloads

Both identity keys live under identity/; an older install that kept them flat in the home root is migrated into identity/ automatically on next use. Everything else a pairing needs lives inline in config.json — there are no sidecar files on a fresh pairing. connect / ssh / daemon default their flags from this config. relays pair, relays use, gateways use, and gateways resync edit config.json in place.

How config.json reaches v4 — and the way back ​

A config.json at v1, v2 or v3 is migrated in place the first time a v4 build loads it, one version at a time, transparently on the next connect, ssh, relays list, etc. Two things about that step are worth knowing before you take it:

The v3 → v4 step writes a backup, and it is the only way back

Before migrating, the CLI writes the exact pre-migration bytes to config.json.v3.bak beside the config (config.beta.json.v3.bak on a beta build), at mode 0600. Treat that file as a secret — it inlines the same service PSK the config does.

An older CLI cannot read a v4 file at all. It decodes strictly, so the per-gateway relays object is an unknown field and every command fails at startup, not just the relay ones. To go back, restore config.json.v3.bak over config.json.

What the v3 → v4 step changes: each gateway's relays split into its system path and its edges, by kind; the old per-gateway default relay becomes relays.default when it was an edge, and the gateway's system path when it was the system relay; the flat edges[] table, the matrix-root defaults.relay, and every stored via are dropped. Bridges, the pinned transport, each relay's default_gateway, and relays keyed by their origin (from a gateway that predates relay ids) all survive it. One thing does not: a relay that has a domain and that you had pinned to LAN by hand loses that pin, and is dialled over its domain from then on — see No stored dial face.

Daemon socket ​

PathPurpose
~/.burrowee/cli/sockets/transport.sockThe transport daemon's IPC socket — stream consumers receive per-service-sealed streams over it, and every relays/gateways subcommand that mutates state or needs a live answer (use, rm, pair, resync, probe, …) pokes it after editing config.json (the list forms and relays ping read config.json directly and need no daemon — ping dials the relay itself). On a pathologically long home path it overflows to $XDG_RUNTIME_DIR/burrowee/transport.sock (OS temp dir when XDG_RUNTIME_DIR is unset). Override with --socket on daemon/relays/gateways.

Service unit ​

Installed by burrowee service install — a system-level unit (written via sudo, run as the installing user), so the daemon starts at boot with no GUI login. One system slot per machine; --force-service-override consents to taking over a unit another user installed.

PlatformUnitPath
macOS (launchd daemon)com.burrowee.cli/Library/LaunchDaemons/com.burrowee.cli.plist
Linux (systemd system unit)burrowee-cli.service/etc/systemd/system/burrowee-cli.service

Legacy per-user units (org.burrowee.cli gui agent / systemd --user) are migrated away on install but still probed by service status.

Gateway — /usr/local/burrowee/{etc,var}/gateway ​

The gateway is a system service running as root; its state is split across a config root and a data root (flags --config-dir / --data-dir; the old single --home is a deprecated alias). Created on first serve / bootstrap. The gateway's identity is self-generated — the private keys never leave the config root. Since the microkernel split, the roots are shared by three binaries: burrowee-gateway (the daemon), burrowee-gateway-console (the local console, supervised as the daemon's child), and burrowee-gateway-updater (the push-update agent).

Config root — /usr/local/burrowee/etc/gateway/ ​

File / dirWhat it holds
identity/relay_ed.keyThe gateway's identity key toward relays (its fingerprint is the gateway's id everywhere)
identity/cli_ed.keyThe gateway's identity key toward paired clients
identity/session.keyKey material for session tokens (generated on first serve)
configOptional KEY=VALUE overrides for the few operator-tunable defaults: console_port=<n> (the loopback console port, default 16518) and allow_push_update=false (opt out of console-driven remote push-updates; default true — see push allow|stop|status)
fingerprints.jsonThe opt-in browser TLS/HTTP disguise config (burrowee gateway fingerprint path); disabled by default
console.tokenThe local console's bearer token, owned root:<admin-group> mode 0640 — reading the signed-in URL (console-url) needs admin-group membership; rotating it (console-rotate-token) needs root

Data root — /usr/local/burrowee/var/gateway/ ​

File / dirWhat it holds
gateway.dbThe gateway store: persisted relays, targets, sessions, pairings — everything the local console shows
sockets/Runtime unix sockets (see below)
logs/stdout/stderr of the managed service on macOS (every stderr line timestamped); on Linux, logs go to the journal — journalctl -u burrowee-gateway.service

Upgrading from a pre-0.2.0 install

A legacy per-user ~/.burrowee/gateway tree is adopted one-way into the roots above by the migration ladder that runs on install/update, or explicitly with burrowee gateway migrate --from <dir> (adoption sources only the running user's home). A verified migration retires the tree it adopted from. Until an unmigrated legacy tree is dealt with, bootstrap/run refuse to silently mint a fresh identity — pass --migrate-from <dir> to adopt it or --accept-new-identity to deliberately start over.

Sockets ​

PathPurpose
~/.burrowee/gateway/sockets/register.sockWhere burrowee-register registers a local TCP service with the running gateway (the default --sock path; burrowee gateway register info prints the resolved path and whether it dials). On an over-long home path, --sock becomes required.
<data-root>/sockets/console.sockWhere the separate burrowee-gateway-console process talks to the daemon for operations that need it live.

Service unit ​

Installed by burrowee gateway service install (and automatically by bootstrap) — system-level units that name --config-dir/--data-dir explicitly and serve the daemon with --no-open. burrowee-gateway-updater gets its own unit installed alongside; there is no separate unit for the console, which runs as a supervised child of the daemon. --force-service-override consents to replacing a unit installed by a different user.

PlatformUnitPath
macOS (launchd daemons)com.burrowee.gateway, com.burrowee.gateway.updater/Library/LaunchDaemons/
Linux (systemd system units)burrowee-gateway.service, burrowee-gateway-updater.service/etc/systemd/system/

Upgrading from an old install

Earlier builds used per-user agents (org.burrowee.gateway, then a per-user com.burrowee.gateway). service install migrates automatically — it boots out and removes the stale unit before installing the current system-level one.

Edge — /usr/local/burrowee/{etc,var}/edge ​

Written by burrowee edge bootstrap <blob> <pin> and by the running relay. Same split as the gateway: a config root at /usr/local/burrowee/etc/edge and a data root at /usr/local/burrowee/var/edge (root-owned 0700). The edge's --home flag names the config root only — the data root is always derived from it. A host with no system install keeps ~/.burrowee/edge; a pre-0.2.0 per-user tree is adopted with burrowee edge migrate --from <dir> (copies, never moves; a verified adoption renames the source to <tree>.bak.<timestamp> with a printed one-mv recovery) — normally run for you by the shipped migration ladder.

Config root — /usr/local/burrowee/etc/edge/ ​

File / dirWhat it holds
identity/relay_ed.keyThe edge's identity key; its fingerprint is what you approve in the cloud console
console.jsonThe enrolled console URL + public key (console_url, console_pub_hex), persisted by bootstrap; the compiled-in console identity is the fallback when absent
configServe settings as KEY=VALUE lines: tls_listen (default :443, off = LAN-only), quic_addr (unset = off), lan_listen (default 127.0.0.1:9448, off), lan_advertise_port, lan_cert, lan_allow_ips, serve_mode (frontier|lan, written by edge mode), raw_port / raw_port_listen (the nginx-bypass isolated listener, unset = off — see Ports), proxy_protocol (default derived: on when tls_listen is loopback/nginx-fronted, off when public — see edge proxy-protocol on|off|status), the client-IP attribution keys trusted_proxy_cidrs / client_ip_header / trust_loopback_client_ip_header, allow_push_update (opt in to cloud-initiated push updates; default false), the optional buffer profile buffer_stream/buffer_session/buffer_frame (byte counts, or k/m/g suffixes), and the operator binary-path overrides bin_path / bin_<tool>. Read by run; serve flags override per key (where a flag exists). # comments and blank lines are preserved. Read/write it with edge cli config get|set
lan-cert/cert.pem, lan-cert/key.pemThe long-lived self-signed LAN TLS cert nginx terminates on the LAN port; its SHA-256 fingerprint is pinned in client/gateway blobs. There is no rotate flag — to force a new one, delete this directory and re-run sudo burrowee edge nginx reconcile --mode lan (see Rotating the LAN certificate)
bridge/bridge_ed.keyThis edge's edge-to-edge bridge identity — separate from its relay identity above; generated automatically the first time the edge runs after upgrading, so every edge becomes bridge-capable with no setup step
bridge/authorized_keysThe inbound bridge allowlist: peer edges' bridge public keys this edge accepts Links from (edge cli bridge approve)
bridge/links.jsonOperator-staged outbound bridge Links this edge subscribes to (edge cli bridge subscribe)

Data root — /usr/local/burrowee/var/edge/ ​

File / dirWhat it holds
config.jsonThe latest console-signed relay config (owner tenant, authorized gateway fingerprints, served domains) — cached so status works offline; its signature is verified on every read
logs/Service logs (every stderr line timestamped)
stats/Persisted daily-stats series

nginx front ​

burrowee edge nginx writes server-only snippets and wires them in — it never rewrites your existing servers (the whole nginx verb family self-elevates via sudo where needed). Where the snippets themselves land differs by platform: on Linux they sit inside the resolved nginx conf dir (<nginx-conf-dir> below — nginx -V's own --conf-path, not an assumed constant); on macOS they sit in burrowee's own root-owned tree, /usr/local/burrowee/etc/nginx/, kept out of whichever package manager's (or hand-built) conf dir is actually running nginx — see nginx on macOS. The frontier and LAN fronts are two separate files in the same stream include folder, distinguished by filename (see nginx front → File paths):

PathPurpose
<nginx-conf-dir>/servers-stream/burrowee-edge-stream.conf (Linux) — /usr/local/burrowee/etc/nginx/servers-stream/burrowee-edge-stream.conf (macOS)The frontier stream front (nginx install/reconcile --mode frontier, and the legacy apply's combined file): :443 ssl_preread SNI passthrough to the edge's loopback tls_listen
<nginx-conf-dir>/servers-stream/burrowee-edge-lan.conf (Linux) — /usr/local/burrowee/etc/nginx/servers-stream/burrowee-edge-lan.conf (macOS)The LAN front (reconcile --mode lan): an L4 stream server — listen 8448 ssl; — terminating TLS with the LAN cert and passing the byte stream straight through to the edge's loopback lan_listen. Lives in the same servers-stream/ folder as the frontier front (needs libnginx-mod-stream on Debian/Ubuntu, same as the frontier front), so it needs no extra hook
<nginx-conf-dir>/nginx.conf (Linux) — the running nginx's own nginx.conf (macOS)Gains one top-level line if missing (frontier only): a relative stream { include servers-stream/*.conf; } on Linux, an absolute stream { include /usr/local/burrowee/etc/nginx/servers-stream/*.conf; } on macOS — pointing at burrowee's tree rather than the package manager's

Service unit ​

Installed by burrowee edge service install — system-level units for the edge and its updater. service status still reports legacy per-user units; --force-service-override consents to replacing a unit installed by a different user.

PlatformUnitPath
macOS (launchd daemons)com.burrowee.edge, com.burrowee.edge.updater/Library/LaunchDaemons/
Linux (systemd system units)burrowee-edge.service, burrowee-edge-updater.service/etc/systemd/system/