Skip to content

The setup key ​

A boat proves it is allowed onto MUXEN's support network with a single secret, used once: the NetBird setup key. It arrives inside the muxen-eagle package, is handed to the NetBird client at enrolment, and is deleted from the boat the moment enrolment succeeds. Nobody types it, and after commissioning nobody can read it off a Brain, because it is no longer there.

That is the whole story at owner level. The rest of this chapter is for whoever builds, ships or debugs the package.

Where it lives ​

PropertyValue
Path/etc/muxen/eagle.key
Ownerroot:root
Mode0600
Contentthe key, one line
Conffileno
Overridable byMUXEN_EAGLE_KEY_FILE

0600 root:root is deliberate and carries a lintian override to say so: muxen-eagle-init runs as root, and nothing else on the boat has any business reading the key. dh_fixperms would normalise it back to 0644, so the packaging excludes the path from it explicitly.

The script reads the path from MUXEN_EAGLE_KEY_FILE, falling back to /etc/muxen/eagle.key. The systemd unit sets no environment, so on a Brain the fallback is always what is used; the variable is there for running the script by hand against a key somewhere else.

Why it is not a conffile ​

Files under /etc are normally Debian conffiles, and this one is deliberately unregistered — debian/rules strips it out of the generated DEBIAN/conffiles after dh_installdeb has added it, and a lintian override records the reason.

Two things would go wrong otherwise:

  • dpkg would prompt on upgrade. A conffile the local system has modified — and deleting counts — makes dpkg ask the operator what to do. On an unattended Brain that is an upgrade that never finishes.
  • dpkg would restore the key. The boat deletes it on purpose. A conffile handler putting it back would leave every enrolled boat in the fleet carrying a live fleet secret on disk again, indefinitely.

Not being a conffile means an upgrade simply reinstalls the key file. That is harmless: the next run of the service short-circuits on netbird status before ever reading it, and deletes it again.

Where it comes from ​

The key is never present in MUXEN's source. It is injected at package build time from $SETUP_KEY, a masked and protected GitLab CI/CD variable, by a recipe in debian/rules whose body is silenced so that make cannot echo the key into the build log.

Three outcomes, by build context:

$SETUP_KEYContextResult
setanythe key is written to /etc/muxen/eagle.key; eagle.key: written from $SETUP_KEY
unseta tag build ($CI_COMMIT_TAG set)the build fails, rather than ship a fleet that cannot enrol
unsetanything elsean empty key file is shipped, with a loud warning on stderr

The variable is protected, so it is exposed only on protected refs. The practical consequence for anyone testing a branch build:

A .deb from an unprotected feature branch contains an empty key and cannot enrol a boat. It will install, the service will run, and on a Brain that was never enrolled it will exit 78. That is the designed behaviour, not a bug in the branch.

Release tags must therefore be protected in the project settings, or tagged releases fail to build — loudly, which is the point.

What the boat does with it ​

The key is read exactly once, at step 4 of the enrolment chain, and only after both already-connected checks have failed. It is considered present if it holds at least one non-whitespace character, so an empty file and a missing file are the same thing.

It is passed to NetBird as --setup-key-file, never as --setup-key: a secret on a command line is readable by every local user through /proc/<pid>/cmdline for as long as the process runs.

It is then deleted on all three paths that end with the boat on the network:

  • the legacy-install short-circuit,
  • the already-connected short-circuit,
  • a successful netbird up.

There is no path that leaves a used key on a boat.

Rotation ​

Rotating the fleet key is a change to $SETUP_KEY plus a new release; nothing in the boat's copy or in the script needs to change. Boats already enrolled are unaffected — they hold peer credentials issued at enrolment, not the setup key, and the service never reads the key on them again.

debian/rules also notes that moving from one fleet key to per-device keys would be a change to that recipe alone, since muxen-eagle-init only ever reads the file.

What is not visible here ​

The key's expiry, whether it is reusable or single-use, how many peers it may enrol and which group it places them in are all properties held on the NetBird management server. None of them is visible from here, and none of them is stated in this manual. See internal/open-questions.md.

Integration of multiplexed solutions
MUXEN and the MUXEN logo are trademarks of MUXEN SAS.