Skip to content

feat: enrol nodes with a one-time setup token - #166

Merged
encodeous merged 3 commits into
encodeous:mainfrom
e226li:feat/node-enrolment
Sep 30, 2026
Merged

encodeous merged 3 commits into
encodeous:mainfrom
e226li:feat/node-enrolment

Conversation

@e226li

@e226li e226li commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Why

Previously joining a node to the cluster involved a lot of friction: the user had to manually fetch the central config, then generate the keys on the joiner, then amend the central config and redistribute it to every node. This PR provides a 1 to 2 step process to reduce this friction.

How

  • nylon init --serve loads or creates node.yaml / central.yaml, prints a single use setup token, and waits on node port for one join
  • A joining node sends only its ID, pubkey, and the addresses and prefixes passed with --address / --prefix. The server adds it as a router with those and no graph edges, then returns central.yaml which is given to the user on the client node
  • The node ID defaults to the OS hostname and can be set with --id
  • The serving node’s config remains in sync with other nodes and will only accept connections from the joiner once the change is distributed to the config distributor. However, it validates that the config it returns is valid

Usage

# existing node
$ nylon init --serve

# new node
$ nylon init --connect <server-ip> --token <token> --address 10.0.0.2 --prefix 192.168.5.0/24 --id node-2

# output on existing node
Node node-2 joined with address [10.0.0.2], wrote ./central.join.yaml
It has no connections yet, add it to graph (e.g. `node-1, node-2`) then:
Seal it and publish it to https://example.com/central.nybundle:

  nylon seal -c ./central.join.yaml -k ./central.key -o ./central.nybundle

New nylon init options:

Option Description
--serve Print a setup token and wait for a node to join with --connect
--connect <host[:port]> Join the network through a node running --serve (port defaults to 57175)
--token <token> Setup token printed by --serve (required with --connect)
-c, --config <path> Central config path used by --serve and --connect (default ./central.yaml)
--address <ip> Nylon address for this node in central config (repeatable)
--prefix <cidr> IP prefix this node advertises in central config (repeatable)
--id <name> Unique node ID, now defaults to the OS hostname
--force With --connect, overwrite existing configs; with --serve, discard an undistributed join

Testing

This was tested in a KVM setup with 4 separate Nylon nodes. The tool was successfully used to add a new node.

@e226li
e226li marked this pull request as ready for review September 30, 2026 20:11
@encodeous

Copy link
Copy Markdown
Owner

I think it's a bit of a slippery slope for nylon to auto configure the ip, and graph...

Since the join is authenticated with the token, maybe on the client side, we can pass some options like what node name, prefixes, and address we want for this new node. (this could be both via cli, or interactive)

As for the graph, I think we might want to default to a fully connected graph (maybe add support for wildcards), for ease of use, I think it should be more of an advanced feature anyways.

  • We can expand this in the future with full ACL support (?)

@encodeous
encodeous merged commit b3b8d9c into encodeous:main Sep 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants