@flwrlabs/supernode-authentication
flwr new @flwrlabs/supernode-authenticationFlower Federations with Authentication ๐งช
The following steps describe how to start a long-running Flower server (SuperLink) and a long-running Flower clients (SuperNode) with authentication enabled. The task is to train a simple CNN for image classification using PyTorch.
TIP
Follow this how-to guide to learn more about Flower's Deployment Engine, how setting up secure TLS-enabled communications and SuperNode authentication works. If you are already familiar with how the Deployment Engine works, you may want to learn how to run this same example using Docker. Check out the Flower with Docker documentation.
Project Setup
Fetch the app
Install Flower:
pip install flwr
Fetch the app:
flwr new @flwrlabs/supernode-authentication
This will create a new directory called supernode-authentication with the following project structure:
supernode-authentication โโโ authexample โ โโโ __init__.py โ โโโ client_app.py # Defines your ClientApp โ โโโ server_app.py # Defines your ServerApp โ โโโ task.py # Defines your model, training and data loading โโโ pyproject.toml # Project metadata like dependencies and configs โโโ generate_creds.py # Generate certificates and keys โโโ prepare_dataset.py # Generate datasets for each SuperNode to use โโโ README.md
Install dependencies and project
Install the dependencies defined in pyproject.toml as well as the authexample package.
pip install -e .
Generate TLS certificates and authentication keys
The generate_creds.py script generates:
- TLS certificates for establishing a secure connection.
- Private and public keys for SuperNode authentication.
NOTE
This script is for development purposes only.
TIP
You can configure the certificate details (e.g. Validity, Organization, or adding a public IP to SERVER_SAN_IPS) by editing the global variables at the top of generate_creds.py.
# Generate certificates and keys (creates 2 SuperNodes key pairs by default) python generate_creds.py # Or specify the number of SuperNodes key pairs python generate_creds.py --supernodes {your_number_of_supernodes}
Define a SuperLink connection in the Flower Configuration file
Let's first locate the Flower Configuration file and create a SuperLink connection with that will allow us to interface with the SuperLink using the TLS certificate we just created.
Locate the Flower Configuration file:
flwr config list
# Example output: Flower Config file: /path/to/your/.flwr/config.toml SuperLink connections: supergrid local (default)
Create a new Superlink connection named my-connection:
[superlink.my-connection] address = "127.0.0.1:9093" # Control API of SuperLink root-certificates = "/abs/path/to/certificates/ca.crt"
Make this new connection the default one by editing the top part of the config.toml. In this way, if you now execute flwr config list again you should see the following output:
Flower Config file: /path/to/your/.flwr/config.toml SuperLink connections: supergrid local my-connection (default)
Start the long-running Flower server (SuperLink)
Starting long-running Flower server component (SuperLink) and enable authentication is very easy; all you need to do is to pass the --enable-supernode-auth flag. In this example we also enable secure TLS communications between SuperLink, the SuperNodes and the Flower CLI.
Let's first launch the SuperLink:
flower-superlink \ --ssl-ca-certfile certificates/ca.crt \ --ssl-certfile certificates/server.pem \ --ssl-keyfile certificates/server.key \ --enable-supernode-auth
At this point your server-side is idling. Next, let's connect two SuperNodes, and then we'll start a run.
Start the long-running Flower client (SuperNode)
NOTE
Typically each SuperNode runs in a different entity/organization which has access to a dataset. In this example we are going to artificially create N dataset splits and saved them into a new directory called datasets/. Then, each SuperNode will be pointed to the dataset it should load via the --node-config argument. We provide a script that does the download, partition and saving of CIFAR-10.
python prepare_dataset.py
Pre-registering SuperNodes
Before connecting the SuperNodes we need to register them with the SuperLink. This means we'll tell the SuperLink about the identities of the SuperNodes that will be connected. We do this by sending to it the public keys of the SuperNodes that we want the SuperLink to authorize.
Let's register the first SuperNode. The command below will send the public key to the SuperLink.
flwr supernode register keys/supernode_credentials_1.pub # It will print something like: # โ SuperNode 16019329408659850374 registered successfully.
Then, we register the second SuperNode using the other public key:
flwr supernode register keys/supernode_credentials_2.pub # It will print something like: # โ SuperNode 8392976743692794070 registered successfully.
You could also use the Flower ClI to view the status of the SuperNodes.
flwr supernode list ๐ Listing all nodes... โโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโณโโโโโโโโโโณโโโโโโโโโโโณโโโโโโโโโโโโโโโโโโโโโโโ โ Node ID โ Owner โ Status โ Elapsed โ Status Changed @ โ โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ โ 16019329408659850374 โ none โ created โ โ N/A โ โโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโค โ 8392976743692794070 โ none โ created โ โ N/A โ โโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโ
Once the SuperNodes are connected, you'll see the status changes. Let's connect them !
Connecting SuperNodes
In a new terminal window, start the first long-running Flower client (SuperNode):
flower-supernode \ --root-certificates certificates/ca.crt \ --auth-supernode-private-key keys/supernode_credentials_1 \ --superlink "127.0.0.1:9092" \ --node-config 'dataset-path="datasets/cifar10_part_1"' \ --clientappio-api-address="127.0.0.1:9094"
In yet another new terminal window, start the second long-running Flower client:
flower-supernode \ --root-certificates certificates/ca.crt \ --auth-supernode-private-key keys/supernode_credentials_2 \ --superlink "127.0.0.1:9092" \ --node-config 'dataset-path="datasets/cifar10_part_2"' \ --clientappio-api-address="127.0.0.1:9095"
Now that you have connected the SuperNodes, you should see them with status online:
flwr supernode list ๐ Listing all nodes... โโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโณโโโโโโโโโโณโโโโโโโโโโโณโโโโโโโโโโโโโโโโโโโโโโโ โ Node ID โ Owner โ Status โ Elapsed โ Status Changed @ โ โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ โ 16019329408659850374 โ none โ online โ 00:00:30 โ 2025-10-13 13:40:47Z โ โโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโค โ 8392976743692794070 โ none โ online โ 00:00:22 โ 2025-10-13 13:52:21Z โ โโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโ
If you generated more than 2 client credentials, you can add more clients by opening new terminal windows and running the command above. Don't forget to specify the correct client private key for each client (SuperNode) you created.
TIP
Note the --node-config passed when spawning the SuperNode is accessible to the ClientApp via the context argument, i.e., context.node_config. In this example, the ClientApp uses it to load the dataset and then proceed with the training of the model.
@app.train() def train(msg: Message, context: Context): # Read the node_config to know where dataset is located dataset_path = context.node_config["dataset-path"] # then load the dataset
Run the Flower App
With both the long-running server (SuperLink) and two SuperNodes up and running, we can now start the run. You can optionally use the --stream flag to stream logs from your ServerApp running on SuperLink.
flwr run . --stream